From: R. Steve McKown Date: Tue, 9 Aug 2011 02:14:40 +0000 (-0600) Subject: Merge branch 'upstream' X-Git-Url: https://oss.titaniummirror.com/gitweb?a=commitdiff_plain;h=b5bc4ffdfbaa76db7cd4cdeb078097ec17024f6b;hp=-c;p=webber.git Merge branch 'upstream' Conflicts: in/sitemap.md plugins/read_markdown.py --- b5bc4ffdfbaa76db7cd4cdeb078097ec17024f6b diff --combined in/sitemap.md index ca8649f,afcf51e..ae8fd01 --- a/in/sitemap.md +++ b/in/sitemap.md @@@ -1,5 -1,9 +1,6 @@@ title: Sitemap -parent: Home -hide: true +parent: Webber + lang: en template: sitemap -ctime: 2009-06-24 -mtime: 2009-06-24 The following pages exist: diff --combined in/webber.conf index f5117ce,675db98..1403d85 --- a/in/webber.conf +++ b/in/webber.conf @@@ -1,7 -1,7 +1,7 @@@ -template: "history" +template: "sidebar" subtitle: "Webber" main_url: "www.holgerschurig.de/projects/webber" - date_format: "%Y-%m.%d" + date_format: "%Y-%m-%d" input_encoding: "iso-8859-1" output_encoding: "iso-8859-1" plugins: [ @@@ -14,11 -14,13 +14,13 @@@ "read_markdown", "template_mako", "google_sitemap", + "toc", ] - exclude_dir: [ + exclude_dirs: [ ] exclude_files: [ "webber.conf", + "directory.conf", "*.tmpl", ] copy_files: [ diff --combined webber.py index f3e0f63,9913e81..a59583b --- a/webber.py +++ b/webber.py @@@ -11,21 -11,21 +11,21 @@@ from config import Holde __all__ = [ # Globals - "cfg", # configuration from webber.ini - "directories", # global hash of directories, by rel_path - "files", # global hash of files, by rel_path - "functions", # all exported template functions + "cfg", # configuration from webber.ini + "directories", # global hash of directories, by rel_path + "files", # global hash of files, by rel_path + "functions", # all exported template functions # Functions - "set_hook", # decorator for hook-functions - "set_macro", # define macro + "set_hook", # decorator for hook-functions + "set_macro", # define macro "set_function", # define functions for the template "get_file_for", "get_link_from", "get_current_file", # because mako-called functions cannot access the - # current File object + # current File object "get_program_directory", - "log", # misc logging functions + "log", # misc logging functions "info", "warning", "error", @@@ -50,7 -50,18 +50,18 @@@ class Directory(Holder) def __init__(self, **kw): Holder.__init__(self, **kw) - directories[kw["rel_path"]] = self + kw["rel_path"] = self + if self.rel_path == "": + self.rel_path = "." + directories[self.rel_path] = self + try: + self.load(os.path.join(self.abs_path, "directory.conf")) + #print self + except IOError: + pass + + def __repr__(self): + return "" % self.rel_path files = {} @@@ -63,6 -74,7 +74,7 @@@ class File(Holder) Holder.__init__(self, **kw) files[kw["rel_path"]] = self self.render = None + self.contents = None mtime = os.stat(self.path)[stat.ST_MTIME] self.mtime = mtime self.ctime = mtime @@@ -80,7 -92,7 +92,7 @@@ if read_keywords: s = s.strip() #print "kwd:", s - if s==terminate_line: + if s == terminate_line: read_keywords = False continue @@@ -115,16 -127,19 +127,19 @@@ # Warn about long titles / long linktitles if len(self.linktitle) > 20: - log('%s: define a shorter "linktitle: xxx"') + log('%s: define a shorter linktitle' % self.rel_path) self.contents = "".join(txt) + def __repr__(self): + return "" % self.rel_path + _get_file_for_cache = {} def get_file_for(name): """webber.files is an hash of File objects, but keyed on the real file name. This function returns a File object for a specific linktitle.""" - + try: return _get_file_for_cache[name] except: @@@ -138,6 -153,10 +153,10 @@@ #print " via linktitle:", s _get_file_for_cache[name] = f return f + if f.title == name: + #print " via title:", s + _get_file_for_cache[name] = f + return f except: pass # Allow exact match as well @@@ -206,8 -225,8 +225,8 @@@ def relpath(base_path, target) def get_link_from(source, dest): - #print "get_link_from", source, dest - #print source + if dest is None: + raise KeyError if not isinstance(source, File): source = get_file_for(source) if not source: @@@ -216,7 -235,7 +235,7 @@@ if not isinstance(dest, File): dest = get_file_for(dest) if not dest: - print "NO DEST" + warning("unknown link from %s to %s" % (source.rel_path, dest)) return "." rel_path = relpath(directories[source.direc].abs_path, directories[dest.direc].abs_path) try: @@@ -228,7 -247,7 +247,7 @@@ if rel_path.startswith("./"): rel_path = rel_path[2:] #print " from path:", source.out_path - #print " to path: ", out_path + #print " to path: ", out_path #print " rel path: ", rel_path return rel_path @@@ -254,14 -273,14 +273,14 @@@ def get_program_directory() # # Logging # - # 1 Error - # 2 Warning - # 3 Info - # 4 Log + # 1 Error + # 2 Warning + # 3 Info + # 4 Log # 5... Debug # def log(s, level=4): - if level>4: + if level > 4: indent = " " * (level-4) else: indent = "" @@@ -287,43 -306,43 +306,43 @@@ def info(s) # IkiWiki does something like this: # At startup: - # getopt modify ARGV - # checkconfig check configuration - # refresh allow plugins to build source files + # getopt modify ARGV + # checkconfig check configuration + # refresh allow plugins to build source files # While scanning files: - # needsbuild detect if page needs to be rebuild - # filter arbitrary changes - # scan collect metadata + # needsbuild detect if page needs to be rebuild + # filter arbitrary changes + # scan collect metadata # While rendering files: - # filter arbitrary changes - # preprocess execute macros - # linkify change wikilinks into links - # htmlize turns text into html - # sanitize sanitize html - # templatefile allows changing of the template on a per-file basis - # pagetemplate fill template with page - # format similar to sanitize, but act on whole page body + # filter arbitrary changes + # preprocess execute macros + # linkify change wikilinks into links + # htmlize turns text into html + # sanitize sanitize html + # templatefile allows changing of the template on a per-file basis + # pagetemplate fill template with page + # format similar to sanitize, but act on whole page body # At the end: - # savestate plugins can save their state + # savestate plugins can save their state # # # We do something like this: # # At startup: - # addoptions allow plugins to add command-line options - # checkconfig check configuration - # start + # addoptions allow plugins to add command-line options + # checkconfig check configuration + # start # While reading files: - # read ask any reader (plugins!) to read the file - # filter ask anybody to filter the contents + # read ask any reader (plugins!) to read the file + # filter ask anybody to filter the contents # While scanning files: - # scan called per file, let plugins act on file data - # scan_done Allows post-processing of scanned data + # scan called per file, let plugins act on file data + # scan_done Allows post-processing of scanned data # While rendering files: - # htmlize turns text into html-part - # linkify convert link macros to HTML - # pagetemplate ask template engine (plugin!) to generate HTML out - # of template and body part + # htmlize turns text into html-part + # linkify convert link macros to HTML + # pagetemplate ask template engine (plugin!) to generate HTML out + # of template and body part # At the end: # finish # @@@ -336,13 -355,11 +355,11 @@@ hooks = { def load_plugins(): """Loads all plugins in the plugins directory.""" sys.path.append(os.path.join(get_program_directory(), "plugins")) + if cfg.has_key("plugin_dirs"): + for s in cfg.plugin_dirs: + sys.path.append(s) for s in cfg.plugins: - #print "import:", s - #try: exec "import %s" % s - #except: - # print "Could not import plugin '%s'" % s - # sys.exit(1) def set_hook(name, last=False): @@@ -434,28 -451,23 +451,30 @@@ def iso_to_time(val) try: t = time.strptime(val, "%Y-%m-%d") except ValueError: - warning("%s: wrong ISO format in '%s'" % (self.rel_path, s)) + warning("wrong ISO format in '%s'" % val) return int(time.mktime(t)) @set_function("format_date") - def format_date(timestamp): - return time.strftime(cfg.date_format, time.localtime(timestamp)) + def format_date(timestamp, format=None): + if not format: + format = cfg.date_format + return time.strftime(format, time.localtime(timestamp)) @set_function("get_time") - def get_time(): - return format_date(time.time()) + def get_time(format=None): + return format_date(time.time(), format) @set_function("get_current_file") def get_current_file(): return current_file +@set_function("get_path_to_root") +def get_path_to_root(): + rel_path = relpath(directories[current_file.direc].abs_path, directories[''].abs_path) + rel_path = os.path.join(rel_path, os.path.split("")[1]) + if rel_path[-1] == "/": + rel_path = rel_path[:-1] + return rel_path @@@ -485,9 -497,9 +504,9 @@@ def read_file(direc, file) return_holder=False) if not contents: return + file.contents = contents log("filtering file %s" % file.rel_path, level=6) - file.contents = contents res = run_hooks("filter", direc=direc, file=file) @@@ -519,7 -531,7 +538,7 @@@ def walk_tree(dirpath) full_path = os.path.join(dirpath, s) ok = True if os.path.isdir(full_path): - for e in cfg.exclude_dir: + for e in cfg.exclude_dirs: if fnmatch.fnmatchcase(s, e): log("ignoring directory %s" % s, level=7) ok = False @@@ -551,7 -563,7 +570,7 @@@ ) file.inheritFrom(direc) read_file(direc, file) - + walk(dirpath) @@@ -562,14 -574,14 +581,14 @@@ # reMacro = re.compile(r''' - \[\[\! # Begin of macro + \[\[\! # Begin of macro \s* - ([^\s\]]+) # Macro name + ([^\s\]]+) # Macro name (?: - \s+ # optional space - ([^\]]+) # optional argumens + \s+ # optional space + ([^\]]+) # optional argumens )? - \]\] # End of macro + \]\] # End of macro ''', re.VERBOSE) reMacroArgs = re.compile(r''' ([-_\w]+) # parameter name @@@ -578,9 -590,9 +597,9 @@@ = \s* (?: - "([^"]*)" # single-quoted + "([^"]*)" # single-quoted | - (\S+) # unquoted + (\S+) # unquoted ) )? ''', re.VERBOSE) @@@ -608,21 -620,27 +627,27 @@@ def run_macros(file, contents) s = reMacro.sub(do_macro, contents) #print s return s - + def scan_files(): info("Scanning files ...") for s in files: file = files[s] - try: - # Just check if the file has contents - contents = file.contents - except: + if not file.has_key("contents"): continue + # try: + # # Just check if the file has contents + # contents = file.contents + # except: + # continue direc = directories[file.direc] + # "calculate" output file name + if file.render and file.render == "html": + file.out_path = os.path.splitext(s)[0] + ".html" + run_hooks("scan", direc=direc, file=file) @@@ -668,9 -686,6 +693,6 @@@ def render_files() continue file.contents = contents - # Output-Filename "berechnen" - file.out_path = os.path.splitext(fname_in)[0] + ".html" - for fname_in in files: file = files[fname_in] current_file = file @@@ -679,18 -694,16 +701,16 @@@ continue direc = directories[file.direc] - contents = run_hooks("linkify", + run_hooks("linkify", direc=direc, file=file, - return_holder=False) + return_holder=True) #print "contents after 'linkify':", contents - if not contents: + if not file.contents: continue - file.contents = contents - # TODO: einige Fragmente sollen u.U. in eine andere - # Webseite eingebaut werden und sollten daher nicht in - # ein HTML-File landen + # TODO: make it possible to render also "fragments", e.g. + # parts that don't end up immediately in a the HTML file. contents = run_hooks("pagetemplate", direc=direc, file=file, @@@ -708,12 -721,13 +728,13 @@@ except OSError: pass - # TODO: evtl. überprüfen, ob contents == f.read(), dann nicht schreiben + # TODO: check if contents == f.read(). In this case we don't + # need to save. Probably overkill. log("writing file %s" % fname_out, level=6) f = open(fname_out, "w") f.write(contents) f.close() - # TODO: Time-Stamps setzen? + os.utime(fname_out, (file.mtime, file.mtime)) #print file.mtime, file.get("ctime","?") #print direc.keys() @@@ -746,7 -760,7 +767,7 @@@ def addoptions(params) return parser - + @set_hook("checkconfig", last=True) def checkconfig(params): # Ensure absolute paths that end in '/'. @@@ -775,7 -789,12 +796,12 @@@ def main() # link contents of webber.ini into cfg and set some defaults, # then let plugins fixup things in cfg.* cfg.inheritFrom(options) - cfg.setDefault("exclude_dir", ["plugins"]) + cfg.setDefault("exclude_dirs", []) + cfg.setDefault("exclude_files", ["webber.conf", "directory.conf", "*.tmpl"]) + cfg.setDefault("copy_files", []) + cfg.setDefault("input_encoding", "iso-8859-1") + cfg.setDefault("output_encoding", "iso-8859-1") + cfg.setDefault("template", "default") run_hooks("checkconfig") run_hooks("start")