X-Git-Url: http://nitlanguage.org
diff --git a/contrib/nitiwiki/src/wiki_html.nit b/contrib/nitiwiki/src/wiki_html.nit
index 2bb8f8c..15ae4d7 100644
--- a/contrib/nitiwiki/src/wiki_html.nit
+++ b/contrib/nitiwiki/src/wiki_html.nit
@@ -15,7 +15,8 @@
# HTML wiki rendering
module wiki_html
-import wiki_base
+import wiki_links
+import markdown::decorators
redef class Nitiwiki
@@ -35,7 +36,7 @@ redef class Nitiwiki
var src = expand_path(config.root_dir, config.assets_dir)
var out = expand_path(config.root_dir, config.out_dir)
if need_render(src, expand_path(out, config.assets_dir)) then
- if src.file_exists then sys.system "cp -R {src} {out}"
+ if src.file_exists then sys.system "cp -R -- {src.escape_to_sh} {out.escape_to_sh}"
end
end
@@ -45,23 +46,32 @@ redef class Nitiwiki
sitemap.is_dirty = true
return sitemap
end
-end
-redef class WikiEntry
+ # Markdown processor used for inline element such as titles in TOC.
+ private var inline_processor: MarkdownProcessor is lazy do
+ var proc = new MarkdownProcessor
+ proc.emitter.decorator = new InlineDecorator
+ return proc
+ end
- # Url to `self` once generated.
- fun url: String do return wiki.config.root_url.join_path(breadcrumbs.join("/"))
+ # Inline markdown (remove h1, p, ... elements).
+ private fun inline_md(md: Writable): Writable do
+ return inline_processor.process(md.write_to_string)
+ end
+end
+redef class WikiEntry
# Get a `` template link to `self`
- fun tpl_link: Writable do
- return "{title}"
+ fun tpl_link(context: WikiEntry): Writable do
+ return "{title}"
end
end
redef class WikiSection
# Output directory (where to ouput the HTML pages for this section).
- redef fun out_path: String do
+ redef fun out_path do
+ var parent = self.parent
if parent == null then
return wiki.config.out_dir
else
@@ -74,25 +84,28 @@ redef class WikiSection
if is_new then
out_full_path.mkdir
else
- sys.system "touch {out_full_path}"
+ sys.system "touch -- {out_full_path.escape_to_sh}"
end
if has_source then
- wiki.message("Render section {out_path}", 1)
+ wiki.message("Render section {name} -> {out_path}", 1)
copy_files
end
var index = self.index
if index isa WikiSectionIndex then
- wiki.message("Render auto-index for section {out_path}", 1)
+ wiki.message("Render auto-index for section {name} -> {out_path}", 1)
index.is_dirty = true
add_child index
end
+ # Hack: Force the rendering of `index` first so that trails are collected
+ # TODO: Add first-pass analysis to collect global information before doing the rendering
+ index.render
super
end
# Copy attached files from `src_path` to `out_path`.
private fun copy_files do
assert has_source
- var dir = src_full_path.to_s
+ var dir = src_full_path.as(not null).to_s
for name in dir.files do
if name == wiki.config_filename then continue
if name.has_suffix(".md") then continue
@@ -100,22 +113,11 @@ redef class WikiSection
var src = wiki.expand_path(dir, name)
var out = wiki.expand_path(out_full_path, name)
if not wiki.need_render(src, out) then continue
- sys.system "cp -R {src} {out_full_path}"
- end
- end
-
- # The index page for this section.
- #
- # If no file `index.md` exists for this section,
- # a summary is generated using contained articles.
- var index: WikiArticle is lazy do
- for child in children.values do
- if child isa WikiArticle and child.is_index then return child
+ sys.system "cp -R -- {src.escape_to_sh} {out_full_path.escape_to_sh}"
end
- return new WikiSectionIndex(wiki, "index", self)
end
- redef fun tpl_link do return index.tpl_link
+ redef fun tpl_link(context) do return index.tpl_link(context)
# Render the section hierarchy as a html tree.
#
@@ -135,15 +137,15 @@ redef class WikiSection
#
# ~~~
fun tpl_tree(limit: Int): Template do
- return tpl_tree_intern(limit, 1)
+ return tpl_tree_intern(limit, 1, self)
end
# Build the template tree for this section recursively.
- protected fun tpl_tree_intern(limit, count: Int): Template do
+ protected fun tpl_tree_intern(limit, count: Int, context: WikiEntry): Template do
var out = new Template
var index = index
out.add "
"
- out.add tpl_link
+ out.add tpl_link(context)
if (limit < 0 or count < limit) and
(children.length > 1 or (children.length == 1)) then
out.add "
"
@@ -151,10 +153,10 @@ redef class WikiSection
if child == index then continue
if child isa WikiArticle then
out.add "
"
else if child isa WikiSection and not child.is_hidden then
- out.add child.tpl_tree_intern(limit, count + 1)
+ out.add child.tpl_tree_intern(limit, count + 1, context)
end
end
out.add "
"
@@ -166,7 +168,8 @@ end
redef class WikiArticle
- redef fun out_path: String do
+ redef fun out_path do
+ var parent = self.parent
if parent == null then
return wiki.expand_path(wiki.config.out_dir, "{name}.html")
else
@@ -174,32 +177,28 @@ redef class WikiArticle
end
end
- redef fun url do
- if parent == null then
- return wiki.config.root_url.join_path("{name}.html")
- else
- return parent.url.join_path("{name}.html")
- end
- end
-
- # Is `self` an index page?
- #
- # Checks if `self.name == "index"`.
- fun is_index: Bool do return name == "index"
-
redef fun render do
+ super
if not is_dirty and not wiki.force_render then return
- wiki.message("Render article {name}", 2)
var file = out_full_path
+ wiki.message("Render article {name} -> {file}", 1)
file.dirname.mkdir
tpl_page.write_to_file file
- super
end
+ # Load a template and resolve page-related macros
+ fun load_template(template_file: String): TemplateString do
+ var tpl = wiki.load_template(template_file)
+ if tpl.has_macro("ROOT_URL") then
+ tpl.replace("ROOT_URL", root_href)
+ end
+ return tpl
+ end
+
# Replace macros in the template by wiki data.
private fun tpl_page: TemplateString do
- var tpl = wiki.load_template(template_file)
+ var tpl = load_template(template_file)
if tpl.has_macro("TOP_MENU") then
tpl.replace("TOP_MENU", tpl_menu)
end
@@ -212,6 +211,9 @@ redef class WikiArticle
if tpl.has_macro("FOOTER") then
tpl.replace("FOOTER", tpl_footer)
end
+ if tpl.has_macro("TRAIL") then
+ tpl.replace("TRAIL", tpl_trail)
+ end
return tpl
end
@@ -219,21 +221,30 @@ redef class WikiArticle
fun tpl_header: Writable do
var file = header_file
if not wiki.has_template(file) then return ""
- return wiki.load_template(file)
+ return load_template(file)
end
# Generate the HTML page for this article.
fun tpl_article: TplArticle do
var article = new TplArticle
article.body = content
- article.breadcrumbs = new TplBreadcrumbs(self)
- tpl_sidebar.blocks.add tpl_summary
+ if wiki.config.auto_breadcrumbs then
+ article.breadcrumbs = new TplBreadcrumbs(self)
+ end
article.sidebar = tpl_sidebar
+ article.sidebar_pos = wiki.config.sidebar
return article
end
# Sidebar for this page.
- var tpl_sidebar = new TplSidebar
+ var tpl_sidebar: TplSidebar is lazy do
+ var res = new TplSidebar
+ if wiki.config.auto_summary then
+ res.blocks.add tpl_summary
+ end
+ res.blocks.add_all sidebar.blocks
+ return res
+ end
# Generate the HTML summary for this article.
#
@@ -246,8 +257,7 @@ redef class WikiArticle
while iter.is_ok do
var hl = iter.item
# parse title as markdown
- var title = hl.title.md_to_html.to_s
- title = title.substring(3, title.length - 8)
+ var title = wiki.inline_md(hl.title)
tpl.add "
{title}"
iter.next
if iter.is_ok then
@@ -269,7 +279,7 @@ redef class WikiArticle
fun tpl_menu: Writable do
var file = menu_file
if not wiki.has_template(file) then return ""
- var tpl = wiki.load_template(file)
+ var tpl = load_template(file)
if tpl.has_macro("MENUS") then
var items = new Template
for child in wiki.root_section.children.values do
@@ -280,7 +290,7 @@ redef class WikiArticle
items.add " class=\"active\""
end
items.add ">"
- items.add child.tpl_link
+ items.add child.tpl_link(self)
items.add "
"
end
tpl.replace("MENUS", items)
@@ -288,11 +298,46 @@ redef class WikiArticle
return tpl
end
+ # Generate navigation links for the trail of this article, if any.
+ #
+ # A trail is generated if the article include or is included in a trail.
+ # See `wiki.trails` for details.
+ fun tpl_trail: Writable do
+ if not wiki.trails.has(self) then return ""
+
+ # Get the position of `self` in the trail
+ var flat = wiki.trails.to_a
+ var pos = flat.index_of(self)
+ assert pos >= 0
+
+ var res = new Template
+ res.add "
"
+ var parent = wiki.trails.parent(self)
+ # Up and prev are disabled on a root
+ if parent != null then
+ if pos > 0 then
+ var target = flat[pos-1]
+ res.add "
{target.a_from(self, "prev")}
"
+ end
+ res.add "
{parent.a_from(self, "up")}
"
+ end
+ if pos < flat.length - 1 then
+ var target = flat[pos+1]
+ # Only print the next if it is not a root
+ if target.parent != null then
+ res.add "
{target.a_from(self, "next")}
"
+ end
+ end
+ res.add "
"
+
+ return res
+ end
+
# Generate the HTML footer for this article.
fun tpl_footer: Writable do
var file = footer_file
if not wiki.has_template(file) then return ""
- var tpl = wiki.load_template(file)
+ var tpl = load_template(file)
var time = new Tm.gmtime
if tpl.has_macro("YEAR") then
tpl.replace("YEAR", (time.year + 1900).to_s)
@@ -300,6 +345,14 @@ redef class WikiArticle
if tpl.has_macro("GEN_TIME") then
tpl.replace("GEN_TIME", time.to_s)
end
+ if tpl.has_macro("LAST_CHANGES") then
+ var url = "{wiki.config.last_changes}{src_path or else ""}"
+ tpl.replace("LAST_CHANGES", url)
+ end
+ if tpl.has_macro("EDIT") then
+ var url = "{wiki.config.edit}{src_path or else ""}"
+ tpl.replace("EDIT", url)
+ end
return tpl
end
end
@@ -318,15 +371,7 @@ class WikiSitemap
end
# A `WikiArticle` that contains the section index tree.
-class WikiSectionIndex
- super WikiArticle
-
- # The section described by `self`.
- var section: WikiSection
-
- redef fun title do return section.title
-
- redef fun url do return section.url
+redef class WikiSectionIndex
redef var is_dirty = false
@@ -351,6 +396,11 @@ class TplArticle
# Sidebar of this article (if any).
var sidebar: nullable TplSidebar = null
+ # Position of the sidebar.
+ #
+ # See `WikiConfig::sidebar`.
+ var sidebar_pos: String = "left"
+
# Breadcrumbs from wiki root to this article.
var breadcrumbs: nullable TplBreadcrumbs = null
@@ -360,13 +410,11 @@ class TplArticle
end
redef fun rendering do
- if sidebar != null then
- add "
"
- add sidebar.as(not null)
- add "
"
- add "
"
- else
+ if sidebar_pos == "left" then render_sidebar
+ if sidebar == null then
add "
"
+ else
+ add "
"
end
if body != null then
add ""
@@ -382,6 +430,14 @@ class TplArticle
add " "
end
add "
"
+ if sidebar_pos == "right" then render_sidebar
+ end
+
+ private fun render_sidebar do
+ if sidebar == null then return
+ add "
"
+ add sidebar.as(not null)
+ add "
"
end
end
@@ -394,9 +450,9 @@ class TplSidebar
redef fun rendering do
for block in blocks do
- add "
"
+ add "
"
+ add ""
end
end
end
@@ -420,7 +476,7 @@ class TplBreadcrumbs
else
if article.parent == entry and article.is_index then continue
add "