]> oss.titaniummirror.com Git - webber.git/commitdiff
Merge branch 'upstream'
authorR. Steve McKown <rsmckown@gmail.com>
Tue, 9 Aug 2011 02:14:40 +0000 (20:14 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Tue, 9 Aug 2011 02:14:40 +0000 (20:14 -0600)
Conflicts:
in/sitemap.md
plugins/read_markdown.py

1  2 
in/sitemap.md
in/webber.conf
webber.py

diff --combined in/sitemap.md
index ca8649fd9d058c730df68c725e8ab3dcde47a260,afcf51e41e83be247d811e2e7f18f9dc937900a2..ae8fd016527cb288ed27a3f140324d3c54f193fa
@@@ -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 f5117ced36866ecb34910f3285c67a2e39da9474,675db98515f1d116d0f10f2e3da4ff8e99109ca5..1403d8520f06bcec584a83b63d36ec44e151855b
@@@ -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: [
        "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 f3e0f63fec5c57e0d50dc37870d4630869e4c02d,9913e81d0d4041e83149d6fa00982487452ebcf5..a59583be000c045e74d9cc57ddd8605131513433
+++ 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 "<Directory %s>" % 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
  
  
                # 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 "<File %s>" % 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:
                                #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:
        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:
        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
                                        )
                                        file.inheritFrom(direc)
                                        read_file(direc, file)
-                                               
        walk(dirpath)
  
  
  #
  
  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
                =
                \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
                        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,
                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")