Source Edit

This module implements a reStructuredText (RST) and Markdown parser. User’s manual on supported markup syntax and command line usage can be found in Nim-flavored Markdown and reStructuredText.

Choice between Markdown and RST as well as optional additional features are turned on by passing options: RstParseOptions to proc rstParse.

Imports

os, strutils, rstast, dochelpers, enumutils, algorithm, lists, sequtils, miscdollars, tables, strscans, rstidx, highlite

Types

  1. EParseError = object of ValueError

Source Edit

  1. FindFileHandler = proc (filename: string): string {.closure, ...gcsafe.}

Source Edit

  1. FindRefFileHandler = proc (targetRelPath: string): tuple[targetPath: string,
  2. linkRelPath: string] {.closure, ...gcsafe.}

returns where .html or .idx file should be found by its relative path; linkRelPath is a prefix to be added before a link anchor from such file Source Edit

  1. MsgClass = enum
  2. mcHint = "Hint", mcWarning = "Warning", mcError = "Error"

Source Edit

  1. MsgHandler = proc (filename: string; line, col: int; msgKind: MsgKind;
  2. arg: string) {.closure, ...gcsafe.}

what to do in case of an error Source Edit

  1. MsgKind = enum
  2. meCannotOpenFile = "cannot open \'$1\'", meExpected = "\'$1\' expected",
  3. meMissingClosing = "$1",
  4. meGridTableNotImplemented = "grid table is not implemented",
  5. meMarkdownIllformedTable = "illformed delimiter row of a Markdown table",
  6. meIllformedTable = "Illformed table: $1",
  7. meNewSectionExpected = "new section expected $1",
  8. meGeneralParseError = "general parse error",
  9. meInvalidDirective = "invalid directive: \'$1\'",
  10. meInvalidField = "invalid field: $1",
  11. meFootnoteMismatch = "mismatch in number of footnotes and their refs: $1",
  12. mwRedefinitionOfLabel = "redefinition of label \'$1\'",
  13. mwUnknownSubstitution = "unknown substitution \'$1\'",
  14. mwAmbiguousLink = "ambiguous doc link $1",
  15. mwBrokenLink = "broken link \'$1\'",
  16. mwUnsupportedLanguage = "language \'$1\' not supported",
  17. mwUnsupportedField = "field \'$1\' not supported",
  18. mwRstStyle = "RST style: $1",
  19. mwUnusedImportdoc = "importdoc for \'$1\' is not used",
  20. meSandboxedDirective = "disabled directive: \'$1\'"

the possible messages Source Edit

  1. PRstSharedState = ref RstSharedState

Source Edit

  1. RstFileTable = object
  2. filenameToIdx*: Table[string, FileIndex]
  3. idxToFilename*: seq[string]

Source Edit

  1. RstParseOption = enum
  2. roSupportSmilies, ## make the RST parser support smilies like ``:)``
  3. roSupportRawDirective, ## support the ``raw`` directive (don't support
  4. ## it for sandboxing)
  5. roSupportMarkdown, ## support additional features of Markdown
  6. roPreferMarkdown, ## parse as Markdown (keeping RST as "extension"
  7. ## to Markdown) -- implies `roSupportMarkdown`
  8. roNimFile, ## set for Nim files where default interpreted
  9. ## text role should be :nim:
  10. roSandboxDisabled ## this option enables certain options
  11. ## (e.g. raw, include, importdoc)
  12. ## which are disabled by default as they can
  13. ## enable users to read arbitrary data and
  14. ## perform XSS if the parser is used in a web
  15. ## app.

options for the RST parser Source Edit

  1. RstParseOptions = set[RstParseOption]

Source Edit

Consts

  1. ColRstInit = 0

Initial column number for standalone RST text (Nim global reporting adds ColOffset=1) Source Edit

  1. ColRstOffset = 1

1: a replica of ColOffset for internal use Source Edit

  1. LineRstInit = 1

Initial line number for standalone RST text Source Edit

Procs

  1. proc addAnchorNim(s: var PRstSharedState; external: bool; refn: string;
  2. tooltip: string; langSym: LangSymbol; priority: int;
  3. info: TLineInfo; module: FileIndex) {....raises: [], tags: [],
  4. forbids: [].}

Adds an anchor refn, which follows the rule arNim (i.e. a symbol in *.nim file) Source Edit

  1. proc addFilename(s: PRstSharedState; file1: string): FileIndex {....raises: [],
  2. tags: [], forbids: [].}

