X-Git-Url: http://nitlanguage.org diff --git a/contrib/nitiwiki/src/wiki_base.nit b/contrib/nitiwiki/src/wiki_base.nit index b250071..d3adc26 100644 --- a/contrib/nitiwiki/src/wiki_base.nit +++ b/contrib/nitiwiki/src/wiki_base.nit @@ -50,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. @@ -79,7 +84,6 @@ class Nitiwiki 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:" @@ -90,7 +94,7 @@ class Nitiwiki var entry = entries[path] if not entry.is_dirty then continue var name = entry.name - if entry.has_source then name = entry.src_path.to_s + if entry.has_source then name = entry.src_path.as(not null) if entry.is_new then print " + {name}" else @@ -137,7 +141,7 @@ class Nitiwiki fun need_render(src, target: String): Bool do if force_render then return true if not target.file_exists then return true - return src.file_stat.mtime >= target.file_stat.mtime + return src.file_stat.as(not null).mtime >= target.file_stat.as(not null).mtime end # Create a new `WikiSection`. @@ -147,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 @@ -194,9 +198,6 @@ class Nitiwiki 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 @@ -209,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 = "" @@ -223,7 +244,7 @@ class Nitiwiki # Used to translate ids in beautiful page names. fun pretty_name(name: String): String do name = name.replace("_", " ") - name = name.capitalized + name = name.capitalized(keep_upper=true) return name end end @@ -262,7 +283,7 @@ abstract class WikiEntry # Returns `-1` if not `has_source`. fun create_time: Int do if not has_source then return -1 - return src_full_path.file_stat.ctime + return src_full_path.as(not null).file_stat.as(not null).ctime end # Entry last modification time. @@ -270,7 +291,7 @@ abstract class WikiEntry # Returns `-1` if not `has_source`. fun last_edit_time: Int do if not has_source then return -1 - return src_full_path.file_stat.mtime + return src_full_path.as(not null).file_stat.as(not null).mtime end # Entry list rendering time. @@ -278,7 +299,7 @@ abstract class WikiEntry # Returns `-1` if `is_new`. fun last_render_time: Int do if is_new then return -1 - return out_full_path.file_stat.mtime + return out_full_path.file_stat.as(not null).mtime end # Entries hierarchy @@ -324,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 @@ -376,7 +400,7 @@ abstract class WikiEntry # then returns the main wiki template file. fun template_file: String do if is_root then return wiki.config.template_file - return parent.template_file + return parent.as(not null).template_file end # Header template file for `self`. @@ -384,7 +408,7 @@ abstract class WikiEntry # Behave like `template_file`. fun header_file: String do if is_root then return wiki.config.header_file - return parent.header_file + return parent.as(not null).header_file end # Footer template file for `self`. @@ -392,7 +416,7 @@ abstract class WikiEntry # Behave like `template_file`. fun footer_file: String do if is_root then return wiki.config.footer_file - return parent.footer_file + return parent.as(not null).footer_file end # Menu template file for `self`. @@ -400,7 +424,7 @@ abstract class WikiEntry # Behave like `template_file`. fun menu_file: String do if is_root then return wiki.config.menu_file - return parent.menu_file + return parent.as(not null).menu_file end # Display the entry `name`. @@ -418,7 +442,7 @@ class WikiSection redef fun title do if has_config then - var title = config.title + var title = config.as(not null).title if title != null then return title end return super @@ -428,7 +452,7 @@ class WikiSection # # Hidden section are rendered but not linked in menus. fun is_hidden: Bool do - if has_config then return config.is_hidden + if has_config then return config.as(not null).is_hidden return false end @@ -437,7 +461,7 @@ class WikiSection if parent == null then return wiki.config.source_dir else - return wiki.expand_path(parent.src_path, name) + return wiki.expand_path(parent.as(not null).src_path, name) end end @@ -453,7 +477,7 @@ class WikiSection private fun try_load_config do var cfile = wiki.expand_path(wiki.config.root_dir, src_path, wiki.config_filename) if not cfile.file_exists then return - wiki.message("Custom config for section {name}", 1) + wiki.message("Custom config for section {name}", 2) config = new SectionConfig(cfile) end @@ -462,41 +486,41 @@ class WikiSection # Also check custom config. redef fun template_file do if has_config then - var tpl = config.template_file + var tpl = config.as(not null).template_file if tpl != null then return tpl end if is_root then return wiki.config.template_file - return parent.template_file + return parent.as(not null).template_file end # Also check custom config. redef fun header_file do if has_config then - var tpl = config.header_file + var tpl = config.as(not null).header_file if tpl != null then return tpl end if is_root then return wiki.config.header_file - return parent.header_file + return parent.as(not null).header_file end # Also check custom config. redef fun footer_file do if has_config then - var tpl = config.footer_file + var tpl = config.as(not null).footer_file if tpl != null then return tpl end if is_root then return wiki.config.footer_file - return parent.footer_file + return parent.as(not null).footer_file end # Also check custom config. redef fun menu_file do if has_config then - var tpl = config.menu_file + var tpl = config.as(not null).menu_file if tpl != null then return tpl end if is_root then return wiki.config.menu_file - return parent.menu_file + return parent.as(not null).menu_file end end @@ -510,7 +534,8 @@ class WikiArticle # Articles can only have `WikiSection` as parents. redef type PARENT: WikiSection - redef fun title: String do + redef fun title do + var parent = self.parent if name == "index" and parent != null then return parent.title return super end @@ -527,11 +552,13 @@ class WikiArticle content = md end - redef var src_full_path: nullable String = null + redef var src_full_path = 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. @@ -541,7 +568,7 @@ class WikiArticle # REQUIRE: `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 file = new FileReader.open(src_full_path.as(not null)) var md = file.read_all file.close return md @@ -552,7 +579,7 @@ class WikiArticle redef fun is_dirty do if super then return true if has_source then - return wiki.need_render(src_full_path.to_s, out_full_path) + return wiki.need_render(src_full_path.as(not null), out_full_path) end return false end @@ -560,6 +587,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. @@ -567,9 +616,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. @@ -596,12 +644,6 @@ class WikiConfig # * default: `` var wiki_logo: String is lazy do return value_or_default("wiki.logo", "") - # Root url of the wiki. - # - # * key: `wiki.root_url` - # * default: `http://localhost/` - var root_url: String is lazy do return value_or_default("wiki.root_url", "http://localhost/") - # Markdown extension recognized by this wiki. # # We allow only one kind of extension per wiki. @@ -702,6 +744,59 @@ class WikiConfig 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").as(not null).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). @@ -721,6 +816,18 @@ class WikiConfig # * key: `wiki.git_branch` # * default: `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.