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.text_moin_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.emit_http_headers()
178 request.page.send_page(msg='End of slides')
179 return
180
181 # request.emit_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 request.theme.send_title(self.page.split_title(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 request.theme.send_footer(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.