diff options
-rw-r--r-- | doc/idetools.txt | 15 | ||||
-rw-r--r-- | lib/core/macros.nim | 32 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 99 |
3 files changed, 123 insertions, 23 deletions
diff --git a/doc/idetools.txt b/doc/idetools.txt index 7e51669f2..c1eba9e5f 100644 --- a/doc/idetools.txt +++ b/doc/idetools.txt @@ -527,21 +527,6 @@ At the moment idetools support is still in development so the test suite is not integrated with the main test suite and you have to run it manually. First you have to compile the tester:: - $ cd my/nimrod/checkout - $ nimrod c tests/tester.nim - -Running the tester without parameters will display some options. -To run the caas test suite (and other special tests) you need to -use the `special` command. You need to run this command from the -root of the checkout or it won't be able to open the required files:: - - $ ./tests/tester special - -However this is a roundabout way of running the test suite. You can -also compile and run ``tests/caasdriver.nim`` manually. In fact, -running it manually will allow you to specify special parameters -too. Example:: - $ cd my/nimrod/checkout/tests $ nimrod c caasdriver.nim diff --git a/lib/core/macros.nim b/lib/core/macros.nim index d28826071..52ee9326f 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -268,6 +268,8 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst".} ## ## Example: ## + ## .. code-block:: nimrod + ## ## macro check(ex: expr): stmt = ## # this is a simplified version of the check macro from the ## # unittest module. @@ -290,6 +292,8 @@ template emit*(e: expr[string]): stmt = ## that should be inserted verbatim in the program ## Example: ## + ## .. code-block:: nimrod + ## ## emit("echo " & '"' & "hello world".toUpper & '"') ## eval: result = e.parseStmt @@ -474,6 +478,34 @@ proc newDotExpr*(a, b: PNimrodNode): PNimrodNode {.compileTime.} = proc newIdentDefs*(name, kind: PNimrodNode; default = newEmptyNode()): PNimrodNode {.compileTime.} = + ## Creates a new ``nnkIdentDefs`` node of a specific kind and value. + ## + ## ``nnkIdentDefs`` need to have at least three children, but they can have + ## more: first comes a list of identifiers followed by a type and value + ## nodes. This helper proc creates a three node subtree, the first subnode + ## being a single identifier name. Both the ``kind`` node and ``default`` + ## (value) nodes may be empty depending on where the ``nnkIdentDefs`` + ## appears: tuple or object definitions will have an empty ``default`` node, + ## ``let`` or ``var`` blocks may have an empty ``kind`` node if the + ## identifier is being assigned a value. Example: + ## + ## .. code-block:: nimrod + ## + ## var varSection = newNimNode(nnkVarSection).add( + ## newIdentDefs(ident("a"), ident("string")), + ## newIdentDefs(ident("b"), newEmptyNode(), newLit(3))) + ## # --> var + ## # a: string + ## # b = 3 + ## + ## If you need to create multiple identifiers you need to use the lower level + ## ``newNimNode``: + ## + ## .. code-block:: nimrod + ## + ## result = newNimNode(nnkIdentDefs).add( + ## ident("a"), ident("b"), ident("c"), ident("string"), + ## newStrLitNode("Hello")) newNimNode(nnkIdentDefs).add(name, kind, default) proc newNilLit*(): PNimrodNode {.compileTime.} = diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 364f847cc..09c6ba8b8 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -7,7 +7,18 @@ # distribution, for details about the copyright. # -## This module implements a generator of HTML/Latex from `reStructuredText`:idx:. +## This module implements a generator of HTML/Latex from +## `reStructuredText`:idx: (see http://docutils.sourceforge.net/rst.html for +## information on this markup syntax). You can generate HTML output through the +## convenience proc ``rstToHtml``, which provided an input string with rst +## markup returns a string with the generated HTML. The final output is meant +## to be embedded inside a full document you provide yourself, so it won't +## contain the usual ``<header>`` or ``<body>`` parts. +## +## You can also create a ``TRstGenerator`` structure and populate it with the +## other lower level methods to finally build complete documents. This requires +## many options and tweaking, but you are not limited to snippets and can +## generate `LaTeX documents <https://en.wikipedia.org/wiki/LaTeX>`_ too. import strutils, os, hashes, strtabs, rstast, rst, highlite @@ -40,13 +51,51 @@ type filename*: string meta*: array[TMetaEnum, string] - PDoc = var TRstGenerator + PDoc = var TRstGenerator ## Alias to type less. proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, config: PStringTable, filename: string, options: TRstParseOptions, findFile: TFindFileHandler, msgHandler: TMsgHandler) = + ## Initializes a ``TRstGenerator``. + ## + ## You need to call this before using a ``TRstGenerator`` with any other + ## procs in this module. Pass a non ``nil`` ``PStringTable`` value as + ## ``config`` with parameters used by the HTML output generator. If you + ## don't know what to use, pass the results of the ``defaultConfig()`` proc. + ## The ``filename`` is symbolic and used only for error reporting, you can + ## pass any non ``nil`` string here. + ## + ## The ``TRstParseOptions``, ``TFindFileHandler`` and ``TMsgHandler`` types + ## are defined in the the `packages/docutils/rst module <rst.html>`_. + ## ``options`` selects the behaviour of the rst parser. + ## + ## ``findFile`` is a proc used by the rst ``include`` directive among others. + ## The purpose of this proc is to mangle or filter paths. It receives paths + ## specified in the rst document and has to return a valid path to existing + ## files or the empty string otherwise. If you pass ``nil``, a default proc + ## will be used which given a path returns the input path only if the file + ## exists. One use for this proc is to transform relative paths found in the + ## document to absolute path, useful if the rst file and the resources it + ## references are not in the same directory as the current working directory. + ## + ## The ``msgHandler`` is a proc used for user error reporting. It will be + ## called with the filename, line, col, and type of any error found during + ## parsing. If you pass ``nil``, a default message handler will be used which + ## writes the messages to the standard output. + ## + ## Example: + ## + ## .. code-block:: nimrod + ## + ## import packages/docutils/rstgen + ## + ## var gen: TRstGenerator + ## + ## gen.initRstGenerator(outHtml, defaultConfig(), + ## "filename", {}, nil, nil) + g.config = config g.target = target g.tocPart = @[] @@ -147,7 +196,19 @@ proc dispA(target: TOutputTarget, dest: var string, if target != outLatex: addf(dest, xml, args) else: addf(dest, tex, args) -proc renderRstToOut*(d: PDoc, n: PRstNode, result: var string) +proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string) + ## Writes into ``result`` the rst ast ``n`` using the ``d`` configuration. + ## + ## Before using this proc you need to initialise a ``TRstGenerator`` with + ## ``initRstGenerator`` and parse a rst file with ``rstParse`` from the + ## `packages/docutils/rst module <rst.html>`_. Example: + ## + ## .. code-block:: nimrod + ## + ## # ...configure gen and rst vars... + ## var generatedHTML = "" + ## renderRstToOut(gen, rst, generatedHTML) + ## echo generatedHTML proc renderAux(d: PDoc, n: PRstNode, result: var string) = for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result) @@ -162,7 +223,7 @@ proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) = # ---------------- index handling -------------------------------------------- -proc setIndexTerm*(d: PDoc, id, term: string) = +proc setIndexTerm*(d: var TRstGenerator, id, term: string) = d.theIndex.add(term) d.theIndex.add('\t') let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt) @@ -295,7 +356,7 @@ proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) = "<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>\n", "\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header]) -proc renderTocEntries*(d: PDoc, j: var int, lvl: int, result: var string) = +proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, result: var string) = var tmp = "" while j <= high(d.tocPart): var a = abs(d.tocPart[j].n.level) @@ -678,8 +739,26 @@ $content proc rstToHtml*(s: string, options: TRstParseOptions, config: PStringTable): string = - ## exported for *nimforum*. - + ## Converts an input rst string into embeddable HTML. + ## + ## This convenience proc parses any input string using rst markup (it doesn't + ## have to be a full document!) and returns an embeddable piece of HTML. The + ## proc is meant to be used in *online* environments without access to a + ## meaningful filesystem, and therefore rst ``include`` like directives won't + ## work. For an explanation of the ``config`` parameter see the + ## ``initRstGenerator`` proc. Example: + ## + ## .. code-block:: nimrod + ## import packages/docutils/rstgen, strtabs + ## + ## echo rstToHtml("*Hello* **world**!", {}, + ## newStringTable(modeStyleInsensitive)) + ## # --> <em>Hello</em> <strong>world</strong>! + ## + ## If you need to allow the rst ``include`` directive or tweak the generated + ## output you have to create your own ``TRstGenerator`` with + ## ``initRstGenerator`` and related procs. + proc myFindFile(filename: string): string = # we don't find any files in online mode: result = "" @@ -692,4 +771,8 @@ proc rstToHtml*(s: string, options: TRstParseOptions, var rst = rstParse(s, filen, 0, 1, dummyHasToc, options) result = "" renderRstToOut(d, rst, result) - + + +when isMainModule: + echo rstToHtml("*Hello* **world**!", {}, + newStringTable(modeStyleInsensitive)) |