X-Git-Url: http://nitlanguage.org diff --git a/contrib/nitiwiki/src/wiki_base.nit b/contrib/nitiwiki/src/wiki_base.nit index fa78818..70cf35f 100644 --- a/contrib/nitiwiki/src/wiki_base.nit +++ b/contrib/nitiwiki/src/wiki_base.nit @@ -16,7 +16,6 @@ module wiki_base import template::macro -import markdown import opts import ini @@ -51,12 +50,17 @@ class Nitiwiki # Synchronize local output with the distant `WikiConfig::rsync_dir`. fun sync do var root = expand_path(config.root_dir, config.out_dir) - sys.system "rsync -vr --delete {root}/ {config.rsync_dir}" + var rsync_dir = config.rsync_dir + if rsync_dir == "" then + message("Error: configure `wiki.rsync_dir` to use rsync.", 0) + return + end + sys.system "rsync -vr --delete -- {root.escape_to_sh}/ {rsync_dir.escape_to_sh}" end # Pull data from git repository. fun fetch do - sys.system "git pull {config.git_origin} {config.git_branch}" + sys.system "git pull {config.git_origin.escape_to_sh} {config.git_branch.escape_to_sh}" end # Analyze wiki files from `dir` to build wiki entries. @@ -72,12 +76,14 @@ class Nitiwiki end end + # Render output. + fun render do end + # Show wiki status. fun status do print "nitiWiki" print "name: {config.wiki_name}" print "config: {config.ini_file}" - print "url: {config.root_url}" print "" if root_section.is_dirty then print "There is modified files:" @@ -105,7 +111,7 @@ class Nitiwiki end end - # Display msg if `level >= verbose_level` + # Display msg if `level <= verbose_level` fun message(msg: String, level: Int) do if level <= verbose_level then print msg end @@ -113,11 +119,11 @@ class Nitiwiki # List markdown source files from a directory. fun list_md_files(dir: String): Array[String] do var files = new Array[String] - var pipe = new ProcessReader("find", dir, "-name", "*.md") + var pipe = new ProcessReader("find", dir, "-name", "*.{config.md_ext}") while not pipe.eof do var file = pipe.read_line if file == "" then break # last line - var name = file.basename(".md") + var name = file.basename(".{config.md_ext}") if name == "header" or name == "footer" or name == "menu" then continue files.add file end @@ -145,7 +151,7 @@ class Nitiwiki path = path.simplify_path if entries.has_key(path) then return entries[path].as(WikiSection) var root = expand_path(config.root_dir, config.source_dir) - var name = path.basename("") + var name = path.basename var section = new WikiSection(self, name) entries[path] = section if path == root then return section @@ -163,6 +169,7 @@ class Nitiwiki # `path` is used to determine the ancestor sections. protected fun new_article(path: String): WikiArticle do if entries.has_key(path) then return entries[path].as(WikiArticle) + message("Found article `{path}`", 2) var article = new WikiArticle.from_source(self, path) var section = new_section(path.dirname) section.add_child(article) @@ -185,12 +192,12 @@ class Nitiwiki # # REQUIRE: `has_template` fun load_template(name: String): TemplateString do - assert has_template(name) + if not has_template(name) then + message("Error: can't load template `{name}`", 0) + exit 1 + end var file = expand_path(config.root_dir, config.templates_dir, name) var tpl = new TemplateString.from_file(file) - if tpl.has_macro("ROOT_URL") then - tpl.replace("ROOT_URL", config.root_url) - end if tpl.has_macro("TITLE") then tpl.replace("TITLE", config.wiki_name) end @@ -203,6 +210,26 @@ class Nitiwiki return tpl end + # Does a sideblock named `name` exists for this wiki? + fun has_sideblock(name: String): Bool do + name = "{name}.{config.md_ext}" + return expand_path(config.root_dir, config.sidebar_dir, name).file_exists + end + + # Load a markdown block with `name` from `WikiConfig::sidebar_dir`. + private fun load_sideblock(name: String): nullable String do + if not has_sideblock(name) then + message("Error: can't load sideblock `{name}`", 0) + return null + end + name = "{name}.{config.md_ext}" + var path = expand_path(config.root_dir, config.sidebar_dir, name) + var file = new FileReader.open(path) + var res = file.read_all + file.close + return res + end + # Join `parts` as a path and simplify it fun expand_path(parts: String...): String do var path = "" @@ -308,7 +335,7 @@ abstract class WikiEntry # Result is returned as an array containg ordered entries: # `breadcrumbs.first` is the root entry and # `breadcrumbs.last == self` - fun breadcrumbs: Array[WikiEntry] is cached do + var breadcrumbs: Array[WikiEntry] is lazy do var path = new Array[WikiEntry] var entry: nullable WikiEntry = self while entry != null and not entry.is_root do @@ -318,6 +345,9 @@ abstract class WikiEntry return path.reversed end + # Sidebar relative to this wiki entry. + var sidebar = new WikiSidebar(self) + # Relative path from `wiki.config.root_dir` to source if any. fun src_path: nullable String is abstract @@ -512,25 +542,22 @@ class WikiArticle # Page content. # # What you want to be displayed in the page. - var content: nullable Writable = null - - # Headlines ids and titles. - var headlines = new ArrayMap[String, HeadLine] + var content: nullable Writable = null is writable - # Create a new articleu sing a markdown source file. + # Create a new article using a markdown source file. init from_source(wiki: Nitiwiki, md_file: String) do src_full_path = md_file - init(wiki, md_file.basename(".md")) - var md_proc = new MarkdownProcessor - content = md_proc.process(md) - headlines = md_proc.emitter.decorator.headlines + init(wiki, md_file.basename(".{wiki.config.md_ext}")) + content = md end redef var src_full_path: nullable String = null redef fun src_path do + var src_full_path = self.src_full_path if src_full_path == null then return null - return src_full_path.substring_from(wiki.config.root_dir.length) + var res = wiki.config.root_dir.relpath(src_full_path) + return res end # The page markdown source content. @@ -538,8 +565,8 @@ class WikiArticle # Extract the markdown text from `source_file`. # # REQUIRE: `has_source`. - fun md: String is cached do - assert has_source + var md: nullable String is lazy do + if not has_source then return null var file = new FileReader.open(src_full_path.to_s) var md = file.read_all file.close @@ -559,6 +586,28 @@ class WikiArticle redef fun to_s do return "{name} ({parent or else "null"})" end +# The sidebar is displayed in front of the main panel of a `WikiEntry`. +class WikiSidebar + + # Wiki used to parse sidebar blocks. + var wiki: Nitiwiki is lazy do return entry.wiki + + # WikiEntry this panel is related to. + var entry: WikiEntry + + # Blocks are ieces of markdown that will be rendered in the sidebar. + var blocks: Array[Text] is lazy do + var res = new Array[Text] + # TODO get blocks from the entry for more customization + for name in entry.wiki.config.sidebar_blocks do + var block = wiki.load_sideblock(name) + if block == null then continue + res.add block + end + return res + end +end + # Wiki configuration class. # # This class provides services that ensure static typing when accessing the `config.ini` file. @@ -566,9 +615,8 @@ class WikiConfig super ConfigTree # Returns the config value at `key` or return `default` if no key was found. - private fun value_or_default(key: String, default: String): String do - if not has_key(key) then return default - return self[key] + protected fun value_or_default(key: String, default: String): String do + return self[key] or else default end # Site name displayed. @@ -577,7 +625,7 @@ class WikiConfig # # * key: `wiki.name` # * default: `MyWiki` - fun wiki_name: String is cached do return value_or_default("wiki.name", "MyWiki") + var wiki_name: String is lazy do return value_or_default("wiki.name", "MyWiki") # Site description. # @@ -585,7 +633,7 @@ class WikiConfig # # * key: `wiki.desc` # * default: `` - fun wiki_desc: String is cached do return value_or_default("wiki.desc", "") + var wiki_desc: String is lazy do return value_or_default("wiki.desc", "") # Site logo url. # @@ -593,14 +641,16 @@ class WikiConfig # # * key: `wiki.logo` # * default: `` - fun wiki_logo: String is cached do return value_or_default("wiki.logo", "") + var wiki_logo: String is lazy do return value_or_default("wiki.logo", "") - # Root url of the wiki. + # Markdown extension recognized by this wiki. # - # * key: `wiki.root_url` - # * default: `http://localhost/` - fun root_url: String is cached do return value_or_default("wiki.root_url", "http://localhost/") - + # We allow only one kind of extension per wiki. + # Files with other markdown extensions will be treated as resources. + # + # * key: `wiki.md_ext` + # * default: `md` + var md_ext: String is lazy do return value_or_default("wiki.md_ext", "md") # Root directory of the wiki. # @@ -608,7 +658,7 @@ class WikiConfig # # * key: `wiki.root_dir` # * default: `./` - fun root_dir: String is cached do return value_or_default("wiki.root_dir", "./").simplify_path + var root_dir: String is lazy do return value_or_default("wiki.root_dir", "./").simplify_path # Pages directory. # @@ -616,7 +666,7 @@ class WikiConfig # # * key: `wiki.source_dir # * default: `pages/` - fun source_dir: String is cached do + var source_dir: String is lazy do return value_or_default("wiki.source_dir", "pages/").simplify_path end @@ -627,7 +677,7 @@ class WikiConfig # # * key: `wiki.out_dir` # * default: `out/` - fun out_dir: String is cached do return value_or_default("wiki.out_dir", "out/").simplify_path + var out_dir: String is lazy do return value_or_default("wiki.out_dir", "out/").simplify_path # Asset files directory. # @@ -636,7 +686,7 @@ class WikiConfig # # * key: `wiki.assets_dir` # * default: `assets/` - fun assets_dir: String is cached do + var assets_dir: String is lazy do return value_or_default("wiki.assets_dir", "assets/").simplify_path end @@ -647,7 +697,7 @@ class WikiConfig # # * key: `wiki.templates_dir` # * default: `templates/` - fun templates_dir: String is cached do + var templates_dir: String is lazy do return value_or_default("wiki.templates_dir", "templates/").simplify_path end @@ -657,7 +707,7 @@ class WikiConfig # # * key: `wiki.template` # * default: `template.html` - fun template_file: String is cached do + var template_file: String is lazy do return value_or_default("wiki.template", "template.html") end @@ -668,7 +718,7 @@ class WikiConfig # # * key: `wiki.header` # * default: `header.html` - fun header_file: String is cached do + var header_file: String is lazy do return value_or_default("wiki.header", "header.html") end @@ -678,7 +728,7 @@ class WikiConfig # # * key: `wiki.menu` # * default: `menu.html` - fun menu_file: String is cached do + var menu_file: String is lazy do return value_or_default("wiki.menu", "menu.html") end @@ -689,29 +739,94 @@ class WikiConfig # # * key: `wiki.footer` # * default: `footer.html` - fun footer_file: String is cached do + var footer_file: String is lazy do return value_or_default("wiki.footer", "footer.html") end + # Automatically add a summary. + # + # * key: `wiki.auto_summary` + # * default: `true` + var auto_summary: Bool is lazy do + return value_or_default("wiki.auto_summary", "true") == "true" + end + + # Automatically add breadcrumbs. + # + # * key: `wiki.auto_breadcrumbs` + # * default: `true` + var auto_breadcrumbs: Bool is lazy do + return value_or_default("wiki.auto_breadcrumbs", "true") == "true" + end + + # Sidebar position. + # + # Position of the sidebar between `left`, `right` and `none`. Any other value + # will be considered as `none`. + # + # * key: `wiki.sidebar` + # * default: `left` + var sidebar: String is lazy do + return value_or_default("wiki.sidebar", "left") + end + + # Sidebar markdown block to include. + # + # Blocks are specified by their filename without the extension. + # + # * key: `wiki.sidebar.blocks` + # * default: `[]` + var sidebar_blocks: Array[String] is lazy do + var res = new Array[String] + if not has_key("wiki.sidebar.blocks") then return res + for val in at("wiki.sidebar.blocks").values do + res.add val + end + return res + end + + # Sidebar files directory. + # + # Directory where sidebar blocks are stored. + # **This path MUST be relative to `root_dir`.** + # + # * key: `wiki.sidebar_dir` + # * default: `sidebar/` + var sidebar_dir: String is lazy do + return value_or_default("wiki.sidebar_dir", "sidebar/").simplify_path + end + # Directory used by rsync to upload wiki files. # # This information is used to update your distant wiki files (like the webserver). # # * key: `wiki.rsync_dir` # * default: `` - fun rsync_dir: String is cached do return value_or_default("wiki.rsync_dir", "") + var rsync_dir: String is lazy do return value_or_default("wiki.rsync_dir", "") # Remote repository used to pull modifications on sources. # # * key: `wiki.git_origin` # * default: `origin` - fun git_origin: String is cached do return value_or_default("wiki.git_origin", "origin") + var git_origin: String is lazy do return value_or_default("wiki.git_origin", "origin") # Remote branch used to pull modifications on sources. # # * key: `wiki.git_branch` # * default: `master` - fun git_branch: String is cached do return value_or_default("wiki.git_branch", "master") + var git_branch: String is lazy do return value_or_default("wiki.git_branch", "master") + + # URL to source versionning used to display last changes + # + # * key: `wiki.last_changes` + # * default: `` + var last_changes: String is lazy do return value_or_default("wiki.last_changes", "") + + # URL to source edition. + # + # * key: `wiki.edit` + # * default: `` + var edit: String is lazy do return value_or_default("wiki.edit", "") end # WikiSection custom configuration.