def humanlink(s):
return re.sub(r'(?:.*[/:]|)([^:/\.]+)(?:\.[^/:]+|)$', r'\1', s.replace('_', ' '))
-# Split arg lists like "blah| blah blah| width=100 | align = center",
+# Split arg lists like "blah|blah blah| width=100 | align = center",
# return a list containing anonymous arguments and a map containing the named arguments
def parse_args(s):
args = []
- kwargs = {}
+ kvargs = {}
for arg in s.strip('<[{}]>').split('|'):
m = re.match('\s*(\w+)\s*=\s*(.+)\s*', arg)
if m is not None:
- kwargs[m.group(1)] = m.group(2)
+ kvargs[m.group(1)] = m.group(2)
else:
args.append(arg.strip())
- return (args, kwargs)
+ return (args, kvargs)
def url_args(kvargs):
argv = []
elif image_re.match(name):
return '<a href="%s"><img border="0" src="%s" alt="%s" /></a>' % (url, url + url_args(kvargs), descr)
elif file_re.match(name) and not ext_re.search(name): # FIXME: this guesses a wiki page
- return Page(name).send_naked()
+ return Page(name).send_naked(kvargs)
else:
return '<iframe width="100%%" scrolling="auto" frameborder="0" src="%s"><a href="%s">%s</a></iframe>' \
% (url, url, name)
cgi.print_arguments()
cgi.print_form(form)
cgi.print_environ()
- print('''
-<div id="footer"><hr />
-<p class="copyright">
-<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img class="license" alt="Creative Commons License" src="%s" /></a>
-<span class="benchmark">generated in %0.3fs</span> by <a href="http://www.codewiz.org/wiki/GeekiGeeki">GeekiGeeki</a> version %s
-</p>
-''' % (relative_url('cc-by-sa.png'), clock() - start_time, __version__))
- if mod_string:
- print('<p class="modified">last modified %s</p>' % mod_string)
- print('</div></body></html>')
+ link_inline("sys/footer", kvargs= { 'LAST_MODIFIED': mod_string })
+ print("</body></html>")
+
+def _macro_ELAPSED_TIME(*args, **kvargs):
+ return "%03f" % (clock() - start_time)
+
+def _macro_VERSION(*args, **kvargs):
+ return __version__
class WikiFormatter:
"""Object that turns Wiki markup into HTML.
All formatting commands can be parsed one line at a time, though
some state is carried over between lines.
"""
- def __init__(self, raw):
+ def __init__(self, raw, kvargs=None):
self.raw = raw
+ self.kvargs = kvargs or {}
self.h_level = 0
self.in_pre = self.in_html = self.in_table = self.in_li = False
self.in_header = True
"**": ["b", False],
"##": ["tt", False],
"__": ["u", False],
+ "--": ["del", False],
"^^": ["sup", False],
",,": ["sub", False],
"''": ["em", False], # LEGACY
style[1] = not style[1]
return ['</', '<'][style[1]] + style[0] + '>'
+ def _glyph_repl(self, word):
+ return '—'
+
def _tit_repl(self, word):
if self.h_level:
result = '</h%d><p>\n' % self.h_level
def _macro_repl(self, word):
try:
- args, kwargs = parse_args(word)
+ args, kvargs = parse_args(word)
+ if args[0] in self.kvargs:
+ return self.kvargs[args[0]]
macro = globals().get('_macro_' + args[0])
if not macro:
- exec(open("macros/" + name + ".py").read(), globals())
- macro = globals().get('_macro_' + name)
- return macro(*args, **kwargs)
- except Exception:
- msg = cgi.escape(word)
+ exec(open("macros/" + args[0] + ".py").read(), globals())
+ macro = globals().get('_macro_' + args[0])
+ return macro(*args, **kvargs)
+ except Exception, e:
+ msg = cgi.escape(word) + ": " + cgi.escape(e.message)
if not self.in_html:
msg = '<strong class="error">' + msg + '</strong>'
return msg
print('<div class="wiki"><p>')
scan_re = re.compile(r"""(?:
- # Styles and formatting
- (?P<b> \*\*|'''|//|''|\#\#|``|__|\^\^|,,)
+ # Styles and formatting ("--" must cling to a word to disambiguate it from the dash)
+ (?P<b> \*\* | // | \#\# | __ | --\b | \b-- | \^\^ | ,, | ''' | '' | `` )
| (?P<tit> \={2,6})
| (?P<br> \\\\)
| (?P<rule> ^-{3,})
| (?P<hi> \b( FIXME | TODO | DONE )\b )
+ | (?P<glyph> --)
# Links
| (?P<macro> \<\<([^\s\|\>]+)(?:\s*\|\s*([^\>]+)|)\>\>)
| (?P<hurl> \[\[([^\s\|]+)(?:\s*\|\s*([^\]]+)|)\]\])
# Inline HTML
- | (?P<html> <(br|hr|div|span|form|iframe|input|textarea|a|img|h[1-5])\b )
+ | (?P<html> <(br|hr|div|span|form|iframe|input|textarea|a|img|h[1-5])\b )
| (?P<htmle> ( /\s*> | </(br|hr|div|span|form|iframe|input|textarea|a|img|h[1-5])> ) )
| (?P<ent> [<>&] )
| (?P<url> (http|https|ftp|mailto)\:[^\s'\"]+\S)
| (?P<email> [-\w._+]+\@[\w.-]+)
- # Lists, divs, spans
+ # Lists, divs, spans and inline objects
| (?P<li> ^\s+[\*\#]\s+)
| (?P<pre> \{\{\{|\s*\}\}\})
| (?P<inl> \{\{([^\s\|]+)(?:\s*\|\s*([^\]]+)|)\}\})
def format_dir(self):
out = '== '
pathname = ''
- for dirname in self.page_name.split('/'):
+ for dirname in self.page_name.strip('/').split('/'):
pathname = (pathname + '/' + dirname) if pathname else dirname
out += '[[' + pathname + '|' + dirname + ']]/'
out += ' ==\n'
def can_read(self):
return self.can("read", True)
- def send_naked(self):
+ def send_naked(self, kvargs=None):
if self.can_read():
- WikiFormatter(self.get_raw_body()).print_html()
+ WikiFormatter(self.get_raw_body(), kvargs).print_html()
else:
send_guru("Read access denied by ACLs", "notice")
os.remove(name)
except OSError, err:
if err.errno != errno.ENOENT: raise err
- os.makedirs(os.path.split(name)[0])
+ path = os.path.split(name)[0]
+ if not os.path.exists(path):
+ os.makedirs(path)
os.rename(tmp_filename, name)
def save(self, newdata, changelog):