Attachment 'Slideshow.py'
Download 1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - Slideshow action
4
5 Usage - Allows treatment of a wiki page as a set of slides. Displays a
6 single slide at a time, along with a navigation aid.
7
8 A slide show page looks like this:
9
10 general introduction or comments
11 = Slide 1 title =
12 Slide 1 contents
13 = Slide 2 title =
14 Slide 2 contents
15 ...
16 = Final slide title =
17 Final slide contents
18
19 The slideshow action takes a parameter 'slidenumber', which is
20 the (1-based) number of the slide to display. The display uses
21 the large screen 'projection' media.
22
23 This action adds two sets of navigation aids for the slides:
24 1) some javascript, so that mouse clicks or space bar move to the
25 next page
26 2) a navigation footer, similar to the [[Navigation]] macro
27
28 History
29 1.0 2005-03-25 First version
30 1.1 2005-03-30 Revised thanks to some comments from NirSoffer.
31 Parse H1 tags instead of using the [[Slide]] macro.
32 Improve navigation.
33
34 @copyright: 2005 Jim Clark
35 @license: GNU GPL, see COPYING for details.
36 """
37
38 import re
39 from MoinMoin import config, wikiutil
40 from MoinMoin.Page import Page
41 from MoinMoin.parser.wiki import Parser
42 from MoinMoin.formatter.text_html import Formatter
43
44 header_re = r"^(?P<heading>\s*(?P<hmarker>=)\s(?P<htext>.*)\s(?P=hmarker))$"
45
46 class slideshow:
47 script_template = """
48 <script type="text/javascript"><!--
49 function firstSlide() {window.location="%s"}
50 function prevSlide() {window.location="%s"}
51 function nextSlide() {window.location="%s"}
52 function lastSlide() {window.location="%s"}
53 function handleKey(e) {
54 var key;
55 if (e == null) {key = event.keyCode} //IE
56 else {if (e.altKey || e.ctrlKey) {return true} key = e.which} // Mozilla
57 switch(key) {
58 case 49: firstSlide(); break //'1'
59 case 32: nextSlide(); break //space
60 case 60: prevSlide(); break //'<'
61 case 62: nextSlide(); break //'>'
62 default:
63 }
64 }
65 document.onkeypress = handleKey
66 //-->
67 </script>"""
68
69 def __init__(self, pagename, request):
70 self.pagename = pagename
71 try:
72 self.slidenumber = int(request.form.get('slidenumber', [1])[0])
73 except ValueError:
74 self.slidenumber = 1
75 request.formatter = Formatter(request)
76 request.page = Page(request, pagename)
77 request.formatter.page = request.page
78 self.request = request
79 self.page = self.request.page
80 self.formatter = self.request.formatter
81 self.body = self.page.get_raw_body()
82 self._parseslides()
83
84 def _parseslides(self):
85 """ Parse slide content from the base page. slideinfo is a tuple
86 of (title, startcharacter, endcharacter) representing each slide.
87 The slides are separated by H1 markers.
88 """
89 self.slideinfo = []
90 title = ""
91 h_pattern = re.compile(header_re, re.MULTILINE)
92 laststart = 0
93 for match in h_pattern.finditer(self.body):
94 if laststart:
95 self.slideinfo.append((title, laststart, match.start()))
96 title = match.group('htext').strip()
97 laststart = match.start()
98 if laststart:
99 self.slideinfo.append((title, laststart, len(self.body)))
100
101
102 def slideurl(self, slidenumber):
103 """ Return a url for a link to another slide based on this page
104 """
105 return "%s/%s?action=Slideshow&slidenumber=%d" % \
106 (self.request.getScriptname(), self.pagename, slidenumber)
107
108 def navigationscript(self):
109 """ Return a section of javascript for capturing mouse button and
110 keyboard events and using for slide navigation.
111 """
112 urls = (self.slideurl(1),
113 self.slideurl(self.slidenumber - 1),
114 self.slideurl(self.slidenumber + 1),
115 self.slideurl(len(self.slideinfo) - 1))
116 return (self.script_template % urls)
117
118
119 def _makeslidelink(self, i, text=None):
120 """ Return a URL link to slide number 'i'. The url title will be the
121 slide number and the title attribute will be the slide title.
122 """
123 if text == None:
124 text = str(i)
125 if i == self.slidenumber:
126 return text
127 else:
128 return self.page.link_to(self.request, text=text, \
129 querystr='action=Slideshow&slidenumber=%d' % i, \
130 attrs='title="%s"' % self.slideinfo[i-1][0])
131
132 def navigationtable(self):
133 """ Return an HTML table for navigating between slides
134 """
135
136 # setup a start and end range around the current slide - up to 20
137 # slides will be displayed
138 slidestart = 1
139 slideend = len(self.slideinfo)
140 if slideend > 20:
141 if self.slidenumber > 10:
142 slideend = min(self.slidenumber + 10, slideend)
143 slidestart = slideend - 19
144 else:
145 slideend = 20
146
147 # Links to the parent page, and the first and previous slides
148 items = []
149 items.append(self.page.link_to(self.request, text='^',
150 attrs='title="Stop Slideshow"'))
151 items.append(self._makeslidelink(1, '|<'))
152 items.append(self._makeslidelink(max(self.slidenumber - 1, 1), '<<'))
153
154 # Numbered slide links
155 for i in range(slidestart, slideend + 1):
156 items.append(self._makeslidelink(i))
157
158 # Links to the next and last slides
159 items.append(self._makeslidelink(min(self.slidenumber + 1,
160 len(self.slideinfo)), '>>'))
161 items.append(self._makeslidelink(len(self.slideinfo), '>|'))
162
163 return self.formatter.table(1, {'tableclass': 'navigation'}) + \
164 self.formatter.table_row(1) + \
165 self.formatter.table_cell(1) + \
166 " ".join(items) + \
167 self.formatter.table_cell(0) + \
168 self.formatter.table_row(0) + \
169 self.formatter.table(0)
170
171 def render(self):
172 """ Render a slide from a page """
173 request = self.request
174
175 # Non-existant slide requested.
176 if self.slidenumber < 0 or self.slidenumber > len(self.slideinfo):
177 request.http_headers()
178 request.page.send_page(request, msg='End of slides')
179 return
180
181 request.http_headers()
182 request.setContentLanguage(request.lang)
183
184 # Send the header in 'projection' mode - for large print and no headings
185 # Q. Would it be better to use the slide title instead of the overall
186 # page title?
187 wikiutil.send_title(request, self.page.split_title(request, force=1),
188 print_mode=1, media='projection')
189
190 # Extract the requested slide, and write it as a page in its own right,
191 # along with the navigation aids
192 request.write(self.navigationscript())
193 request.write(request.formatter.startContent("content"))
194 title, start, end = self.slideinfo[self.slidenumber - 1]
195 parser = Parser(self.body[start:end], request)
196 parser.format(request.formatter)
197 request.write(self.navigationtable())
198 request.write(request.formatter.endContent())
199 wikiutil.send_footer(request, self.pagename, print_mode=1)
200
201 def execute(pagename, request):
202 slideshow(pagename, request).render()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.