diff options
-rw-r--r-- | compiler/aliases.nim | 7 | ||||
-rw-r--r-- | compiler/nimpaths.nim | 2 | ||||
-rw-r--r-- | doc/filters.md | 20 | ||||
-rw-r--r-- | doc/idetools.md | 12 | ||||
-rw-r--r-- | doc/intern.md | 4 | ||||
-rw-r--r-- | doc/manual.md | 32 | ||||
-rw-r--r-- | doc/nimsuggest.md | 8 | ||||
-rw-r--r-- | lib/impure/nre.nim | 28 | ||||
-rw-r--r-- | lib/packages/docutils/rst.nim | 92 | ||||
-rw-r--r-- | lib/packages/docutils/rstast.nim | 2 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 2 | ||||
-rw-r--r-- | lib/pure/algorithm.nim | 8 | ||||
-rw-r--r-- | lib/pure/strformat.nim | 6 | ||||
-rw-r--r-- | lib/std/private/schubfach.nim | 4 | ||||
-rw-r--r-- | tests/stdlib/trst.nim | 136 |
15 files changed, 266 insertions, 97 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim index 9ec72faa4..4b50fdb28 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -77,24 +77,29 @@ proc isPartOf*(a, b: PNode): TAnalysisResult = ## cases: ## ## YES-cases: + ## ``` ## x <| x # for general trees ## x[] <| x ## x[i] <| x ## x.f <| x + ## ``` ## ## NO-cases: + ## ``` ## x !<| y # depending on type and symbol kind ## x[constA] !<| x[constB] ## x.f !<| x.g ## x.f !<| y.f iff x !<= y + ## ``` ## ## MAYBE-cases: ## + ## ``` ## x[] ?<| y[] iff compatible type ## ## ## x[] ?<| y depending on type - ## + ## ``` if a.kind == b.kind: case a.kind of nkSym: diff --git a/compiler/nimpaths.nim b/compiler/nimpaths.nim index c6e188289..3756f956b 100644 --- a/compiler/nimpaths.nim +++ b/compiler/nimpaths.nim @@ -9,7 +9,7 @@ specialpaths is simpler because it doesn't need variables to be relocatable at runtime (eg for use in testament) interpolation variables: - $nimr: such that `$nimr/lib/system.nim` exists (avoids confusion with $nim binary) +: $nimr: such that `$nimr/lib/system.nim` exists (avoids confusion with $nim binary) in compiler, it's obtainable via getPrefixDir(); for other tools (eg koch), this could be getCurrentDir() or getAppFilename().parentDir.parentDir, depending on use case diff --git a/doc/filters.md b/doc/filters.md index cf88724be..bf45788bc 100644 --- a/doc/filters.md +++ b/doc/filters.md @@ -72,10 +72,10 @@ The replace filter replaces substrings in each line. Parameters and their defaults: * `sub: string = ""` - the substring that is searched for + : the substring that is searched for * `by: string = ""` - the string the substring is replaced with + : the string the substring is replaced with Strip filter @@ -87,14 +87,14 @@ each line. Parameters and their defaults: * `startswith: string = ""` - strip only the lines that start with *startswith* (ignoring leading + : strip only the lines that start with *startswith* (ignoring leading whitespace). If empty every line is stripped. * `leading: bool = true` - strip leading whitespace + : strip leading whitespace * `trailing: bool = true` - strip trailing whitespace + : strip trailing whitespace StdTmpl filter @@ -109,19 +109,19 @@ statements need `end X` delimiters. Parameters and their defaults: * `metaChar: char = '#'` - prefix for a line that contains Nim code + : prefix for a line that contains Nim code * `subsChar: char = '$'` - prefix for a Nim expression within a template line + : prefix for a Nim expression within a template line * `conc: string = " & "` - the operation for concatenation + : the operation for concatenation * `emit: string = "result.add"` - the operation to emit a string literal + : the operation to emit a string literal * `toString: string = "$"` - the operation that is applied to each expression + : the operation that is applied to each expression Example:: diff --git a/doc/idetools.md b/doc/idetools.md index 5bfa59442..7c69232e3 100644 --- a/doc/idetools.md +++ b/doc/idetools.md @@ -45,30 +45,30 @@ Or:: nim idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL <switches> proj.nim `proj.nim` - This is the main *project* filename. Most of the time you will +: This is the main *project* filename. Most of the time you will pass in the same as **FILE**, but for bigger projects this is the file which is used as main entry point for the program, the one which users compile to generate a final binary. `<switches>` - This would be any of the other idetools available options, like +: This would be any of the other idetools available options, like `--def` or `--suggest` explained in the following sections. `COL` - An integer with the column you are going to query. For the +: An integer with the column you are going to query. For the compiler columns start at zero, so the first column will be **0** and the last in an 80 column terminal will be **79**. `LINE` - An integer with the line you are going to query. For the compiler +: An integer with the line you are going to query. For the compiler lines start at **1**. `FILE` - The file you want to perform the query on. Usually you will +: The file you want to perform the query on. Usually you will pass in the same value as **proj.nim**. `DIRTY_FILE` - The **FILE** parameter is enough for static analysis, but IDEs +: The **FILE** parameter is enough for static analysis, but IDEs tend to have *unsaved buffers* where the user may still be in the middle of typing a line. In such situations the IDE can save the current contents to a temporary file and then use the diff --git a/doc/intern.md b/doc/intern.md index 08de0edd6..71d695e7d 100644 --- a/doc/intern.md +++ b/doc/intern.md @@ -398,11 +398,11 @@ Runtime type information programming language: Garbage collection - The old GCs use the RTTI for traversing arbitrary Nim types, but usually +: The old GCs use the RTTI for traversing arbitrary Nim types, but usually only the `marker` field which contains a proc that does the traversal. Complex assignments - Sequences and strings are implemented as +: Sequences and strings are implemented as pointers to resizable buffers, but Nim requires copying for assignments. Apart from RTTI the compiler also generates copy procedures as a specialization. diff --git a/doc/manual.md b/doc/manual.md index 3034bc65f..e236132b0 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -1023,24 +1023,24 @@ Pre-defined integer types These integer types are pre-defined: `int` - the generic signed integer type; its size is platform-dependent and has the +: the generic signed integer type; its size is platform-dependent and has the same size as a pointer. This type should be used in general. An integer literal that has no type suffix is of this type if it is in the range `low(int32)..high(int32)` otherwise the literal's type is `int64`. `int`\ XX - additional signed integer types of XX bits use this naming scheme +: additional signed integer types of XX bits use this naming scheme (example: int16 is a 16-bit wide integer). The current implementation supports `int8`, `int16`, `int32`, `int64`. Literals of these types have the suffix 'iXX. `uint` - the generic `unsigned integer`:idx: type; its size is platform-dependent and +: the generic `unsigned integer`:idx: type; its size is platform-dependent and has the same size as a pointer. An integer literal with the type suffix `'u` is of this type. `uint`\ XX - additional unsigned integer types of XX bits use this naming scheme +: additional unsigned integer types of XX bits use this naming scheme (example: uint16 is a 16-bit wide unsigned integer). The current implementation supports `uint8`, `uint16`, `uint32`, `uint64`. Literals of these types have the suffix 'uXX. @@ -1135,12 +1135,12 @@ Pre-defined floating-point types The following floating-point types are pre-defined: `float` - the generic floating-point type; its size used to be platform-dependent, +: the generic floating-point type; its size used to be platform-dependent, but now it is always mapped to `float64`. This type should be used in general. `float`\ XX - an implementation may define additional floating-point types of XX bits using +: an implementation may define additional floating-point types of XX bits using this naming scheme (example: `float64` is a 64-bit wide float). The current implementation supports `float32` and `float64`. Literals of these types have the suffix 'fXX. @@ -2092,52 +2092,52 @@ that expects a proc of the calling convention `closure`. Nim supports these `calling conventions`:idx:\: `nimcall`:idx: - is the default convention used for a Nim **proc**. It is the +: is the default convention used for a Nim **proc**. It is the same as `fastcall`, but only for C compilers that support `fastcall`. `closure`:idx: - is the default calling convention for a **procedural type** that lacks +: is the default calling convention for a **procedural type** that lacks any pragma annotations. It indicates that the procedure has a hidden implicit parameter (an *environment*). Proc vars that have the calling convention `closure` take up two machine words: One for the proc pointer and another one for the pointer to implicitly passed environment. `stdcall`:idx: - This is the stdcall convention as specified by Microsoft. The generated C +: This is the stdcall convention as specified by Microsoft. The generated C procedure is declared with the `__stdcall` keyword. `cdecl`:idx: - The cdecl convention means that a procedure shall use the same convention +: The cdecl convention means that a procedure shall use the same convention as the C compiler. Under Windows the generated C procedure is declared with the `__cdecl` keyword. `safecall`:idx: - This is the safecall convention as specified by Microsoft. The generated C +: This is the safecall convention as specified by Microsoft. The generated C procedure is declared with the `__safecall` keyword. The word *safe* refers to the fact that all hardware registers shall be pushed to the hardware stack. `inline`:idx: - The inline convention means the caller should not call the procedure, +: The inline convention means the caller should not call the procedure, but inline its code directly. Note that Nim does not inline, but leaves this to the C compiler; it generates `__inline` procedures. This is only a hint for the compiler: it may completely ignore it, and it may inline procedures that are not marked as `inline`. `fastcall`:idx: - Fastcall means different things to different C compilers. One gets whatever +: Fastcall means different things to different C compilers. One gets whatever the C `__fastcall` means. `thiscall`:idx: - This is the thiscall calling convention as specified by Microsoft, used on +: This is the thiscall calling convention as specified by Microsoft, used on C++ class member functions on the x86 architecture. `syscall`:idx: - The syscall convention is the same as `__syscall`:c: in C. It is used for +: The syscall convention is the same as `__syscall`:c: in C. It is used for interrupts. `noconv`:idx: - The generated C code will not have any explicit calling convention and thus +: The generated C code will not have any explicit calling convention and thus use the C compiler's default calling convention. This is needed because Nim's default calling convention for procedures is `fastcall` to improve speed. diff --git a/doc/nimsuggest.md b/doc/nimsuggest.md index f542cab19..bfa423707 100644 --- a/doc/nimsuggest.md +++ b/doc/nimsuggest.md @@ -63,10 +63,10 @@ a location. A query location consists of: ``file.nim`` - This is the name of the module or include file the query refers to. +: This is the name of the module or include file the query refers to. ``dirtyfile.nim`` - This is optional. +: This is optional. The `file` parameter is enough for static analysis, but IDEs tend to have *unsaved buffers* where the user may still be in @@ -77,11 +77,11 @@ a location. A query location consists of: ``line`` - An integer with the line you are going to query. For the compiler +: An integer with the line you are going to query. For the compiler lines start at **1**. ``col`` - An integer with the column you are going to query. For the +: An integer with the column you are going to query. For the compiler columns start at **0**. diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 1012c7c36..738fc39cf 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -75,16 +75,16 @@ type ## comment".` ## ## `pattern: string` - ## the string that was used to create the pattern. For details on how + ## : the string that was used to create the pattern. For details on how ## to write a pattern, please see `the official PCRE pattern ## documentation. ## <https://www.pcre.org/original/doc/html/pcrepattern.html>`_ ## ## `captureCount: int` - ## the number of captures that the pattern has. + ## : the number of captures that the pattern has. ## ## `captureNameId: Table[string, int]` - ## a table from the capture names to their numeric id. + ## : a table from the capture names to their numeric id. ## ## ## Options @@ -151,36 +151,36 @@ type ## execution. On failure, it is none, on success, it is some. ## ## `pattern: Regex` - ## the pattern that is being matched + ## : the pattern that is being matched ## ## `str: string` - ## the string that was matched against + ## : the string that was matched against ## ## `captures[]: string` - ## the string value of whatever was captured at that id. If the value + ## : the string value of whatever was captured at that id. If the value ## is invalid, then behavior is undefined. If the id is `-1`, then ## the whole match is returned. If the given capture was not matched, ## `nil` is returned. See examples for `match`. ## ## `captureBounds[]: HSlice[int, int]` - ## gets the bounds of the given capture according to the same rules as + ## : gets the bounds of the given capture according to the same rules as ## the above. If the capture is not filled, then `None` is returned. ## The bounds are both inclusive. See examples for `match`. ## ## `match: string` - ## the full text of the match. + ## : the full text of the match. ## ## `matchBounds: HSlice[int, int]` - ## the bounds of the match, as in `captureBounds[]` + ## : the bounds of the match, as in `captureBounds[]` ## ## `(captureBounds|captures).toTable` - ## returns a table with each named capture as a key. + ## : returns a table with each named capture as a key. ## ## `(captureBounds|captures).toSeq` - ## returns all the captures by their number. + ## : returns all the captures by their number. ## ## `$: string` - ## same as `match` + ## : same as `match` pattern*: Regex ## The regex doing the matching. ## Not nil. str*: string ## The string that was matched against. @@ -583,11 +583,11 @@ proc find*(str: string, pattern: Regex, start = 0, endpos = int.high): Option[Re ## positions. ## ## `start` - ## The start point at which to start matching. `|abc` is `0`; + ## : The start point at which to start matching. `|abc` is `0`; ## `a|bc` is `1` ## ## `endpos` - ## The maximum index for a match; `int.high` means the end of the + ## : The maximum index for a match; `int.high` means the end of the ## string, otherwise it’s an inclusive upper bound. return str.matchImpl(pattern, start, endpos, 0) diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 0a997ecba..629245b4b 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -2064,7 +2064,22 @@ proc getWrappableIndent(p: RstParser): int = elif nextIndent >= currentTok(p).col: # may be a definition list [case.2] result = currentTok(p).col else: - result = nextIndent # [case.3] + result = nextIndent # allow parsing next lines [case.3] + +proc getMdBlockIndent(p: RstParser): int = + ## Markdown version of `getWrappableIndent`. + if currentTok(p).kind == tkIndent: + result = currentTok(p).ival + else: + var nextIndent = p.tok[tokenAfterNewline(p)-1].ival + # TODO: Markdown-compliant definition should allow nextIndent == currInd(p): + if nextIndent <= currInd(p): # parse only this line + result = currentTok(p).col + else: + result = nextIndent # allow parsing next lines [case.3] + +template isRst(p: RstParser): bool = roPreferMarkdown notin p.s.options +template isMd(p: RstParser): bool = roPreferMarkdown in p.s.options proc parseField(p: var RstParser): PRstNode = ## Returns a parsed rnField node. @@ -2309,6 +2324,39 @@ proc isDefList(p: RstParser): bool = p.tok[j].kind in {tkWord, tkOther, tkPunct} and p.tok[j - 2].symbol != "::" +proc `$`(t: Token): string = # for debugging only + result = "(" & $t.kind & " line=" & $t.line & " col=" & $t.col + if t.kind == tkIndent: result = result & " ival=" & $t.ival & ")" + else: result = result & " symbol=" & t.symbol & ")" + +proc skipNewlines(p: RstParser, j: int): int = + result = j + while p.tok[result].kind != tkEof and p.tok[result].kind == tkIndent: + inc result # skip blank lines + +proc skipNewlines(p: var RstParser) = + p.idx = skipNewlines(p, p.idx) + +const maxMdRelInd = 3 ## In Markdown: maximum indentation that does not yet + ## make the indented block a code + +proc isMdRelInd(outerInd, nestedInd: int): bool = + result = outerInd <= nestedInd and nestedInd <= outerInd + maxMdRelInd + +proc isMdDefBody(p: RstParser, j: int, termCol: int): bool = + let defCol = p.tok[j].col + result = p.tok[j].symbol == ":" and + isMdRelInd(termCol, defCol) and + p.tok[j+1].kind == tkWhite and + p.tok[j+2].kind in {tkWord, tkOther, tkPunct} + +proc isMdDefListItem(p: RstParser, idx: int): bool = + var j = tokenAfterNewline(p, idx) + j = skipNewlines(p, j) + let termCol = p.tok[j].col + result = isMdRelInd(currInd(p), termCol) and + isMdDefBody(p, j, termCol) + proc isOptionList(p: RstParser): bool = result = match(p, p.idx, "-w") or match(p, p.idx, "--w") or match(p, p.idx, "/w") or match(p, p.idx, "//w") @@ -2381,8 +2429,10 @@ proc whichSection(p: RstParser): RstNodeKind = result = rnEnumList elif isOptionList(p): result = rnOptionList - elif isDefList(p): + elif isRst(p) and isDefList(p): result = rnDefList + elif isMd(p) and isMdDefListItem(p, p.idx): + result = rnMdDefList else: result = rnParagraph of tkWord, tkOther, tkWhite: @@ -2391,7 +2441,9 @@ proc whichSection(p: RstParser): RstNodeKind = if isAdornmentHeadline(p, tokIdx): result = rnHeadline else: result = rnParagraph elif match(p, p.idx, "e) ") or match(p, p.idx, "e. "): result = rnEnumList - elif isDefList(p): result = rnDefList + elif isRst(p) and isDefList(p): result = rnDefList + elif isMd(p) and isMdDefListItem(p, p.idx): + result = rnMdDefList else: result = rnParagraph else: result = rnLeaf @@ -2921,6 +2973,36 @@ proc parseOptionList(p: var RstParser): PRstNode = if currentTok(p).kind != tkEof: dec p.idx # back to tkIndent break +proc parseMdDefinitionList(p: var RstParser): PRstNode = + ## Parses (Pandoc/kramdown/PHPextra) Mardkown definition lists. + result = newRstNodeA(p, rnMdDefList) + let termCol = currentTok(p).col + while true: + var item = newRstNode(rnDefItem) + var term = newRstNode(rnDefName) + parseLine(p, term) + skipNewlines(p) + inc p.idx, 2 # skip ":" and space + item.add(term) + while true: + var def = newRstNode(rnDefBody) + let indent = getMdBlockIndent(p) + pushInd(p, indent) + parseSection(p, def) + popInd(p) + item.add(def) + let j = skipNewlines(p, p.idx) + if isMdDefBody(p, j, termCol): # parse next definition body + p.idx = j + 2 # skip ":" and space + else: + break + result.add(item) + let j = skipNewlines(p, p.idx) + if p.tok[j].col == termCol and isMdDefListItem(p, j): + p.idx = j # parse next item + else: + break + proc parseDefinitionList(p: var RstParser): PRstNode = result = nil var j = tokenAfterNewline(p) - 1 @@ -3094,6 +3176,7 @@ proc parseSection(p: var RstParser, result: PRstNode) = of rnLeaf: rstMessage(p, meNewSectionExpected, "(syntax error)") of rnParagraph: discard of rnDefList: a = parseDefinitionList(p) + of rnMdDefList: a = parseMdDefinitionList(p) of rnFieldList: if p.idx > 0: dec p.idx a = parseFields(p) @@ -3120,9 +3203,6 @@ proc parseSectionWrapper(p: var RstParser): PRstNode = while result.kind == rnInner and result.len == 1: result = result.sons[0] -proc `$`(t: Token): string = - result = $t.kind & ' ' & t.symbol - proc parseDoc(p: var RstParser): PRstNode = result = parseSectionWrapper(p) if currentTok(p).kind != tkEof: diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim index 05e4ec39e..e85bbfb98 100644 --- a/lib/packages/docutils/rstast.nim +++ b/lib/packages/docutils/rstast.nim @@ -27,7 +27,7 @@ type rnBulletItem, # a bullet item rnEnumList, # an enumerated list rnEnumItem, # an enumerated item - rnDefList, # a definition list + rnDefList, rnMdDefList, # a definition list (RST/Markdown) rnDefItem, # an item of a definition list consisting of ... rnDefName, # ... a name part ... rnDefBody, # ... and a body part ... diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 1b5f9e78c..f5ff9aa03 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -1212,7 +1212,7 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) = of rnBulletItem, rnEnumItem: renderAux(d, n, "<li$2>$1</li>\n", "\\item $2$1\n", result) of rnEnumList: renderEnumList(d, n, result) - of rnDefList: + of rnDefList, rnMdDefList: renderAux(d, n, "<dl$2 class=\"docutils\">$1</dl>\n", "\\begin{description}\n$2\n$1\\end{description}\n", result) of rnDefItem: renderAux(d, n, result) diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index c43545f78..fc0eceac3 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -825,10 +825,10 @@ proc rotateLeft*[T](arg: var openArray[T]; slice: HSlice[int, int]; ## If an invalid range (`HSlice`) is passed, it raises `IndexDefect`. ## ## `slice` - ## The indices of the element range that should be rotated. + ## : The indices of the element range that should be rotated. ## ## `dist` - ## The distance in amount of elements that the data should be rotated. + ## : The distance in amount of elements that the data should be rotated. ## Can be negative, can be any number. ## ## **See also:** @@ -876,10 +876,10 @@ proc rotatedLeft*[T](arg: openArray[T]; slice: HSlice[int, int], ## If an invalid range (`HSlice`) is passed, it raises `IndexDefect`. ## ## `slice` - ## The indices of the element range that should be rotated. + ## : The indices of the element range that should be rotated. ## ## `dist` - ## The distance in amount of elements that the data should be rotated. + ## : The distance in amount of elements that the data should be rotated. ## Can be negative, can be any number. ## ## **See also:** diff --git a/lib/pure/strformat.nim b/lib/pure/strformat.nim index 247d0a296..fe3cfdab0 100644 --- a/lib/pure/strformat.nim +++ b/lib/pure/strformat.nim @@ -180,15 +180,15 @@ The square brackets `[]` indicate an optional element. The optional `align` flag can be one of the following: `<` - Forces the field to be left-aligned within the available +: Forces the field to be left-aligned within the available space. (This is the default for strings.) `>` - Forces the field to be right-aligned within the available space. +: Forces the field to be right-aligned within the available space. (This is the default for numbers.) `^` - Forces the field to be centered within the available space. +: Forces the field to be centered within the available space. Note that unless a minimum field width is defined, the field width will always be the same size as the data to fill it, so that the alignment diff --git a/lib/std/private/schubfach.nim b/lib/std/private/schubfach.nim index 206153a68..872317ebf 100644 --- a/lib/std/private/schubfach.nim +++ b/lib/std/private/schubfach.nim @@ -78,19 +78,23 @@ proc floorDivPow2(x: int32; n: int32): int32 {.inline.} = return x shr n ## Returns floor(log_10(2^e)) +## ```c ## static inline int32_t FloorLog10Pow2(int32_t e) ## { ## SF_ASSERT(e >= -1500); ## SF_ASSERT(e <= 1500); ## return FloorDivPow2(e * 1262611, 22); ## } +## ``` ## Returns floor(log_10(3/4 2^e)) +## ```c ## static inline int32_t FloorLog10ThreeQuartersPow2(int32_t e) ## { ## SF_ASSERT(e >= -1500); ## SF_ASSERT(e <= 1500); ## return FloorDivPow2(e * 1262611 - 524031, 22); ## } +## ``` ## Returns floor(log_2(10^e)) proc floorLog2Pow10(e: int32): int32 {.inline.} = diff --git a/tests/stdlib/trst.nim b/tests/stdlib/trst.nim index f9150e02d..a92ab2daa 100644 --- a/tests/stdlib/trst.nim +++ b/tests/stdlib/trst.nim @@ -423,21 +423,21 @@ suite "RST parsing": .. Note:: deflist: >> quote continuation - """.toAst == expected) + """.toAst(rstOptions = preferRst) == expected) check(dedent""" .. Note:: deflist: >> quote continuation - """.toAst == expected) + """.toAst(rstOptions = preferRst) == expected) check(dedent""" .. Note:: deflist: >> quote >> continuation - """.toAst == expected) + """.toAst(rstOptions = preferRst) == expected) # spaces are not significant between `>`: check(dedent""" @@ -445,7 +445,7 @@ suite "RST parsing": deflist: > > quote > > continuation - """.toAst == expected) + """.toAst(rstOptions = preferRst) == expected) test "Markdown quoted blocks: de-indent handled well": check(dedent""" @@ -616,27 +616,28 @@ suite "RST parsing": check inputTilde.toAst == expected test "option list has priority over definition list": - check(dedent""" - --defusages - file - -o set - """.toAst == - dedent""" - rnOptionList - rnOptionListItem order=1 - rnOptionGroup - rnLeaf '--' - rnLeaf 'defusages' - rnDescription - rnInner - rnLeaf 'file' - rnOptionListItem order=2 - rnOptionGroup - rnLeaf '-' - rnLeaf 'o' - rnDescription - rnLeaf 'set' - """) + for opt in [preferMarkdown, preferRst]: + check(dedent""" + --defusages + file + -o set + """.toAst(rstOptions = opt) == + dedent""" + rnOptionList + rnOptionListItem order=1 + rnOptionGroup + rnLeaf '--' + rnLeaf 'defusages' + rnDescription + rnInner + rnLeaf 'file' + rnOptionListItem order=2 + rnOptionGroup + rnLeaf '-' + rnLeaf 'o' + rnDescription + rnLeaf 'set' + """) test "items of 1 option list can be separated by blank lines": check(dedent""" @@ -660,13 +661,13 @@ suite "RST parsing": rnLeaf 'desc2' """) - test "option list has priority over definition list": + test "definition list does not gobble up the following blocks": check(dedent""" defName defBody -b desc2 - """.toAst == + """.toAst(rstOptions = preferRst) == dedent""" rnInner rnDefList @@ -1054,7 +1055,7 @@ suite "RST indentation": term2 Definition2 """ - check(input.toAst == dedent""" + check(input.toAst(rstOptions = preferRst) == dedent""" rnEnumList labelFmt=1) rnEnumItem rnAdmonition adType=hint @@ -1157,6 +1158,85 @@ suite "RST indentation": # "template..." should be parsed as a definition list attached to ":test:": check inputWrong.toAst != ast + test "Markdown definition lists work in conjunction with bullet lists": + check(dedent""" + * some term + : the definition + + Paragraph.""".toAst == + dedent""" + rnInner + rnBulletList + rnBulletItem + rnMdDefList + rnDefItem + rnDefName + rnLeaf 'some' + rnLeaf ' ' + rnLeaf 'term' + rnDefBody + rnInner + rnLeaf 'the' + rnLeaf ' ' + rnLeaf 'definition' + rnParagraph + rnLeaf 'Paragraph' + rnLeaf '.' + """) + + test "Markdown definition lists work with blank lines and extra paragraphs": + check(dedent""" + Term1 + + : Definition1 + + Term2 *inline markup* + + : Definition2 + + Paragraph2 + + Term3 + : * point1 + * point2 + : term3definition2 + """.toAst == dedent""" + rnMdDefList + rnDefItem + rnDefName + rnLeaf 'Term1' + rnDefBody + rnInner + rnLeaf 'Definition1' + rnDefItem + rnDefName + rnLeaf 'Term2' + rnLeaf ' ' + rnEmphasis + rnLeaf 'inline' + rnLeaf ' ' + rnLeaf 'markup' + rnDefBody + rnParagraph + rnLeaf 'Definition2' + rnParagraph + rnLeaf 'Paragraph2' + rnDefItem + rnDefName + rnLeaf 'Term3' + rnDefBody + rnBulletList + rnBulletItem + rnInner + rnLeaf 'point1' + rnBulletItem + rnInner + rnLeaf 'point2' + rnDefBody + rnInner + rnLeaf 'term3definition2' + """) + suite "Warnings": test "warnings for broken footnotes/links/substitutions": let input = dedent""" |