The results of the compilation of iOS apps by XCode are directories. This PR fix tests.sh to detect those directory and report them cleanly.
Also intro a script for running OS X specific tests.
Pull-Request: #1232
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
bncdir="./benches/out"
mkdir -p $outdir
-s=50
+s=200
function bench_nitmd()
{
}
bench_nitmd
+function bench_nitmd-o()
+{
+ name="$FUNCNAME"
+ skip_test "$name" && return
+ prepare_res $outdir/nitmd-o.dat "nitmd-o" "nitmd-o"
+ for file in $bncdir/*.md; do
+ bench=`basename $file .md`
+ bench_command "$bench" "" "$engdir/nitmd/nitmd-o" "$file" "$s"
+ done
+}
+bench_nitmd-o
+
function bench_txtmark()
{
name="$FUNCNAME"
# See the License for the specific language governing permissions and
# limitations under the License.
+all: nitmd nitmd-o
+
nitmd:
nitc nitmd.nit
-test: nitmd
+nitmd-o:
+ nitc --semi-global nitmd.nit -o $@
+
+test: all
./nitmd ../../benches/hello.md 5
+ ./nitmd-o ../../benches/hello.md 5
clean:
- rm -rf nitmd
+ rm -rf nitmd nitmd-o
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# HTML templates for Bootstrap components.
+#
+# See http://getbootstrap.com/components/
+module bootstrap
+
+import template
+
+# Bootstrap component abstraction.
+#
+# Mainly used to factoryze CSS treatments.
+# Can be used in the future to handle generic stuff like attributes or escaping.
+#
+# TODO merge with html::HTMTag without init conflict?
+# HTMLTag requires the main init to pass a tagname,
+# this was so much verbose here.
+abstract class BSComponent
+ super Template
+
+ # CSS classes to add on this element.
+ var css_classes = new Array[String]
+
+ # Render `self` css clases as a `class` attribute.
+ fun render_css_classes: String do
+ if css_classes.is_empty then return ""
+ return " class=\"{css_classes.join(" ")}\""
+ end
+end
+
+# A `<a>` tag.
+#
+# Not really a Bootstrap component but used in other components
+# that it required its own abstraction.
+#
+# Example:
+# ~~~
+# var lnk = new Link("http://nitlanguage.org", "Nit")
+# assert lnk.write_to_string == "<a href=\"http://nitlanguage.org\">Nit</a>"
+# ~~~
+#
+# Creates a link with a title attribute:
+# ~~~
+# lnk = new Link.with_title("http://nitlanguage.org", "Nit", "Nit homepage")
+# assert lnk.write_to_string == "<a href=\"http://nitlanguage.org\" title=\"Nit homepage\">Nit</a>"
+# ~~~
+class Link
+ super BSComponent
+
+ # URL pointed by this link.
+ var href: String is writable
+
+ # Displayed text.
+ var text: Writable is writable
+
+ # Optional title.
+ var title: nullable String is noinit, writable
+
+ # Creates a link with a `title` attribute.
+ init with_title(href: String, text: Writable, title: nullable String) do
+ self.href = href
+ self.text = text
+ self.title = title
+ end
+
+ redef fun rendering do
+ add "<a{render_css_classes} href=\"{href}\""
+ if title != null then add " title=\"{title.write_to_string}\""
+ add ">{text}</a>"
+ end
+end
+
+# A `<h1>` to `<h6>` tag.
+#
+# Not really a Bootstrap component but used in other components
+# that it required its own abstraction.
+#
+# Example:
+# ~~~
+# var h1 = new Header(1, "Title")
+# assert h1.write_to_string == "<h1>Title</h1>"
+# ~~~
+#
+# With subtext:
+# ~~~
+# var h6 = new Header.with_subtext(6, "Title", "with subtext")
+# assert h6.write_to_string == "<h6>Title<small>with subtext</small></h6>"
+# ~~~
+class Header
+ super BSComponent
+
+ # Header level between 1 and 6.
+ var level: Int
+
+ # Displayed text.
+ var text: Writable
+
+ # Optional subtext.
+ var subtext: nullable Writable is noinit, writable
+
+ # Creates a link with a `title` attribute.
+ init with_subtext(level: Int, text: Writable, subtext: String) do
+ self.level = level
+ self.text = text
+ self.subtext = subtext
+ end
+
+ redef fun rendering do
+ add "<h{level}{render_css_classes}>{text.write_to_string}"
+ if subtext != null then add "<small>{subtext.write_to_string}</small>"
+ add "</h{level}>"
+ end
+end
+
+# An abstract HTML list.
+#
+# Many Bootstrap components are built around a HTML list.
+#
+# Used to factorize behavior between OrderedList and UnorderedList.
+abstract class HTMLList
+ super BSComponent
+
+ # A list contains `<li>` tags as children.
+ #
+ # See ListItem.
+ var items = new Array[ListItem]
+
+ # Adds a new ListItem to `self`.
+ fun add_li(item: ListItem) do items.add item
+
+ # Does `self` contains no items?
+ fun is_empty: Bool do return items.is_empty
+end
+
+# A `<ol>` list tag.
+#
+# Example:
+#
+# ~~~
+# var lst = new OrderedList
+# lst.add_li(new ListItem("foo"))
+# lst.add_li(new ListItem("bar"))
+# lst.add_li(new ListItem("baz"))
+#
+# assert lst.write_to_string == """
+# <ol>
+# <li>foo</li>
+# <li>bar</li>
+# <li>baz</li>
+# </ol>
+# """
+# ~~~
+class OrderedList
+ super HTMLList
+
+ redef fun rendering do
+ addn "<ol{render_css_classes}>"
+ for item in items do add item
+ addn "</ol>"
+ end
+end
+
+# A `<ul>` list tag.
+#
+# Example:
+#
+# ~~~
+# var lst = new UnorderedList
+# lst.add_li(new ListItem("foo"))
+# lst.add_li(new ListItem("bar"))
+# lst.add_li(new ListItem("baz"))
+#
+# assert lst.write_to_string == """
+# <ul>
+# <li>foo</li>
+# <li>bar</li>
+# <li>baz</li>
+# </ul>
+# """
+# ~~~
+class UnorderedList
+ super HTMLList
+
+ redef fun rendering do
+ addn "<ul{render_css_classes}>"
+ for item in items do add item
+ addn "</ul>"
+ end
+end
+
+# A `<li>` tag.
+class ListItem
+ super BSComponent
+
+ # Content to display in this list item.
+ var text: Writable is writable
+
+ redef fun rendering do addn "<li{render_css_classes}>{text.write_to_string}</li>"
+end
+
+# A Boostrap icon.
+#
+# See http://getbootstrap.com/components/#glyphicons
+#
+# Example:
+#
+# ~~~
+# var icon = new BSIcon("star")
+# assert icon.write_to_string == "<span class=\"glyphicon glyphicon-star\" aria-hidden=\"true\"></span>"
+# ~~~
+class BSIcon
+ super BSComponent
+
+ # Glyphicon name to display.
+ #
+ # See full list at http://getbootstrap.com/components/#glyphicons.
+ var icon: String
+
+ init do css_classes.add "glyphicon glyphicon-{icon}"
+
+ redef fun rendering do
+ add "<span{render_css_classes} aria-hidden=\"true\"></span>"
+ end
+end
+
+# A Bootstrap breadcrumbs component.
+#
+# See http://getbootstrap.com/components/#breadcrumbs
+#
+# Example:
+#
+# ~~~
+# var bc = new BSBreadCrumbs
+# bc.add_li(new ListItem("foo"))
+# bc.add_li(new ListItem("bar"))
+# bc.add_li(new ListItem("baz"))
+#
+# assert bc.write_to_string == """
+# <ol class=\"breadcrumbs\">
+# <li>foo</li>
+# <li>bar</li>
+# <li class=\"active\">baz</li>
+# </ol>
+# """
+# ~~~
+class BSBreadCrumbs
+ super OrderedList
+
+ init do css_classes.add "breadcrumbs"
+
+ redef fun rendering do
+ items.last.css_classes.add "active"
+ super
+ end
+end
+
+# A Bootstrap label component.
+#
+# See http://getbootstrap.com/components/#labels
+#
+# Example:
+#
+# ~~~
+# var lbl = new BSLabel("danger", "Danger!")
+# assert lbl.write_to_string == "<span class=\"label label-danger\">Danger!</span>"
+# ~~~
+class BSLabel
+ super BSComponent
+
+ # Class used to change the color of the label.
+ #
+ # Can be one of `default`, `primary`, `success`, `info`, `warning` or `danger`.
+ var color: String
+
+ # Text to display in the label.
+ var text: Writable
+
+ init do css_classes.add "label label-{color}"
+
+ redef fun rendering do
+ add "<span{render_css_classes}>{text.write_to_string}</span>"
+ end
+end
+
+# A Bootstrap badge component.
+#
+# See http://getbootstrap.com/components/#badges
+#
+# Example:
+#
+# ~~~
+# var b = new BSBadge("42 messages")
+# assert b.write_to_string == "<span class=\"badge\">42 messages</span>"
+# ~~~
+class BSBadge
+ super BSComponent
+
+ # Text to display in the label.
+ var text: Writable
+
+ init do css_classes.add "badge"
+
+ redef fun rendering do
+ add "<span{render_css_classes}>{text.write_to_string}</span>"
+ end
+end
+
+# A Bootstrap page header component.
+#
+# See http://getbootstrap.com/components/#page-header
+#
+# Example:
+#
+# ~~~
+# var h = new BSPageHeader("Welcome")
+# assert h.write_to_string == """
+# <div class=\"page-header\">
+# Welcome
+# </div>
+# """
+# ~~~
+class BSPageHeader
+ super BSComponent
+
+ # Text to display as title.
+ var text: Writable
+
+ init do css_classes.add "page-header"
+
+ redef fun rendering do
+ addn "<div{render_css_classes}>"
+ addn text.write_to_string
+ addn "</div>"
+ end
+end
+
+# A Bootstrap alert component.
+#
+# See http://getbootstrap.com/components/#alerts
+#
+# Example:
+#
+# ~~~
+# var alert = new BSAlert("danger", "Danger!")
+# assert alert.write_to_string == """
+# <div class="alert alert-danger">
+# Danger!
+# </div>
+# """
+# ~~~
+class BSAlert
+ super BSComponent
+
+ # Class used to change the color of the alert.
+ #
+ # Can be one of `primary`, `success`, `info`, `warning` or `danger`.
+ var color: String
+
+ # Text to display in the alert.
+ var text: Writable
+
+ # Can the alert be dismissed by clicking the close button?
+ #
+ # See http://getbootstrap.com/components/#alerts-dismissible
+ #
+ # Default is `false`.
+ var is_dismissible = false
+
+ init do css_classes.add "alert alert-{color}"
+
+ redef fun rendering do
+ addn "<div{render_css_classes}>"
+ if is_dismissible then
+ add "<button type=\"button\" class=\"close\" data-dismiss=\"alert\""
+ add "aria-label=\"Close\"><span aria-hidden=\"true\">×</span>"
+ addn "</button>"
+ end
+ addn text.write_to_string
+ addn "</div>"
+ end
+end
+
+# A Bootstrap panel component.
+#
+# See http://getbootstrap.com/components/#panels
+#
+# Example:
+#
+# ~~~
+# var p = new BSPanel("default", "Panel content")
+#
+# assert p.write_to_string == """
+# <div class="panel panel-default">
+# <div class="panel-body">
+# Panel content
+# </div>
+# </div>
+# """
+# ~~~
+#
+# Panel with heading:
+#
+# ~~~
+# p = new BSPanel("danger", "Panel content")
+# p.heading = "Panel heading"
+#
+# assert p.write_to_string == """
+# <div class="panel panel-danger">
+# <div class="panel-heading">
+# Panel heading
+# </div>
+# <div class="panel-body">
+# Panel content
+# </div>
+# </div>
+# """
+# ~~~
+class BSPanel
+ super BSComponent
+
+ # Panel color.
+ #
+ # Can be one of `default`, `primary`, `success`, `info`, `warning` or `danger`.
+ var color: String
+
+ # Panel header if any.
+ var heading: nullable Writable is noinit, writable
+
+ # Body to display in the panel.
+ var body: Writable
+
+ # Panel footer is any.
+ var footer: nullable Writable is noinit, writable
+
+ init do css_classes.add "panel panel-{color}"
+
+ redef fun rendering do
+ addn "<div{render_css_classes}>"
+ if heading != null then
+ addn "<div class=\"panel-heading\">"
+ addn heading.write_to_string
+ addn "</div>"
+ end
+ addn "<div class=\"panel-body\">"
+ addn body.write_to_string
+ addn "</div>"
+ if footer != null then
+ addn "<div class=\"panel-footer\">"
+ addn footer.write_to_string
+ addn "</div>"
+ end
+ addn "</div>"
+ end
+end
# Real items, used as cache for to_cstring is called
private var real_items: nullable NativeString = null
+ # Returns a char* starting at position `index_from`
+ #
+ # WARNING: If you choose to use this service, be careful of the following.
+ #
+ # Strings and NativeString are *ideally* always allocated through a Garbage Collector.
+ # Since the GC tracks the use of the pointer for the beginning of the char*, it may be
+ # deallocated at any moment, rendering the pointer returned by this function invalid.
+ # Any access to freed memory may very likely cause undefined behaviour or a crash.
+ # (Failure to do so will most certainly result in long and painful debugging hours)
+ #
+ # The only safe use of this pointer is if it is ephemeral (e.g. read in a C function
+ # then immediately return).
+ #
+ # As always, do not modify the content of the String in C code, if this is what you want
+ # copy locally the char* as Nit Strings are immutable.
+ private fun fast_cstring: NativeString is abstract
+
redef var length: Int = 0
redef fun output
return native.to_s_with_length(self.length)
end
+ redef fun fast_cstring do return items.fast_cstring(index_from)
+
redef fun substring(from, count)
do
assert count >= 0
private var capacity: Int = 0
+ redef fun fast_cstring do return items.fast_cstring(0)
+
redef fun substrings do return new FlatSubstringsIter(self)
# Re-copies the `NativeString` into a new one and sets it as the new `Buffer`
# Creates a new NativeString with a capacity of `length`
new(length: Int) is intern
+ # Returns a char* starting at `index`.
+ #
+ # WARNING: Unsafe for extern code, use only for temporary
+ # pointer manipulation purposes (e.g. write to file or such)
+ fun fast_cstring(index: Int): NativeString is intern
+
# Get char at `index`.
fun [](index: Int): Char is intern
else if pname == "atoi" then
v.ret(v.new_expr("atoi({arguments[0]});", ret.as(not null)))
return true
+ else if pname == "fast_cstring" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
else if pname == "new" then
v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
return true
abstract class DocComposite
# Parent element.
- var parent: nullable DocComposite = null
+ var parent: nullable DocComposite = null is writable
# Does `self` have a `parent`?
fun is_root: Bool do return parent == null
#
# Shortcut for `children.add`.
fun add_child(child: DocComposite) do
+ child.parent = self
children.add child
end
end
if article == null then continue
# FIXME avoid diff
# page.root.add article
- page.root.children[1].children.insert(article, 0)
+ article.parent = page.root.children.first.children[1]
+ page.root.children.first.children[1].children.insert(article, 0)
end
end
end
var clients = self.clients.to_a
v.name_sorter.sort(clients)
section.add_child new HierarchyListArticle(mentity, "Clients", clients)
- root.children.insert(section, 1)
+ section.parent = root.children.first
+ root.children.first.children.insert(section, 1)
end
end
var descendants = self.descendants.to_a
v.name_sorter.sort(descendants)
section.add_child new HierarchyListArticle(mentity, "Descendants", descendants)
- root.children.insert(section, 1)
+ section.parent = root.children.first
+ root.children.first.children.insert(section, 1)
end
end
# Build top menu template if any.
fun init_topmenu(v: RenderHTMLPhase, doc: DocModel) do
- topmenu = new TplTopMenu(html_url)
+ topmenu = new DocTopMenu
var brand = v.ctx.opt_custom_brand.value
if brand != null then
var tpl = new Template
tpl.add "</span>"
topmenu.brand = tpl
end
- topmenu.add_link new TplLink("index.html", "Overview")
- topmenu.add_link new TplLink("search.html", "Index")
+ var title = "Overview"
+ if v.ctx.opt_custom_title.value != null then
+ title = v.ctx.opt_custom_title.value.to_s
+ end
+ topmenu.add_li new ListItem(new Link("index.html", title))
+ topmenu.add_li new ListItem(new Link("search.html", "Index"))
+ topmenu.active_item = topmenu.items.first
end
# Build page sidebar if any.
redef class SearchPage
redef var html_url = "search.html"
redef fun init_title(v, doc) do title = "Index"
+
+ redef fun init_topmenu(v, doc) do
+ super
+ topmenu.active_item = topmenu.items.last
+ end
+
redef fun init_sidebar(v, doc) do end
# TODO this should be done in StructurePhase.
redef class MEntityPage
redef var html_url is lazy do return mentity.nitdoc_url
- redef fun init_title(v, doc) do title = mentity.nitdoc_name
+ redef fun init_title(v, doc) do title = mentity.html_name
redef fun init_content(v, doc) do add_section root.start_rendering(v, doc, self)
end
super
var mproject = mentity.mproject
if not mentity.is_root then
- topmenu.add_link new TplLink(mproject.nitdoc_url, mproject.nitdoc_name)
+ topmenu.add_li new ListItem(new Link(mproject.nitdoc_url, mproject.html_name))
end
- topmenu.add_link new TplLink(html_url, mproject.nitdoc_name)
+ topmenu.add_li new ListItem(new Link(html_url, mproject.html_name))
+ topmenu.active_item = topmenu.items.last
end
redef fun init_sidebar(v, doc) do
redef fun init_topmenu(v, doc) do
super
var mproject = mentity.mproject
- topmenu.add_link new TplLink(mproject.nitdoc_url, mproject.nitdoc_name)
- topmenu.add_link new TplLink(mentity.nitdoc_url, mentity.nitdoc_name)
+ topmenu.add_li new ListItem(new Link(mproject.nitdoc_url, mproject.html_name))
+ topmenu.add_li new ListItem(new Link(mentity.nitdoc_url, mentity.html_name))
+ topmenu.active_item = topmenu.items.last
end
# Class list to display in sidebar
redef class MClassPage
- redef fun init_title(v, doc) do
- title = "{mentity.nitdoc_name}{mentity.tpl_signature.write_to_string}"
- end
-
redef fun init_topmenu(v, doc) do
super
var mproject = mentity.intro_mmodule.mgroup.mproject
- topmenu.add_link new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}")
- topmenu.add_link new TplLink(html_url, mentity.nitdoc_name)
+ topmenu.add_li new ListItem(new Link(mproject.nitdoc_url, mproject.html_name))
+ topmenu.add_li new ListItem(new Link(html_url, mentity.html_name))
+ topmenu.active_item = topmenu.items.last
end
redef fun init_sidebar(v, doc) do
classes.add "inherit"
var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url
var def_url = "{cls_url}#{mprop.nitdoc_id}"
- var lnk = new TplLink(def_url, mprop.nitdoc_name)
+ var lnk = new TplLink(def_url, mprop.html_name)
var mdoc = mprop.intro.mdoc_or_fallback
if mdoc != null then lnk.title = mdoc.short_comment
var item = new Template
redef class MPropertyPage
redef fun init_title(v, doc) do
- title = "{mentity.nitdoc_name}{mentity.tpl_signature.write_to_string}"
+ title = "{mentity.html_name}{mentity.tpl_signature.write_to_string}"
end
redef fun init_topmenu(v, doc) do
var mmodule = mentity.intro_mclassdef.mmodule
var mproject = mmodule.mgroup.mproject
var mclass = mentity.intro_mclassdef.mclass
- topmenu.add_link new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}")
- topmenu.add_link new TplLink("{mclass.nitdoc_url}", "{mclass.nitdoc_name}")
- topmenu.add_link new TplLink(html_url, mentity.nitdoc_name)
+ topmenu.add_li new ListItem(new Link(mproject.nitdoc_url, mproject.html_name))
+ topmenu.add_li new ListItem(new Link(mclass.nitdoc_url, mclass.html_name))
+ topmenu.add_li new ListItem(new Link(html_url, mentity.html_name))
+ topmenu.active_item = topmenu.items.last
end
end
fun start_rendering(v: RenderHTMLPhase, doc: DocModel, page: MEntityPage): TplSection do
var section = new TplSection("top")
var mentity = page.mentity
- section.title = mentity.nitdoc_name
+ section.title = mentity.html_name
section.subtitle = mentity.tpl_declaration
# FIXME ugly hack to avoid diff
if mentity isa MGroup and mentity.is_root then
- section.title = mentity.mproject.nitdoc_name
+ section.title = mentity.mproject.html_name
section.subtitle = mentity.mproject.tpl_declaration
- else if mentity isa MClass then
- section.title = "{mentity.nitdoc_name}{mentity.tpl_signature.write_to_string}"
else if mentity isa MProperty then
- section.title = "{mentity.nitdoc_name}{mentity.intro.tpl_signature.write_to_string}"
+ section.title = "{mentity.html_name}{mentity.intro.tpl_signature.write_to_string}"
section.subtitle = mentity.tpl_namespace
- section.summary_title = mentity.nitdoc_name
+ section.summary_title = mentity.html_name
end
render(v, doc, page, section)
return section
var title = new Template
if mmodule == page.mentity then
title.add "in "
- section.summary_title = "in {mmodule.nitdoc_name}"
+ section.summary_title = "in {mmodule.html_name}"
else
title.add "from "
- section.summary_title = "from {mmodule.nitdoc_name}"
+ section.summary_title = "from {mmodule.html_name}"
end
title.add mmodule.tpl_namespace
section.title = title
title.add "in "
title.add mmodule.tpl_namespace
section.title = title
- section.summary_title = "in {mmodule.nitdoc_name}"
+ section.summary_title = "in {mmodule.html_name}"
+ end
+end
+
+redef class MEntitySection
+ redef fun render(v, doc, page, parent) do
+ for child in children do child.render(v, doc, page, parent)
end
end
else
var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url
var def_url = "{cls_url}#{mprop.nitdoc_id}"
- var lnk = new TplLink.with_title(def_url, mprop.nitdoc_name,
+ var lnk = new TplLink.with_title(def_url, mprop.html_name,
"Go to introduction")
title.add "redef "
title.add lnk
end
article.title = title
article.title_classes.add "signature"
- article.summary_title = "{mprop.nitdoc_name}"
+ article.summary_title = "{mprop.html_name}"
article.subtitle = mpropdef.tpl_namespace
if mpropdef.mdoc_or_fallback != null then
article.content = mpropdef.mdoc_or_fallback.tpl_comment
redef class MGroupPage
redef fun apply_structure(v, doc) do
+ var section = new MEntitySection(mentity)
+ root.add_child section
if mentity.is_root then
- root.add_child new IntroArticle(mentity.mproject)
+ section.add_child new IntroArticle(mentity.mproject)
else
- root.add_child new IntroArticle(mentity)
+ section.add_child new IntroArticle(mentity)
end
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
concerns.sort_with(v.concerns_sorter)
mentity.mproject.booster_rank = 0
mentity.booster_rank = 0
- root.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle(mentity, concerns)
for mentity in concerns do
if mentity isa MModule then
- root.add_child new DefinitionArticle(mentity)
+ section.add_child new DefinitionArticle(mentity)
else
- root.add_child new ConcernSection(mentity)
+ section.add_child new ConcernSection(mentity)
end
end
end
redef class MModulePage
redef fun apply_structure(v, doc) do
- root.add_child new IntroArticle(mentity)
+ var section = new MEntitySection(mentity)
+ root.add_child section
+ section.add_child new IntroArticle(mentity)
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
# FIXME avoid diff
mentity.mgroup.mproject.booster_rank = 0
mentity.mgroup.booster_rank = 0
mentity.booster_rank = 0
- root.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle(mentity, concerns)
# reference list
for mentity in concerns do
- var section = new ConcernSection(mentity)
+ var ssection = new ConcernSection(mentity)
if mentity isa MModule then
var mclasses = mclasses_for_mmodule(mentity).to_a
v.name_sorter.sort(mclasses)
for mclassdef in mclassdefs do
article.add_child(new DefinitionArticle(mclassdef))
end
- section.add_child article
+ ssection.add_child article
end
end
- root.add_child section
+ section.add_child ssection
end
end
redef class MClassPage
redef fun apply_structure(v, doc) do
- root.add_child new IntroArticle(mentity)
+ var section = new MEntitySection(mentity)
+ root.add_child section
+ section.add_child new IntroArticle(mentity)
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
# FIXME diff hack
mentity.intro_mmodule.mgroup.mproject.booster_rank = 0
mentity.intro_mmodule.mgroup.booster_rank = 0
mentity.intro_mmodule.booster_rank = 0
- root.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle(mentity, concerns)
for mentity in concerns do
- var section = new ConcernSection(mentity)
+ var ssection = new ConcernSection(mentity)
if mentity isa MModule then
var mprops = mproperties_for(mentity)
var by_kind = new PropertiesByKind.with_elements(mprops)
v.name_sorter.sort(group)
for mprop in group do
for mpropdef in mpropdefs_for(mprop, mentity) do
- section.add_child new DefinitionArticle(mpropdef)
+ ssection.add_child new DefinitionArticle(mpropdef)
end
end
end
end
- root.add_child section
+ section.add_child ssection
end
end
redef class MPropertyPage
redef fun apply_structure(v, doc) do
- root.add_child new IntroArticle(mentity)
+ var section = new MEntitySection(mentity)
+ root.add_child section
+ section.add_child new IntroArticle(mentity)
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
# FIXME diff hack
mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = 0
mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
mentity.intro.mclassdef.mmodule.booster_rank = 0
- root.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle(mentity, concerns)
for mentity in concerns do
- var section = new ConcernSection(mentity)
+ var ssection = new ConcernSection(mentity)
if mentity isa MModule then
# Add mproperties
var mpropdefs = mpropdefs_for(mentity).to_a
v.name_sorter.sort(mpropdefs)
for mpropdef in mpropdefs do
- section.add_child new DefinitionArticle(mpropdef)
+ ssection.add_child new DefinitionArticle(mpropdef)
end
end
- root.add_child section
+ section.add_child ssection
end
end
super DocArticle
end
+# A section about a Mentity.
+#
+# Used to regroup content about a MEntity.
+class MEntitySection
+ super MEntityComposite
+ super DocSection
+end
+
# An introduction article about a MEntity.
#
# Used at the top of a documentation page to introduce the documented MEntity.
# general layout elements
#########################
-# Top menu bar template
-class TplTopMenu
- super Template
-
- # Brand link to display in first position of the top menu
- private var brand: nullable Writable = null is writable
- # Elements of the topmenu
- private var elts = new Array[Writable]
-
- # The page url where the top menu is displayed.
- #
- # Used to select the active link.
- private var current_url: String
-
- # Add a new link to the menu.
- fun add_link(content: TplLink) do
- var is_active = content.href == current_url
- add_item(content, is_active)
- end
-
- # Add a content between `<li>` tags
- fun add_item(content: Writable, is_active: Bool) do
- var tpl = new Template
- tpl.add "<li"
- if is_active then
- tpl.add " class=\"active\""
- end
- tpl.add ">"
- tpl.add content
- tpl.addn "</li>"
- add_raw(tpl)
- end
-
- # Add a raw content to the menu
- fun add_raw(content: Writable) do
- elts.add content
- end
-
- redef fun rendering do
- if brand == null and elts.is_empty then return
- addn "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
- addn " <div class='container-fluid'>"
- addn " <div class='navbar-header'>"
- add " <button type='button' class='navbar-toggle' "
- addn " data-toggle='collapse' data-target='#topmenu-collapse'>"
- addn " <span class='sr-only'>Toggle menu</span>"
- addn " <span class='icon-bar'></span>"
- addn " <span class='icon-bar'></span>"
- addn " <span class='icon-bar'></span>"
- addn " </button>"
- if brand != null then add brand.as(not null)
- addn " </div>"
- addn " <div class='collapse navbar-collapse' id='topmenu-collapse'>"
- if not elts.is_empty then
- addn "<ul class='nav navbar-nav'>"
- for elt in elts do add elt
- addn "</ul>"
- end
- addn " </div>"
- addn " </div>"
- addn "</nav>"
- end
-end
-
# A sidebar template
class TplSidebar
super Template
# URL of this entity’s Nitdoc page.
fun nitdoc_url: String is abstract
+ # Returns the mentity name without short signature.
+ #
+ # * MProject: `foo`
+ # * MGroup: `foo`
+ # * MModule: `foo`
+ # * MClass: `Foo[E]`
+ # * MClassDef: `Foo[E]`
+ # * MProperty: `foo(e)`
+ # * MPropdef: `foo(e)`
+ var html_name: String is lazy do return name.html_escape
+
# A template link to the mentity `nitdoc_id`
fun tpl_anchor: TplLink do
- var tpl = new TplLink("#{nitdoc_id}", nitdoc_name)
+ var tpl = new TplLink("#{nitdoc_id}", html_name)
var mdoc = mdoc_or_fallback
if mdoc != null then
tpl.title = mdoc.short_comment
# A template link to the mentity `nitdoc_url`
fun tpl_link: TplLink do
- var tpl = new TplLink(nitdoc_url, nitdoc_name)
+ var tpl = new TplLink(nitdoc_url, html_name)
var mdoc = mdoc_or_fallback
if mdoc != null then
tpl.title = mdoc.short_comment
var tpl = new TplArticle.with_title(nitdoc_id, tpl_title)
tpl.title_classes.add "signature"
tpl.subtitle = tpl_namespace
- tpl.summary_title = nitdoc_name
+ tpl.summary_title = html_name
return tpl
end
redef fun nitdoc_url do return "class_{nitdoc_id}.html"
redef fun mdoc_or_fallback do return intro.mdoc
+ # Format: `Foo[E]`
+ redef var html_name is lazy do
+ var tpl = new Template
+ tpl.add name.html_escape
+ if arity > 0 then
+ tpl.add "["
+ var parameter_names = new Array[String]
+ for p in mparameters do
+ parameter_names.add(p.html_name)
+ end
+ tpl.add parameter_names.join(", ")
+ tpl.add "]"
+ end
+ return tpl.write_to_string
+ end
+
redef fun tpl_declaration do return intro.tpl_declaration
redef fun tpl_definition do return intro.tpl_definition
var title = new Template
title.add tpl_icon
title.add tpl_link
- title.add tpl_signature
return title
end
tpl.add "["
var parameter_names = new Array[String]
for p in mparameters do
- parameter_names.add(p.nitdoc_name)
+ parameter_names.add(p.html_name)
end
tpl.add parameter_names.join(", ")
tpl.add "]"
return tpl
end
- redef fun tpl_article do
- var tpl = super
- tpl.summary_title = "{nitdoc_name}{tpl_signature.write_to_string}"
- return tpl
- end
-
redef fun tpl_css_classes do return intro.tpl_css_classes
end
redef fun tpl_article do
var tpl = new TplArticle(nitdoc_id)
- tpl.summary_title = "in {mmodule.nitdoc_name}"
+ tpl.summary_title = "in {mmodule.html_name}"
tpl.title = tpl_declaration
tpl.title_classes.add "signature"
var title = new Template
var title = new Template
title.add tpl_icon
title.add tpl_link
- title.add tpl_signature
return title
end
if not mparameters.is_empty then
tpl.add "["
for i in [0..mparameters.length[ do
- tpl.add "{mparameters[i].nitdoc_name}: "
+ tpl.add "{mparameters[i].html_name}: "
tpl.add bound_mtype.arguments[i].tpl_signature
if i < mparameters.length - 1 then tpl.add ", "
end
redef fun tpl_article do
var tpl = new TplArticle(nitdoc_id)
- tpl.summary_title = "in {mclassdef.nitdoc_name}"
+ tpl.summary_title = "in {mclassdef.html_name}"
var title = new Template
title.add "in "
title.add mclassdef.tpl_link
redef class MGenericType
redef fun tpl_signature do
var tpl = new Template
- tpl.add tpl_link
+ var lnk = tpl_link
+ lnk.text = mclass.name.html_escape
+ tpl.add lnk
tpl.add "["
for i in [0..arguments.length[ do
tpl.add arguments[i].tpl_signature
module html_templates
import html_model
+import html::bootstrap
# Renders the page as HTML.
redef class DocPage
var body_attrs = new Array[TagAttribute]
# Top menu template if any.
- var topmenu: TplTopMenu is writable, noinit
+ var topmenu: DocTopMenu is writable, noinit
# Sidebar template if any.
var sidebar: nullable TplSidebar = null is writable
addn ">"
end
- # Renders the topmenu template.
- private fun render_topmenu do
- addn " <div class='row'>"
- add topmenu
- addn " </div>"
- end
-
# Renders the sidebar template.
#
# Sidebar is automatically populated with a summary of all sections
redef fun rendering do
render_head
addn "<div class='container-fluid'>"
- render_topmenu
+ addn " <div class='row'>"
+ add topmenu
+ addn " </div>"
addn " <div class='row' id='content'>"
if sidebar != null then
addn "<div class='col col-xs-3 col-lg-2'>"
render_footer
end
end
+
+# Top menu bar template.
+#
+# FIXME should be a Bootstrap component template
+# At this moment, the topmenu structure stills to specific to Nitdoc to use the
+# generic component.
+class DocTopMenu
+ super UnorderedList
+
+ # Brand link to display in first position of the top menu.
+ #
+ # This is where you want to put your logo.
+ var brand: nullable Writable is noinit, writable
+
+ # Active menu item.
+ #
+ # Depends on the current page, this allows to hilighted the current item.
+ #
+ # FIXME should be using Boostrap breadcrumbs component.
+ # This will still like this to avoid diff and be changed in further fixes
+ # when we will modify the output.
+ var active_item: nullable ListItem is noinit, writable
+
+ redef fun rendering do
+ addn "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
+ addn " <div class='container-fluid'>"
+ addn " <div class='navbar-header'>"
+ add " <button type='button' class='navbar-toggle' "
+ addn " data-toggle='collapse' data-target='#topmenu-collapse'>"
+ addn " <span class='sr-only'>Toggle menu</span>"
+ addn " <span class='icon-bar'></span>"
+ addn " <span class='icon-bar'></span>"
+ addn " <span class='icon-bar'></span>"
+ addn " </button>"
+ if brand != null then
+ add "<span class='navbar-brand'>"
+ add brand.write_to_string
+ add "</span>"
+ end
+ addn " </div>"
+ addn " <div class='collapse navbar-collapse' id='topmenu-collapse'>"
+ addn " <ul class='nav navbar-nav'>"
+ for item in items do
+ if item == active_item then item.css_classes.add "active"
+ add item.write_to_string
+ end
+ addn " </ul>"
+ addn " </div>"
+ addn " </div>"
+ addn "</nav>"
+ end
+end
return v.int_instance(res)
else if pname == "atof" then
return v.float_instance(recvval.to_f)
+ else if pname == "fast_cstring" then
+ var ns = recvval.to_cstring.to_s.substring_from(args[1].to_i)
+ return v.native_string_instance(ns)
end
else if cname == "String" then
var cs = v.send(v.force_get_primitive_method("to_cstring", args.first.mtype), [args.first])
end
# Load a bunch of modules and groups.
- # Each name can be a module or a group.
- # If it is a group then recursively all its modules are parsed.
+ #
+ # Each name can be:
+ #
+ # * a path to a module, a group or a directory of projects.
+ # * a short name of a module or a group that are looked in the `paths` (-I)
+ #
+ # Then, for each entry, if it is:
+ #
+ # * a module, then is it parser and returned.
+ # * a group then recursively all its modules are parsed.
+ # * a directory of projects then all the modules of all projects are parsed.
+ # * else an error is displayed.
+ #
# See `parse` for details.
fun parse_full(names: Sequence[String]): Array[MModule]
do
self.toolcontext.info("*** PARSE ***", 1)
var mmodules = new ArraySet[MModule]
for a in names do
+ # Case of a group
var mgroup = self.get_mgroup(a)
if mgroup != null then
mmodules.add_all parse_group(mgroup)
continue
end
+
+ # Case of a directory that is not a group
+ var stat = a.to_path.stat
+ if stat != null and stat.is_dir then
+ self.toolcontext.info("look in directory {a}", 2)
+ var fs = a.files
+ # Try each entry as a group or a module
+ for f in fs do
+ var af = a/f
+ mgroup = get_mgroup(af)
+ if mgroup != null then
+ mmodules.add_all parse_group(mgroup)
+ continue
+ end
+ var mp = identify_file(af)
+ if mp != null then
+ var nmodule = self.load_module(af)
+ if nmodule == null then continue # Skip error
+ build_module_importation(nmodule)
+ mmodules.add(nmodule.mmodule.as(not null))
+ else
+ self.toolcontext.info("ignore file {af}", 2)
+ end
+ end
+ continue
+ end
+
var nmodule = self.load_module(a)
if nmodule == null then continue # Skip error
# Load imported module
return mgroups[rdp]
end
- # Hack, a group is determined by:
+ # Hack, a group is determined by one of the following:
# * the presence of a honomymous nit file
# * the fact that the directory is named `src`
+ # * the fact that there is a sub-directory named `src`
var pn = rdp.basename(".nit")
var mp = dirpath.join_path(pn + ".nit").simplify_path
+ # dirpath2 is the root directory
+ # dirpath is the src subdirectory directory, if any, else it is the same that dirpath2
var dirpath2 = dirpath
if not mp.file_exists then
if pn == "src" then
dirpath2 = rdp.dirname
pn = dirpath2.basename("")
else
- return null
+ # Check a `src` subdirectory
+ dirpath = dirpath2 / "src"
+ if not dirpath.file_exists then
+ # All rules failed, so return null
+ return null
+ end
end
end
# check parent directory
- var parentpath = dirpath.join_path("..").simplify_path
+ var parentpath = dirpath2.join_path("..").simplify_path
var parent = get_mgroup(parentpath)
var mgroup
mgroup = new MGroup(pn, parent.mproject, parent)
toolcontext.info("found sub group `{mgroup.full_name}` at {dirpath}", 2)
end
- var readme = dirpath2.join_path("README.md")
+
+ # search documentation
+ # in src first so the documentation of the project code can be distinct for the documentation of the project usage
+ var readme = dirpath.join_path("README.md")
+ if not readme.file_exists then readme = dirpath.join_path("README")
+ if not readme.file_exists then readme = dirpath2.join_path("README.md")
if not readme.file_exists then readme = dirpath2.join_path("README")
if readme.file_exists then
var mdoc = load_markdown(readme)
mgroup.mdoc = mdoc
mdoc.original_mentity = mgroup
end
+
mgroup.filepath = dirpath
- mgroups[rdp] = mgroup
+ mgroups[module_absolute_path(dirpath)] = mgroup
+ mgroups[module_absolute_path(dirpath2)] = mgroup
return mgroup
end
var modelbuilder = new ModelBuilder(model, toolcontext)
# Here we load an process all modules passed on the command line
-var mmodules = modelbuilder.parse(arguments)
+var mmodules = modelbuilder.parse_full(arguments)
modelbuilder.run_phases
toolcontext.run_global_phases(mmodules)