Returns index of filename, adding it if it has not been used before Source Edit

  1. proc addNodes(n: PRstNode): string {....raises: [], tags: [], forbids: [].}

Source Edit

  1. proc completePass2(s: PRstSharedState) {....raises: [ValueError, Exception],
  2. tags: [RootEffect], forbids: [].}

Source Edit

  1. proc defaultFindFile(filename: string): string {....raises: [],
  2. tags: [ReadDirEffect], forbids: [].}

Source Edit

  1. proc defaultFindRefFile(filename: string): (string, string) {....raises: [],
  2. tags: [], forbids: [].}

Source Edit

  1. proc defaultMsgHandler(filename: string; line, col: int; msgkind: MsgKind;
  2. arg: string) {....raises: [ValueError, EParseError, IOError],
  3. tags: [WriteIOEffect], forbids: [].}

Source Edit

  1. proc getArgument(n: PRstNode): string {....raises: [], tags: [], forbids: [].}

Source Edit

  1. proc getFieldValue(n: PRstNode): string {....raises: [], tags: [], forbids: [].}

Returns the value of a specific rnField node.

This proc will assert if the node is not of the expected type. The empty string will be returned as a minimum. Any value in the rst will be stripped form leading/trailing whitespace.

Source Edit

  1. proc getFieldValue(n: PRstNode; fieldname: string): string {....gcsafe, raises: [],
  2. tags: [], forbids: [].}

Source Edit

  1. proc newRstSharedState(options: RstParseOptions; filename: string;
  2. findFile: FindFileHandler;
  3. findRefFile: FindRefFileHandler; msgHandler: MsgHandler;
  4. hasToc: bool): PRstSharedState {....raises: [], tags: [],
  5. forbids: [].}

Source Edit

  1. proc preparePass2(s: var PRstSharedState; mainNode: PRstNode; importdoc = true) {.
  2. ...raises: [Exception, ValueError, KeyError], tags: [RootEffect, ReadIOEffect],
  3. forbids: [].}

Records titles in node mainNode and orders footnotes. Source Edit

  1. proc resolveSubs(s: PRstSharedState; n: PRstNode): PRstNode {.
  2. ...raises: [ValueError, Exception, KeyError],
  3. tags: [ReadEnvEffect, RootEffect], forbids: [].}

Makes pass 2 of RST parsing. Resolves substitutions and anchor aliases, groups footnotes. Takes input node n and returns the same node with recursive substitutions in n.sons to result. Source Edit

  1. proc rstMessage(filenames: RstFileTable; f: MsgHandler; info: TLineInfo;
  2. msgKind: MsgKind; arg: string) {.
  3. ...raises: [ValueError, Exception], tags: [RootEffect], forbids: [].}

Print warnings using info, i.e. in 2nd-pass warnings for footnotes/substitutions/references or from rstgen.nim. Source Edit

  1. proc rstnodeToRefname(n: PRstNode): string {....raises: [], tags: [], forbids: [].}

Source Edit

  1. proc rstParse(text, filename: string; line, column: int;
  2. options: RstParseOptions; findFile: FindFileHandler = nil;
  3. findRefFile: FindRefFileHandler = nil;
  4. msgHandler: MsgHandler = nil): tuple[node: PRstNode,
  5. filenames: RstFileTable, hasToc: bool] {.
  6. ...raises: [Exception, ValueError, IOError, KeyError],
  7. tags: [RootEffect, ReadDirEffect, ReadIOEffect, ReadEnvEffect], forbids: [].}

Parses the whole text. The result is ready for rstgen.renderRstToOut, note that 2nd tuple element should be fed to initRstGenerator argument filenames (it is being filled here at least with filename and possibly with other files from RST .. include:: statement). Source Edit

  1. proc rstParsePass1(fragment: string; line, column: int;
  2. sharedState: PRstSharedState): PRstNode {.
  3. ...raises: [Exception, ValueError, IOError],
  4. tags: [RootEffect, ReadDirEffect, ReadIOEffect], forbids: [].}

Parses an RST fragment. The result should be further processed by preparePass2 and resolveSubs (which is pass 2). Source Edit

  1. proc safeProtocol(linkStr: var string): string {....raises: [], tags: [],
  2. forbids: [].}

Source Edit

  1. proc setCurrFilename(s: PRstSharedState; file1: string) {....raises: [], tags: [],
  2. forbids: [].}

Source Edit

  1. proc whichMsgClass(k: MsgKind): MsgClass {....raises: [], tags: [], forbids: [].}

returns which message class k belongs to. Source Edit