mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 07:43:26 +00:00
index generation for docgen knows about subdirectories; index knows about enum values; fixes import statement for runnableExamples
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user