diff options
Diffstat (limited to 'lib/packages')
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index a68ae928c..434d98b06 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -85,8 +85,8 @@ proc init(p: var CodeBlockParams) = proc initRstGenerator*(g: var RstGenerator, target: OutputTarget, config: StringTableRef, filename: string, options: RstParseOptions, - findFile: FindFileHandler=nil, - msgHandler: MsgHandler=nil) = + findFile: FindFileHandler = nil, + msgHandler: MsgHandler = nil) = ## Initializes a ``RstGenerator``. ## ## You need to call this before using a ``RstGenerator`` with any other @@ -255,9 +255,9 @@ proc renderRstToOut*(d: var RstGenerator, n: PRstNode, result: var string) ## .. code-block:: nim ## ## # ...configure gen and rst vars... - ## var generatedHTML = "" - ## renderRstToOut(gen, rst, generatedHTML) - ## echo generatedHTML + ## 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) @@ -282,20 +282,26 @@ proc quoteIndexColumn(text: string): string = ## * ``"\\"`` => ``"\\\\"`` ## * ``"\n"`` => ``"\\n"`` ## * ``"\t"`` => ``"\\t"`` - result = text.replace("\\", "\\\\").replace("\n", "\\n").replace("\t", "\\t") + result = newStringOfCap(text.len + 3) + for c in text: + case c + of '\\': result.add "\\" + of '\L': result.add "\\n" + of '\C': discard + of '\t': result.add "\\t" + else: result.add c proc unquoteIndexColumn(text: string): string = ## Returns the unquoted version generated by ``quoteIndexColumn``. - result = text.replace("\\t", "\t").replace("\\n", "\n").replace("\\\\", "\\") + result = text.multiReplace(("\\t", "\t"), ("\\n", "\n"), ("\\\\", "\\")) -proc setIndexTerm*(d: var RstGenerator, id, term: string, +proc setIndexTerm*(d: var RstGenerator, htmlFile, id, term: string, linkTitle, linkDesc = "") = ## Adds a `term` to the index using the specified hyperlink identifier. ## ## A new entry will be added to the index using the format - ## ``term<tab>file#id``. The file part will come from the `filename` - ## parameter used in a previous call to the `initRstGenerator() - ## <#initRstGenerator>`_ proc. + ## ``term<tab>file#id``. The file part will come from the `htmlFile` + ## parameter. ## ## The `id` will be appended with a hash character only if its length is not ## zero, otherwise no specific anchor will be generated. In general you @@ -316,7 +322,6 @@ proc setIndexTerm*(d: var RstGenerator, id, term: string, entry = term isTitle = false entry.add('\t') - let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt) entry.add(htmlFile) if id.len > 0: entry.add('#') @@ -356,7 +361,7 @@ proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) = var term = "" renderAux(d, n, term) - setIndexTerm(d, id, term, d.currentSection) + setIndexTerm(d, "", id, term, d.currentSection) dispA(d.target, result, "<span id=\"$1\">$2</span>", "$2\\label{$1}", [id, term]) @@ -364,15 +369,15 @@ type IndexEntry = object keyword: string link: string - linkTitle: string ## If not nil, contains a prettier text for the href - linkDesc: string ## If not nil, the title attribute of the final href + linkTitle: string ## contains a prettier text for the href + linkDesc: string ## the title attribute of the final href IndexedDocs = Table[IndexEntry, seq[IndexEntry]] ## \ ## Contains the index sequences for doc types. ## ## The key is a *fake* IndexEntry which will contain the title of the ## document in the `keyword` field and `link` will contain the html - ## filename for the document. `linkTitle` and `linkDesc` will be nil. + ## filename for the document. `linkTitle` and `linkDesc` will be empty. ## ## The value indexed by this IndexEntry is a sequence with the real index ## entries found in the ``.idx`` file. @@ -433,13 +438,13 @@ proc generateSymbolIndex(symbols: seq[IndexEntry]): string = var i = 0 while i < symbols.len: let keyword = symbols[i].keyword - let cleaned_keyword = keyword.escapeLink + let cleanedKeyword = keyword.escapeLink result.addf("<dt><a name=\"$2\" href=\"#$2\"><span>$1:</span></a></dt><dd><ul class=\"simple\">\n", - [keyword, cleaned_keyword]) + [keyword, cleanedKeyword]) var j = i while j < symbols.len and keyword == symbols[j].keyword: let - url = symbols[j].link.escapeLink + url = symbols[j].link #.escapeLink text = if symbols[j].linkTitle.len > 0: symbols[j].linkTitle else: url desc = if symbols[j].linkDesc.len > 0: symbols[j].linkDesc else: "" if desc.len > 0: @@ -462,12 +467,12 @@ proc isDocumentationTitle(hyperlink: string): bool = ## for a more detailed explanation. result = hyperlink.find('#') < 0 -proc stripTOCLevel(s: string): tuple[level: int, text: string] = +proc stripTocLevel(s: string): tuple[level: int, text: string] = ## Returns the *level* of the toc along with the text without it. - for c in 0 .. <s.len: + for c in 0 ..< s.len: result.level = c if s[c] != ' ': break - result.text = s[result.level .. <s.len] + result.text = s[result.level ..< s.len] proc indentToLevel(level: var int, newLevel: int): string = ## Returns the sequence of <ul>|</ul> characters to switch to `newLevel`. @@ -483,7 +488,7 @@ proc indentToLevel(level: var int, newLevel: int): string = result = repeat("</ul></li>", level - newLevel) level = newLevel -proc generateDocumentationTOC(entries: seq[IndexEntry]): string = +proc generateDocumentationToc(entries: seq[IndexEntry]): string = ## Returns the sequence of index entries in an HTML hierarchical list. result = "" # Build a list of levels and extracted titles to make processing easier. @@ -495,7 +500,7 @@ proc generateDocumentationTOC(entries: seq[IndexEntry]): string = level = 1 levels.newSeq(entries.len) for entry in entries: - let (rawLevel, rawText) = stripTOCLevel(entry.linkTitle or entry.keyword) + let (rawLevel, rawText) = stripTocLevel(entry.linkTitle or entry.keyword) if rawLevel < 1: # This is a normal symbol, push it *inside* one level from the last one. levels[L].level = level + 1 @@ -519,9 +524,9 @@ proc generateDocumentationTOC(entries: seq[IndexEntry]): string = titleTag = levels[L].text else: result.add(level.indentToLevel(levels[L].level)) - result.addf("""<li><a class="reference" data-doc-search-tag="$1" href="$2"> + result.addf("""<li><a class="reference" data-doc-search-tag="$1: $2" href="$3"> $3</a></li> - """, [titleTag & " : " & levels[L].text, link, levels[L].text]) + """, [titleTag, levels[L].text, link, levels[L].text]) inc L result.add(level.indentToLevel(1) & "</ul>\n") @@ -534,7 +539,7 @@ proc generateDocumentationIndex(docs: IndexedDocs): string = sort(titles, cmp) for title in titles: - let tocList = generateDocumentationTOC(docs.getOrDefault(title)) + let tocList = generateDocumentationToc(docs.getOrDefault(title)) result.add("<ul><li><a href=\"" & title.link & "\">" & title.keyword & "</a>\n" & tocList & "</li></ul>\n") @@ -575,8 +580,8 @@ proc readIndexDir(dir: string): setLen(result.symbols, 0) var L = 0 # Scan index files and build the list of symbols. - for kind, path in walkDir(dir): - if kind == pcFile and path.endsWith(IndexExt): + for path in walkDirRec(dir): + if path.endsWith(IndexExt): var fileEntries: seq[IndexEntry] title: IndexEntry @@ -606,7 +611,7 @@ proc readIndexDir(dir: string): inc F # Depending on type add this to the list of symbols or table of APIs. if title.keyword.len == 0: - for i in 0 .. <F: + for i in 0 ..< F: # Don't add to symbols TOC entries (they start with a whitespace). let toc = fileEntries[i].linkTitle if toc.len > 0 and toc[0] == ' ': @@ -615,7 +620,12 @@ proc readIndexDir(dir: string): setLen(result.symbols, L + 1) result.symbols[L] = fileEntries[i] inc L - result.modules.add(path.splitFile.name) + if fileEntries.len > 0: + var x = fileEntries[0].link + let i = find(x, '#') + if i > 0: + x = x.substr(0, i-1) + result.modules.add(x.changeFileExt("")) else: # Generate the symbolic anchor for index quickjumps. title.linkTitle = "doc_toc_" & $result.docs.len @@ -676,7 +686,7 @@ proc mergeIndexes*(dir: string): string = # ---------------------------------------------------------------------------- -proc stripTOCHTML(s: string): string = +proc stripTocHtml(s: string): string = ## Ugly quick hack to remove HTML tags from TOC titles. ## ## A TocEntry.header field already contains rendered HTML tags. Instead of @@ -724,7 +734,7 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = # Generate index entry using spaces to indicate TOC level for the output HTML. assert n.level >= 0 - setIndexTerm(d, refname, tmp.stripTOCHTML, + setIndexTerm(d, "", refname, tmp.stripTocHtml, spaces(max(0, n.level)) & tmp) proc renderOverline(d: PDoc, n: PRstNode, result: var string) = @@ -872,7 +882,7 @@ proc parseCodeBlockParams(d: PDoc, n: PRstNode): CodeBlockParams = if result.langStr != "": result.lang = getSourceLanguage(result.langStr) -proc buildLinesHTMLTable(d: PDoc; params: CodeBlockParams, code: string): +proc buildLinesHtmlTable(d: PDoc; params: CodeBlockParams, code: string): tuple[beginTable, endTable: string] = ## Returns the necessary tags to start/end a code block in HTML. ## @@ -922,7 +932,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) = if params.testCmd.len > 0 and d.onTestSnippet != nil: d.onTestSnippet(d, params.filename, params.testCmd, params.status, m.text) - let (blockStart, blockEnd) = buildLinesHTMLTable(d, params, m.text) + let (blockStart, blockEnd) = buildLinesHtmlTable(d, params, m.text) dispA(d.target, result, blockStart, "\\begin{rstpre}\n", []) if params.lang == langNone: |