* Rename the annotation `java_package` to `app_namespace`.
* Move up `app_name`, `app_version` and `app_namespace` and their default values from the Android platform.
* Apply these annotations in iOS too.
* Use the annotations in Hello iOS.
Pull-Request: #1233
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
* nitmd
* txtmark 0.11 (https://github.com/rjeschke/txtmark)
* markdown4j 2.2 (https://code.google.com/p/markdown4j/)
+* pandoc (last version installed from `cabal`)
## Benches
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"
}
bench_markdown4j
+function bench_pandoc()
+{
+ name="$FUNCNAME"
+ skip_test "$name" && return
+ prepare_res $outdir/pandoc.dat "pandoc" "pandoc"
+ for file in $bncdir/*.md; do
+ name=`basename $file .md`
+ bench_command "$bench" "" "$engdir/pandoc/pandoc" "$file" "$s"
+ done
+}
+bench_pandoc
+
if test "$#" -gt 0; then
plot $outdir/bench_markdown.gnu
fi
# See the License for the specific language governing permissions and
# limitations under the License.
-all: nitmd/nitmd txtmark/Txtmark.class markdown4j/Markdown4j.class
+all: nitmd/nitmd txtmark/Txtmark.class markdown4j/Markdown4j.class pandoc/pandoc
nitmd/nitmd:
make -C nitmd
markdown4j/Markdown4j.class:
make -C markdown4j
+pandoc/pandoc:
+ make -C pandoc
+
clean:
make -C nitmd clean
make -C txtmark clean
make -C markdown4j clean
+ make -C pandoc clean
# 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 ).
+#
+# Copyright 2015 Alexandre Terrasa <alexandre@moz-code.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.
+
+pandoc:
+ cabal install pandoc
+ ghc pandoc.hs -O
+
+test: pandoc
+ ./pandoc ../../benches/hello.md 5
+
+clean:
+ rm pandoc.hi
+ rm pandoc.o
+ rm pandoc
--- /dev/null
+module Main where
+
+ import System.Environment (getArgs)
+ import Text.Pandoc
+
+ -- Reads a String and parses it as a Pandoc instance
+ readDoc :: String -> Pandoc
+ readDoc = readMarkdown def
+
+ -- Writes a Pandoc instances as a String
+ writeDoc :: Pandoc -> String
+ writeDoc = writeHtmlString def
+
+ -- Reads markdown, writes HTML and prints it in stdout
+ doBench :: String -> IO ()
+ doBench fileName = do
+ content <- readFile fileName
+ let markdown = readDoc content
+ let html = writeDoc markdown
+ print html
+
+ -- Executes `doBench` n times
+ loop :: Int -> String -> IO ()
+ loop 0 _ = return ()
+ loop n fileName = do
+ doBench fileName
+ loop (n - 1) fileName
+ return ()
+
+ main :: IO ()
+ main = do
+ (fileName:count:_) <- getArgs
+ loop (read count::Int) fileName
--- /dev/null
+all: concat iter substr array
+
+concat:
+ ./bench_strings.sh cct 10 10000000 1
+
+substr:
+ ./bench_strings.sh substr 10 10000000 10
+
+iter:
+ ./bench_strings.sh iter 10 10000000 10
+
+array:
+ ./bench_strings.sh array 10 10000000 10
--- /dev/null
+# Strings
+
+Strings are a building block of programming.
+Since they are that necessary, we must keep them as performing as possible.
+
+This series of benchmarks works on different structures for handling strings on the most common operations done on them.
+
+## Structures
+
+Some more structures are susceptible to be added as the project advances.
+At the moment, what is available consists of
+
+* Flat strings
+* Flat buffers
+* Rope strings
+* Rope buffers
+
+A String is defined as an immutable string.
+A Buffer is defined as a mutable string.
+
+Flat strings are arrays of characters, the most basic implementation of a string.
+Ropes are a tree-like structure where strings are bound through concatenation nodes.
+
+## Tests
+
+`concat`: Benches the concatenation speed of strings and buffers.
+
+`iter`: Benches the time of iteration of a string, through iterators or indexed access
+
+`substr`: Benches the time required to produce a substring.
+
+`arraytos`: Special bench, it measures the speed of `Array::to_s` through the use of various strategies.
+
+## Usage
+
+To pass a series of benches you can use the `make` command to bench all the aforementioned tests with default values.
+
+Each bench will be executed 5 times and the mean time will be represented in the final graph.
+
+The alternative is to use `bench_strings.sh` with custom arguments to it.
+For more information on the arguments and the format, execute it with the -h option for help.
# To be used as a Mixin at compile-time for benchmarking purposes.
module array_to_s_buffer
+intrude import standard::collection::array
+import standard::string
+
redef class Array[E]
redef fun to_s: String do
var s = new FlatBuffer
# To be used as a Mixin at compile-time for benchmarking purposes.
module array_to_s_flatstr
+intrude import standard::string
+
+redef class FlatString
+ redef fun +(o) do
+ var mlen = length
+ var slen = o.length
+ var nns = new NativeString(mlen + slen)
+ items.copy_to(nns, mlen, index_from, 0)
+ if o isa FlatString then
+ o.items.copy_to(nns, slen, o.index_from, mlen)
+ else
+ var pos = mlen
+ for i in o.chars do
+ nns[pos] = i
+ pos += 1
+ end
+ end
+ return nns.to_s_with_length(mlen)
+ end
+end
+
redef class Array[E]
redef fun to_s do
# To be used as a Mixin at compile-time for benchmarking purposes.
module array_to_s_man_buf
-redef class NativeArray[E]
- new(length: Int) is intern
-end
+intrude import standard::collection::array
+import standard::string
redef class Array[E]
redef fun to_s: String do
# To be used as a Mixin at compile-time for benchmarking purposes.
module array_to_s_rope
+intrude import standard::collection::array
+intrude import standard::ropes
+
redef class Array[E]
redef fun to_s do
- var i = 1
var l = length
+ var it = _items
if l == 0 then return ""
- var s: String = new RopeString.from(self[0].to_s)
- var its = _items
- while i < l do
- var e = its[i]
- if e != null then s += e.to_s
- i += 1
+ if l == 1 then return it[0].to_s
+ var c = new Concat(it[0].to_s, it[1].to_s)
+ for i in [2 .. l[ do
+ c = new Concat(c, it[i].to_s)
end
- return s
+ return c
end
+
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT. This software is
+# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. You can modify it is you want, provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You are allowed to redistribute it and sell it, alone or is a part of
+# another product.
+
+# Implementation of Array::to_s with RopeBuffer exclusively
+#
+# To be used as a Mixin at compile-time for benchmarking purposes.
+module array_to_s_rope_buf
+
+intrude import standard::collection::array
+import standard::ropes
+
+redef class Array[E]
+ redef fun to_s: String do
+ var s = new RopeBuffer
+ var i = 0
+ var l = length
+ var its = _items
+ while i < l do
+ var e = its[i]
+ if e != null then s.append(e.to_s)
+ i += 1
+ end
+ return s.to_s
+ end
+end
# See the License for the specific language governing permissions and
# limitations under the License.
-source ./bench_common.sh
-source ./bench_plot.sh
+source ../bench_common.sh
+source ../bench_plot.sh
# Default number of times a command must be run with bench_command
# Can be overrided with 'the option -n'
-count=2
+count=5
function usage()
{
echo " -h: this help"
echo ""
echo "Benches : "
- echo " all : all benches"
- echo " - usage : * max_nb_cct loops strlen"
echo " iter: bench iterations"
echo " - usage : iter max_nb_cct loops strlen"
echo " cct: concatenation benching"
echo " - usage : array nb_cct loops max_arrlen"
}
-function benches()
-{
- bench_concat $@;
- bench_iteration $@;
- bench_substr $@;
- bench_array $@;
-}
-
function bench_array()
{
+ if [ -d arraytos ]; then
+ rm arraytos/*
+ else
+ mkdir arraytos
+ fi
+ cd arraytos
+
if $verbose; then
echo "*** Benching Array.to_s performance ***"
fi
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../array_tos.nit -m ../array_to_s_vars/array_to_s_rope.nit
prepare_res arr_tos_ropes.out arr_tos_ropes ropes
if $verbose; then
if $verbose; then
echo "String length = $i, Concats/loop = $1, Loops = $2"
fi
- bench_command $i ropes$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+ bench_command $i ropes$i ./array_tos --loops $2 --strlen $i --ccts $1
done
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
- prepare_res arr_tos_buf_ropes.out arr_tos_buf_ropes buffered_ropes
- if $verbose; then
- echo "Buffered Ropes :"
- fi
- for i in `seq 1 "$3"`; do
- if $verbose; then
- echo "String length = $i, Concats/loop = $1, Loops = $2"
- fi
- bench_command $i buf_ropes$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
- done
-
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../array_tos.nit -m ../array_to_s_vars/array_to_s_flatstr.nit
prepare_res arr_tos_flat.out arr_tos_flat flatstring
if $verbose; then
if $verbose; then
echo "String length = $i, Concats/loop = $1, Loops = $2"
fi
- bench_command $i flatstring$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+ bench_command $i flatstring$i ./array_tos --loops $2 --strlen $i --ccts $1
done
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_buffer.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../array_tos.nit -m ../array_to_s_vars/array_to_s_buffer.nit
prepare_res arr_tos_buf.out arr_tos_buf flatbuffer
if $verbose; then
if $verbose; then
echo "String length = $i, Concats/loop = $1, Loops = $2"
fi
- bench_command $i flatbuffer$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+ bench_command $i flatbuffer$i ./array_tos --loops $2 --strlen $i --ccts $1
done
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_manual.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../array_tos.nit -m ../array_to_s_vars/array_to_s_manual.nit
prepare_res arr_tos_man.out arr_tos_man memmove
if $verbose; then
if $verbose; then
echo "String length = $i, Concats/loop = $1, Loops = $2"
fi
- bench_command $i memmove$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+ bench_command $i memmove$i ./array_tos --loops $2 --strlen $i --ccts $1
done
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_man_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../array_tos.nit -m ../array_to_s_vars/array_to_s_man_buf.nit
prepare_res arr_tos_man_buf.out arr_tos_man_buf flatbuf_with_capacity
if $verbose; then
if $verbose; then
echo "String length = $i, Concats/loop = $1, Loops = $2"
fi
- bench_command $i flatbuf_with_capacity$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+ bench_command $i flatbuf_with_capacity$i ./array_tos --loops $2 --strlen $i --ccts $1
done
- ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_rope_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../array_tos.nit -m ../array_to_s_vars/array_to_s_rope_buf.nit
prepare_res arr_tos_rope_buf.out arr_tos_rope_buf ropebuf
if $verbose; then
if $verbose; then
echo "String length = $i, Concats/loop = $1, Loops = $2"
fi
- bench_command $i ropebuf$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+ bench_command $i ropebuf$i ./array_tos --loops $2 --strlen $i --ccts $1
done
plot array_tos.gnu
+
+ cd ..
}
function bench_concat()
{
- ../bin/nitc --global ./strings/chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- ../bin/nitc --global ./strings/utf_chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ if [ -d string_concat ]; then
+ rm string_concat/*
+ else
+ mkdir string_concat
+ fi
+ cd string_concat
+
+ ../../../bin/nitc --global ../chain_concat.nit
if $verbose; then
echo "*** Benching concat performance ***"
if $verbose; then
echo "String length = $i, Concats/loop = $2, Loops = $3"
fi
- bench_command $i flatstring$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatstring$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i
done
prepare_res concat_buf.out concat_buf flatbuffer
if $verbose; then
echo "String length = $i, Concats/loop = $2, Loops = $3"
fi
- bench_command $i flatbuffer$i ./chain_concat -m flatbuf --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatbuffer$i ./chain_concat -m flatbuf --loops $2 --strlen $3 --ccts $i
done
- prepare_res concat_flatstr_utf8_noindex.out concat_flatstr_utf8_noindex flatstring_utf8_noindex
- if $verbose; then
- echo "FlatString UTF-8 (without index) :"
- fi
- for i in `seq 1 "$1"`; do
- if $verbose; then
- echo "String length = $i, Concats/loop = $2, Loops = $3"
- fi
- bench_command $i flatstr_utf8_noindex$i ./utf_chain_concat -m flatstr_utf8_noindex --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
- done
-
- ../bin/nitc --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
prepare_res concat_ropes.out concat_ropes ropes
if $verbose; then
echo "Ropes :"
if $verbose; then
echo "String length = $i, Concats/loop = $2, Loops = $3"
fi
- bench_command $i ropes$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i ropes$i ./chain_concat -m ropestr --loops $2 --strlen $3 --ccts $i
done
- ../bin/nitc --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
prepare_res concat_buf_ropes.out concat_buf_ropes buffered_ropes
if $verbose; then
- echo "buffered ropes :"
- fi
- for i in `seq 1 "$1"`; do
- if $verbose; then
- echo "string length = $i, concats/loop = $2, loops = $3"
- fi
- bench_command $i buf_ropes$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
- done
-
- ../bin/nitc --global ./strings/chain_cct_ropebuf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
- prepare_res cct_buf_ropes.out cct_buf_ropes cctbuf_ropes
- if $verbose; then
- echo "buffered ropes :"
+ echo "Rope Buffer:"
fi
for i in `seq 1 "$1"`; do
if $verbose; then
echo "string length = $i, concats/loop = $2, loops = $3"
fi
- bench_command $i cctbuf_ropes$i ./chain_cct_ropebuf --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i buf_ropes$i ./chain_concat -m ropebuf --loops $2 --strlen $3 --ccts $i
done
plot concat.gnu
+
+ cd ..
}
function bench_iteration()
{
+ if [ -d string_iter ]; then
+ rm string_iter/*
+ else
+ mkdir string_iter
+ fi
+ cd string_iter
+
if $verbose; then
echo "*** Benching iteration performance ***"
fi
- ../bin/nitc --global ./strings/iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- ../bin/nitc --global ./strings/utf_iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../iteration_bench.nit
prepare_res iter_flat_iter.out iter_flat_iter flatstring_iter
if $verbose; then
if $verbose; then
echo "String base length = $1, Concats = $i, Loops = $3"
fi
- bench_command $i flatstr_iter$i ./iteration_bench -m flatstr --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatstr_iter$i ./iteration_bench -m flatstr --iter-mode iterator --loops $2 --strlen $3 --ccts $i
done
prepare_res iter_flat_index.out iter_flat_index flatstring_index
if $verbose; then
echo "String base length = $1, Concats = $i, Loops = $3"
fi
- bench_command $i flatstr_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatstr_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i
done
prepare_res iter_buf_iter.out iter_buf_iter flatbuffer_iter
if $verbose; then
echo "String base length = $1, Concats = $i, Loops = $3"
fi
- bench_command $i flatbuf_iter$i ./iteration_bench -m flatbuf --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatbuf_iter$i ./iteration_bench -m flatbuf --iter-mode iterator --loops $2 --strlen $3 --ccts $i
done
prepare_res iter_buf_index.out iter_buf_index flatbuffer_index
if $verbose; then
echo "String base length = $1, Concats = $i, Loops = $3"
fi
- bench_command $i flatbuf_index$i ./iteration_bench -m flatbuf --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatbuf_index$i ./iteration_bench -m flatbuf --iter-mode index --loops $2 --strlen $3 --ccts $i
done
- prepare_res iter_flat_utf8_noindex_iter.out iter_flat_iter_utf8_noindex flatstring_utf8_noindex_iter
- if $verbose; then
- echo "FlatStrings by iterator :"
- fi
- for i in `seq 1 "$1"`; do
- if $verbose; then
- echo "String base length = $1, Concats = $i, Loops = $3"
- fi
- bench_command $i flatstr_iter_utf8_noindex$i ./utf_iteration_bench -m flatstr_utf8_noindex --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
- done
-
- prepare_res iter_flat_utf8_noindex_index.out iter_flat_index_utf8_noindex flatstring_utf8_noindex_index
- if $verbose; then
- echo "FlatStrings by index :"
- fi
- for i in `seq 1 "$1"`; do
- if $verbose; then
- echo "String base length = $1, Concats = $i, Loops = $3"
- fi
- bench_command $i flatstr_index_utf8_noindex$i ./utf_iteration_bench -m flatstr_utf8_noindex --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
- done
-
- ../bin/nitc --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
prepare_res iter_ropes_iter.out iter_ropes_iter ropes_iter
if $verbose; then
echo "Ropes by iterator :"
if $verbose; then
echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
fi
- bench_command $i ropes_iter$i ./iteration_bench -m flatstr --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i ropes_iter$i ./iteration_bench -m ropestr --iter-mode iterator --loops $2 --strlen $3 --ccts $i
done
prepare_res iter_ropes_index.out iter_ropes_index ropes_index
if $verbose; then
echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
fi
- bench_command $i ropes_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i ropes_index$i ./iteration_bench -m ropestr --iter-mode index --loops $2 --strlen $3 --ccts $i
done
- ../bin/nitc --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
prepare_res iter_buf_ropes_iter.out iter_buf_ropes_iter buf_ropes_iter
if $verbose; then
- echo "Buffered Ropes by iterator :"
+ echo "RopeBuffer by iterator :"
fi
for i in `seq 1 "$1"`; do
if $verbose; then
echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
fi
- bench_command $i buf_ropes_iter$i ./iteration_bench -m flatstr --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i buf_ropes_iter$i ./iteration_bench -m ropebuf --iter-mode iterator --loops $2 --strlen $3 --ccts $i
done
prepare_res iter_buf_ropes_index.out iter_buf_ropes_index buf_ropes_index
if $verbose; then
- echo "Buffered Ropes by index :"
+ echo "RopeBuffer by index :"
fi
for i in `seq 1 "$1"`; do
if $verbose; then
echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
fi
- bench_command $i buf_ropes_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i buf_ropes_index$i ./iteration_bench -m ropebuf --iter-mode index --loops $2 --strlen $3 --ccts $i
done
plot iter.gnu
+
+ cd ..
}
function bench_substr()
{
+ if [ -d string_substr ]; then
+ rm string_substr/*
+ else
+ mkdir string_substr
+ fi
+ cd string_substr
+
if $verbose; then
echo "*** Benching substring performance ***"
fi
- ../bin/nitc --global ./strings/substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- ../bin/nitc --global ./strings/utf_substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../../../bin/nitc --global ../substr_bench.nit
prepare_res substr_flat.out substr_flat flatstring
if $verbose; then
if $verbose; then
echo "String length = $i, loops = $2, Loops = $3"
fi
- bench_command $i flatstring$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatstring$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i
done
prepare_res substr_buf.out substr_buf flatbuffer
if $verbose; then
echo "String length = $i, loops = $2, Loops = $3"
fi
- bench_command $i flatbuffer$i ./substr_bench -m flatbuf --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
- done
-
- prepare_res substr_flat_utf8_noindex.out substr_flat_utf8_noindex flatstring_utf8_noindex
- if $verbose; then
- echo "FlatStrings UTF-8 (without index) :"
- fi
- for i in `seq 1 "$1"`; do
- if $verbose; then
- echo "String length = $i, loops = $2, Loops = $3"
- fi
- bench_command $i flatstring_utf8_noindex$i ./utf_substr_bench -m flatstr_utf8_noindex --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i flatbuffer$i ./substr_bench -m flatbuf --loops $2 --strlen $3 --ccts $i
done
- ../bin/nitc --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
prepare_res substr_ropes.out substr_ropes ropes
if $verbose; then
echo "Ropes :"
if $verbose; then
echo "String length = $i, loops = $2, Loops = $3"
fi
- bench_command $i ropes$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i ropes$i ./substr_bench -m ropestr --loops $2 --strlen $3 --ccts $i
done
- ../bin/nitc --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
prepare_res substr_buf_ropes.out substr_buf_ropes buf_ropes
if $verbose; then
- echo "Buffered Ropes :"
+ echo "RopeBuffers :"
fi
for i in `seq 1 "$1"`; do
if $verbose; then
echo "String length = $i, loops = $2, Loops = $3"
fi
- bench_command $i buf_ropes$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+ bench_command $i buf_ropes$i ./substr_bench -m ropebuf --loops $2 --strlen $3 --ccts $i
done
+
plot substr.gnu
+
+ cd ..
}
stop=false
cct) shift; bench_concat $@ ;;
substr) shift; bench_substr $@ ;;
array) shift; bench_array $@ ;;
- all) shift; benches $@ ;;
*) usage; exit;;
esac
# Benches measuring the performance of several concatenations on Text variants
module chain_concat
+intrude import standard::ropes
import opts
+redef class FlatString
+ redef fun +(o) do
+ var mlen = length
+ var slen = o.length
+ var nlen = mlen + slen
+ var ns = new NativeString(nlen + 1)
+ items.copy_to(ns, mlen, index_from, 0)
+ if o isa FlatString then
+ o.items.copy_to(ns, slen, o.index_from, 0)
+ else
+ var pos = mlen
+ for i in o.chars do
+ ns[pos] = i
+ pos += 1
+ end
+ end
+ return ns.to_s_with_length(nlen)
+ end
+end
+
fun bench_flatstr(str_size: Int, nb_ccts: Int, loops: Int)
do
var lft = "a" * str_size
- for i in [0..loops] do
- var str: String = lft
- for j in [0..nb_ccts] do
+ for i in [0 .. loops[ do
+ var str: String = ""
+ for j in [0 .. nb_ccts[ do
str += lft
end
end
end
+fun bench_ropestr(str_size, nb_ccts, loops: Int) do
+ var lft = "a" * str_size
+
+ for i in [0 .. loops[ do
+ var str: String = ""
+ for j in [0 .. nb_ccts[ do
+ str = new Concat(str, lft)
+ end
+ end
+end
+
fun bench_flatbuf(str_size: Int, nb_ccts: Int, loops: Int)
do
var lft = "a" * str_size
- for i in [0..loops] do
- var buf = new FlatBuffer.from(lft)
- for j in [0..nb_ccts] do
+ for i in [0 .. loops[ do
+ var buf = new FlatBuffer
+ for j in [0 .. nb_ccts[ do
+ buf.append(lft)
+ end
+ end
+end
+
+fun bench_ropebuf(str_size: Int, nb_ccts: Int, loops: Int)
+do
+ var lft = "a" * str_size
+
+ for i in [0 .. loops[ do
+ var buf = new RopeBuffer
+ for j in [0 .. nb_ccts[ do
buf.append(lft)
end
- buf.to_s
end
end
var opts = new OptionContext
-var mode = new OptionEnum(["flatstr", "flatbuf"], "Mode", -1, "-m")
+var mode = new OptionEnum(["flatstr", "ropestr", "flatbuf", "ropebuf"], "Mode", -1, "-m")
var nb_ccts = new OptionInt("Number of concatenations per loop", -1, "--ccts")
var loops = new OptionInt("Number of loops to be done", -1, "--loops")
var strlen = new OptionInt("Length of the base string", -1, "--strlen")
if modval == 0 then
bench_flatstr(strlen.value, nb_ccts.value, loops.value)
else if modval == 1 then
+ bench_ropestr(strlen.value, nb_ccts.value, loops.value)
+else if modval == 2 then
bench_flatbuf(strlen.value, nb_ccts.value, loops.value)
+else if modval == 3 then
+ bench_ropebuf(strlen.value, nb_ccts.value, loops.value)
+
else
opts.usage
exit -1
module iteration_bench
import opts
+intrude import standard::ropes
+
+redef class Concat
+ redef fun +(o) do
+ var s = o.to_s
+ return new Concat(self, s)
+ end
+end
+
+redef class FlatString
+ redef fun +(o) do
+ var s = o.to_s
+ var b = new FlatBuffer.with_capacity(length + s.length)
+ b.append self
+ for i in s.substrings do b.append i
+ return b.to_s
+ end
+end
fun bench_flatstr_iter(nb_cct: Int, loops: Int, strlen: Int)
do
var a = "a" * strlen
- var x = a
- for i in [0 .. nb_cct] do x += a
+ a = a * nb_cct
var cnt = 0
var c: Char
while cnt != loops do
- for i in x do
+ for i in a do
c = i
end
cnt += 1
fun bench_flatstr_index(nb_cct: Int, loops: Int, strlen: Int)
do
var a = "a" * strlen
- var x = a
- for i in [0 .. nb_cct] do x += a
+ a = a * nb_cct
+ var cnt = 0
+ var c: Char
+ var pos = 0
+ while cnt != loops do
+ pos = 0
+ while pos < a.length do
+ c = a[pos]
+ pos += 1
+ end
+ cnt += 1
+ end
+end
+
+fun bench_ropestr_iter(nb_cct: Int, loops: Int, strlen: Int)
+do
+ var a = "a" * strlen
+ var x: String = new Concat(a, a)
+ for i in [2 .. nb_cct[ do x = new Concat(x, a)
+ var cnt = 0
+ var c: Char
+ while cnt != loops do
+ for i in x do
+ c = i
+ end
+ cnt += 1
+ end
+end
+
+fun bench_ropestr_index(nb_cct: Int, loops: Int, strlen: Int)
+do
+ var a = "a" * strlen
+ var x: String = new Concat(a, a)
+ for i in [2 .. nb_cct[ do x = new Concat(x, a)
var cnt = 0
var c: Char
var pos = 0
fun bench_flatbuf_iter(nb_cct: Int, loops: Int, strlen: Int)
do
var a = "a" * strlen
+ a = a * nb_cct
var x = new FlatBuffer.from(a)
- for i in [0 .. nb_cct] do x.append a
var cnt = 0
var c: Char
while cnt != loops do
fun bench_flatbuf_index(nb_cct: Int, loops: Int, strlen: Int)
do
var a = "a" * strlen
+ a = a * nb_cct
var x = new FlatBuffer.from(a)
- for i in [0 .. nb_cct] do x.append a
+ var cnt = 0
+ var c: Char
+ var pos = 0
+ while cnt != loops do
+ pos = 0
+ while pos < x.length do
+ c = x[pos]
+ pos += 1
+ end
+ cnt += 1
+ end
+end
+
+fun bench_ropebuf_iter(nb_cct: Int, loops: Int, strlen: Int)
+do
+ var a = "a" * strlen
+ var x = new RopeBuffer.from(a)
+ for i in [0 .. nb_cct[ do x.append a
+ var cnt = 0
+ var c: Char
+ while cnt != loops do
+ for i in x do
+ c = i
+ end
+ cnt += 1
+ end
+end
+
+fun bench_ropebuf_index(nb_cct: Int, loops: Int, strlen: Int)
+do
+ var a = "a" * strlen
+ var x = new RopeBuffer.from(a)
+ for i in [0 .. nb_cct[ do x.append a
var cnt = 0
var c: Char
var pos = 0
end
var opts = new OptionContext
-var mode = new OptionEnum(["flatstr", "flatbuf"], "Mode", -1, "-m")
+var mode = new OptionEnum(["flatstr", "flatbuf", "ropestr", "ropebuf"], "Mode", -1, "-m")
var access_mode = new OptionEnum(["iterator", "index"], "Iteration mode", -1, "--iter-mode")
var nb_ccts = new OptionInt("Number of concatenations done to the string (in the case of the rope, this will increase its depth)", -1, "--ccts")
var loops = new OptionInt("Number of loops to be done", -1, "--loops")
opts.usage
exit(-1)
end
+else if modval == 2 then
+ if iterval == 0 then
+ bench_ropestr_iter(nb_ccts.value, loops.value, strlen.value)
+ else if iterval == 1 then
+ bench_ropestr_index(nb_ccts.value, loops.value, strlen.value)
+ else
+ opts.usage
+ exit(-1)
+ end
+else if modval == 3 then
+ if iterval == 0 then
+ bench_ropebuf_iter(nb_ccts.value, loops.value, strlen.value)
+ else if iterval == 1 then
+ bench_ropebuf_index(nb_ccts.value, loops.value, strlen.value)
+ else
+ opts.usage
+ exit(-1)
+ end
else
opts.usage
exit(-1)
module substr_bench
import opts
+intrude import standard::ropes
fun bench_flatstr(nb_cct: Int, loops: Int, strlen: Int)
do
var a = "a" * strlen
- var x = a
- for i in [0 .. nb_cct] do x += a
+ a = a * nb_cct
+ var maxl = a.length - 1
var cnt = 0
while cnt != loops do
- x.substring(0,5)
+ a.substring(maxl.rand, maxl.rand)
cnt += 1
end
end
fun bench_flatbuf(nb_cct: Int, loops: Int, strlen: Int)
do
var a = "a" * strlen
+ a = a * nb_cct
+ var maxl = a.length - 1
var x = new FlatBuffer.from(a)
- for i in [0 .. nb_cct] do x.append a
var cnt = 0
while cnt != loops do
- x.substring(0,5)
+ x.substring(maxl.rand, maxl.rand)
+ cnt += 1
+ end
+end
+
+fun bench_ropestr(nb_cct: Int, loops: Int, strlen: Int)
+do
+ var a = "a" * strlen
+ var x = new Concat(a, a)
+ for i in [2 .. nb_cct[ do x = new Concat(x, a)
+ var maxl = x.length - 1
+ var cnt = 0
+ while cnt != loops do
+ x.substring(maxl.rand, maxl.rand)
+ cnt += 1
+ end
+end
+
+fun bench_ropebuf(nb_cct: Int, loops: Int, strlen: Int)
+do
+ var a = "a" * strlen
+ var x = new RopeBuffer.from(a)
+ for i in [1 .. nb_cct[ do x.append a
+ var maxl = x.length - 1
+ var cnt = 0
+ while cnt != loops do
+ x.substring(maxl.rand, maxl.rand)
cnt += 1
end
end
var opts = new OptionContext
-var mode = new OptionEnum(["flatstr", "flatbuf"], "Mode", -1, "-m")
+var mode = new OptionEnum(["flatstr", "flatbuf", "ropestr", "ropebuf"], "Mode", -1, "-m")
var nb_ccts = new OptionInt("Number of concatenations done to the string (in the case of the rope, this will increase its depth)", -1, "--ccts")
var loops = new OptionInt("Number of loops to be done", -1, "--loops")
var strlen = new OptionInt("Length of the base string", -1, "--strlen")
end
var modval = mode.value
+srand_from(0)
if modval == 0 then
bench_flatstr(nb_ccts.value, loops.value, strlen.value)
else if modval == 1 then
bench_flatbuf(nb_ccts.value, loops.value, strlen.value)
+else if modval == 2 then
+ bench_ropestr(nb_ccts.value, loops.value, strlen.value)
+else if modval == 3 then
+ bench_ropebuf(nb_ccts.value, loops.value, strlen.value)
else
opts.usage
exit(-1)
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Benches measuring the performance of several concatenations on Text variants
-module utf_chain_concat
-
-import opts
-import string_experimentations::utf8_noindex
-
-fun bench_flatstr(str_size: Int, nb_ccts: Int, loops: Int)
-do
- var lft = "a" * str_size
-
- for i in [0..loops] do
- var str: String = lft
- for j in [0..nb_ccts] do
- str += lft
- end
- end
-end
-
-var opts = new OptionContext
-var nb_ccts = new OptionInt("Number of concatenations per loop", -1, "--ccts")
-var loops = new OptionInt("Number of loops to be done", -1, "--loops")
-var strlen = new OptionInt("Length of the base string", -1, "--strlen")
-opts.add_option(nb_ccts, loops, strlen)
-
-opts.parse(args)
-
-if nb_ccts.value == -1 or loops.value == -1 or strlen.value == -1 then
- opts.usage
- exit -1
-end
-
-bench_flatstr(strlen.value, nb_ccts.value, loops.value)
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Benches for iteration on variants of Text
-module utf_iteration_bench
-
-import opts
-import string_experimentations::utf8_noindex
-
-fun bench_flatstr_iter(nb_cct: Int, loops: Int, strlen: Int)
-do
- var a = "a" * strlen
- var x = a.as(FlatString)
- for i in [0 .. nb_cct] do x = (x + a).as(FlatString)
- var cnt = 0
- var c: UnicodeChar
- while cnt != loops do
- var it = new FlatStringIter(x)
- for i in it do
- c = i
- end
- cnt += 1
- end
-end
-
-fun bench_flatstr_index(nb_cct: Int, loops: Int, strlen: Int)
-do
- var a = "a" * strlen
- var x = a.as(FlatString)
- for i in [0 .. nb_cct] do x = (x + a).as(FlatString)
- var cnt = 0
- var c: UnicodeChar
- var pos = 0
- while cnt != loops do
- pos = 0
- while pos < x.length do
- c = x.char_at(pos)
- pos += 1
- end
- cnt += 1
- end
-end
-
-var opts = new OptionContext
-var access_mode = new OptionEnum(["iterator", "index"], "Iteration mode", -1, "--iter-mode")
-var nb_ccts = new OptionInt("Number of concatenations done to the string (in the case of the rope, this will increase its depth)", -1, "--ccts")
-var loops = new OptionInt("Number of loops to be done", -1, "--loops")
-var strlen = new OptionInt("Length of the base string", -1, "--strlen")
-opts.add_option(nb_ccts, loops, strlen, access_mode)
-
-opts.parse(args)
-
-if nb_ccts.value == -1 or loops.value == -1 or strlen.value == -1 then
- opts.usage
- exit(-1)
-end
-
-var iterval = access_mode.value
-
-if iterval == 0 then
- bench_flatstr_iter(nb_ccts.value, loops.value, strlen.value)
-else if iterval == 1 then
- bench_flatstr_index(nb_ccts.value, loops.value, strlen.value)
-else
- opts.usage
- exit(-1)
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Benches on the substring operation on variants of Text
-module utf_substr_bench
-
-import opts
-import string_experimentations::utf8_noindex
-
-fun bench_flatstr(nb_cct: Int, loops: Int, strlen: Int)
-do
- var a = "a" * strlen
- var x = a
- for i in [0 .. nb_cct] do x += a
- var cnt = 0
- while cnt != loops do
- x.substring(0,5)
- cnt += 1
- end
-end
-
-var opts = new OptionContext
-var nb_ccts = new OptionInt("Number of concatenations done to the string (in the case of the rope, this will increase its depth)", -1, "--ccts")
-var loops = new OptionInt("Number of loops to be done", -1, "--loops")
-var strlen = new OptionInt("Length of the base string", -1, "--strlen")
-opts.add_option(nb_ccts, loops, strlen)
-
-opts.parse(args)
-
-if nb_ccts.value == -1 or loops.value == -1 or strlen.value == -1 then
- opts.usage
- exit(-1)
-end
-
-bench_flatstr(nb_ccts.value, loops.value, strlen.value)
--- /dev/null
+# Copyright 2013 Alexandre Terrasa <alexandre@moz-code.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.
+
+all: run
+
+run: hello_world.jar
+ java -jar hello_world.jar
+
+hello_world.jar: nitj
+ NIT_DIR= ./nitj ../examples/hello_world.nit
+
+nitj:
+ NIT_DIR= ./nitg ../src/nitj.nit
+
+clean:
+ rm -rf -- hello_world.jar .nit_jcompile 2> /dev/null || true
--- /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)
--- /dev/null
+out/hello_ios.bin
+out/hello_ios.bin/Info.plist
+out/hello_ios.bin/PkgInfo
+out/hello_ios.bin/hello_ios
--- /dev/null
+out/test_platform_ios.bin
+out/test_platform_ios.bin/Info.plist
+out/test_platform_ios.bin/PkgInfo
+out/test_platform_ios.bin/test_platform_ios
--- /dev/null
+#!/bin/bash
+# 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.
+
+# Tests to run on OS X for the host platform and iOS
+./tests.sh $@ \
+ test_ffi_objc_*.nit \
+ test_*ios.nit \
+ ../lib/ios/examples/*.nit \
+ ../lib/cocoa*/examples/*.nit
*) stop=true
esac
done
- if test -n "$TIME"; then
+ if test -d "$1"; then
+ find $1 | sort
+ elif test -n "$TIME"; then
$TIME -o "$o" $a $TIMEOUT "$@"
else
if test -n "$a"; then echo 0 >> "$o"; else echo 0 > "$o"; fi