123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983 |
- discard """
- output: '''
- [Suite] RST parsing
- [Suite] RST tables
- [Suite] RST indentation
- [Suite] Markdown indentation
- [Suite] Warnings
- [Suite] RST include directive
- [Suite] RST escaping
- [Suite] RST inline markup
- '''
- matrix: "--mm:refc; --mm:orc"
- """
- # tests for rst module
- import ../../lib/packages/docutils/[rstgen, rst, rstast]
- import unittest, strutils
- import std/private/miscdollars
- import os
- import std/[assertions, syncio]
- const preferMarkdown = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
- # legacy nimforum / old default mode:
- const preferRst = {roSupportMarkdown, roNimFile, roSandboxDisabled}
- const pureRst = {roNimFile, roSandboxDisabled}
- proc toAst(input: string,
- rstOptions: RstParseOptions = preferMarkdown,
- error: ref string = nil,
- warnings: ref seq[string] = nil): string =
- ## If `error` is nil then no errors should be generated.
- ## The same goes for `warnings`.
- proc testMsgHandler(filename: string, line, col: int, msgkind: MsgKind,
- arg: string) =
- let mc = msgkind.whichMsgClass
- let a = $msgkind % arg
- var message: string
- toLocation(message, filename, line, col + ColRstOffset)
- message.add " $1: $2" % [$mc, a]
- if mc == mcError:
- if error == nil:
- raise newException(EParseError, "[unexpected error] " & message)
- error[] = message
- # we check only first error because subsequent ones may be meaningless
- raise newException(EParseError, "")
- else:
- doAssert warnings != nil, "unexpected RST warning '" & message & "'"
- warnings[].add message
- try:
- const filen = "input"
- proc myFindFile(filename: string): string =
- # we don't find any files in online mode:
- result = ""
- var (rst, _, _) = rstParse(input, filen, line=LineRstInit, column=ColRstInit,
- rstOptions, myFindFile, nil, testMsgHandler)
- result = treeRepr(rst)
- except EParseError as e:
- if e.msg != "":
- result = e.msg
- suite "RST parsing":
- test "Standalone punctuation is not parsed as heading overlines":
- check(dedent"""
- Paragraph
- !""".toAst ==
- dedent"""
- rnInner
- rnParagraph
- rnLeaf 'Paragraph'
- rnParagraph
- rnLeaf '!'
- """)
- check(dedent"""
- Paragraph1
- ...
- Paragraph2""".toAst ==
- dedent"""
- rnInner
- rnParagraph
- rnLeaf 'Paragraph1'
- rnParagraph
- rnLeaf '...'
- rnParagraph
- rnLeaf 'Paragraph2'
- """)
- check(dedent"""
- ---
- Paragraph""".toAst ==
- dedent"""
- rnInner
- rnLeaf '---'
- rnLeaf ' '
- rnLeaf 'Paragraph'
- """)
- test "References are whitespace-neutral and case-insensitive":
- # refname is 'lexical-analysis', the same for all the 3 variants:
- check(dedent"""
- Lexical Analysis
- ================
- Ref. `Lexical Analysis`_ or `Lexical analysis`_ or `lexical analysis`_.
- """.toAst ==
- dedent"""
- rnInner
- rnHeadline level=1 anchor='lexical-analysis'
- rnLeaf 'Lexical'
- rnLeaf ' '
- rnLeaf 'Analysis'
- rnParagraph
- rnLeaf 'Ref'
- rnLeaf '.'
- rnLeaf ' '
- rnInternalRef
- rnInner
- rnLeaf 'Lexical'
- rnLeaf ' '
- rnLeaf 'Analysis'
- rnLeaf 'lexical-analysis'
- rnLeaf ' '
- rnLeaf 'or'
- rnLeaf ' '
- rnInternalRef
- rnInner
- rnLeaf 'Lexical'
- rnLeaf ' '
- rnLeaf 'analysis'
- rnLeaf 'lexical-analysis'
- rnLeaf ' '
- rnLeaf 'or'
- rnLeaf ' '
- rnInternalRef
- rnInner
- rnLeaf 'lexical'
- rnLeaf ' '
- rnLeaf 'analysis'
- rnLeaf 'lexical-analysis'
- rnLeaf '.'
- rnLeaf ' '
- """)
- test "RST quoted literal blocks":
- let expected =
- dedent"""
- rnInner
- rnLeaf 'Paragraph'
- rnLeaf ':'
- rnLiteralBlock
- rnLeaf '>x'
- """
- check(dedent"""
- Paragraph::
- >x""".toAst(rstOptions = preferRst) == expected)
- check(dedent"""
- Paragraph::
- >x""".toAst(rstOptions = preferRst) == expected)
- test "RST quoted literal blocks, :: at a separate line":
- let expected =
- dedent"""
- rnInner
- rnInner
- rnLeaf 'Paragraph'
- rnLiteralBlock
- rnLeaf '>x
- >>y'
- """
- check(dedent"""
- Paragraph
- ::
- >x
- >>y""".toAst(rstOptions = preferRst) == expected)
- check(dedent"""
- Paragraph
- ::
- >x
- >>y""".toAst(rstOptions = preferRst) == expected)
- test "Markdown quoted blocks":
- check(dedent"""
- Paragraph.
- >x""".toAst ==
- dedent"""
- rnInner
- rnLeaf 'Paragraph'
- rnLeaf '.'
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnLeaf 'x'
- """)
- # bug #17987
- check(dedent"""
- foo https://github.com/nim-lang/Nim/issues/8258
- > bar""".toAst ==
- dedent"""
- rnInner
- rnInner
- rnLeaf 'foo'
- rnLeaf ' '
- rnStandaloneHyperlink
- rnLeaf 'https://github.com/nim-lang/Nim/issues/8258'
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnLeaf 'bar'
- """)
- let expected = dedent"""
- rnInner
- rnLeaf 'Paragraph'
- rnLeaf '.'
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnInner
- rnLeaf 'x1'
- rnLeaf ' '
- rnLeaf 'x2'
- rnMarkdownBlockQuoteItem quotationDepth=2
- rnInner
- rnLeaf 'y1'
- rnLeaf ' '
- rnLeaf 'y2'
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnLeaf 'z'
- """
- check(dedent"""
- Paragraph.
- >x1 x2
- >>y1 y2
- >z""".toAst == expected)
- check(dedent"""
- Paragraph.
- > x1 x2
- >> y1 y2
- > z""".toAst == expected)
- check(dedent"""
- >x
- >y
- >z""".toAst ==
- dedent"""
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnInner
- rnLeaf 'x'
- rnLeaf ' '
- rnLeaf 'y'
- rnLeaf ' '
- rnLeaf 'z'
- """)
- check(dedent"""
- > z
- > > >y
- """.toAst ==
- dedent"""
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnLeaf 'z'
- rnMarkdownBlockQuoteItem quotationDepth=3
- rnLeaf 'y'
- """)
- test "Markdown quoted blocks: lazy":
- let expected = dedent"""
- rnInner
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=2
- rnInner
- rnLeaf 'x'
- rnLeaf ' '
- rnLeaf 'continuation1'
- rnLeaf ' '
- rnLeaf 'continuation2'
- rnParagraph
- rnLeaf 'newParagraph'
- """
- check(dedent"""
- >>x
- continuation1
- continuation2
- newParagraph""".toAst == expected)
- check(dedent"""
- >> x
- continuation1
- continuation2
- newParagraph""".toAst == expected)
- # however mixing more than 1 non-lazy line and lazy one(s) splits quote
- # in our parser, which appeared the easiest way to handle such cases:
- var warnings = new seq[string]
- check(dedent"""
- >> x
- >> continuation1
- continuation2
- newParagraph""".toAst(warnings=warnings) ==
- dedent"""
- rnInner
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=2
- rnLeaf 'x'
- rnMarkdownBlockQuoteItem quotationDepth=2
- rnInner
- rnLeaf 'continuation1'
- rnLeaf ' '
- rnLeaf 'continuation2'
- rnParagraph
- rnLeaf 'newParagraph'
- """)
- check(warnings[] == @[
- "input(2, 1) Warning: RST style: two or more quoted lines " &
- "are followed by unquoted line 3"])
- test "Markdown quoted blocks: not lazy":
- # here is where we deviate from CommonMark specification: 'bar' below is
- # not considered as continuation of 2-level '>> foo' quote.
- check(dedent"""
- >>> foo
- > bar
- >> baz
- """.toAst() ==
- dedent"""
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=3
- rnLeaf 'foo'
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnLeaf 'bar'
- rnMarkdownBlockQuoteItem quotationDepth=2
- rnLeaf 'baz'
- """)
- test "Markdown quoted blocks: inline markup works":
- check(dedent"""
- > hi **bold** text
- """.toAst == dedent"""
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnInner
- rnLeaf 'hi'
- rnLeaf ' '
- rnStrongEmphasis
- rnLeaf 'bold'
- rnLeaf ' '
- rnLeaf 'text'
- """)
- test "Markdown quoted blocks: blank line separator":
- let expected = dedent"""
- rnInner
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnInner
- rnLeaf 'x'
- rnLeaf ' '
- rnLeaf 'y'
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnInner
- rnLeaf 'z'
- rnLeaf ' '
- rnLeaf 't'
- """
- check(dedent"""
- >x
- >y
- > z
- > t""".toAst == expected)
- check(dedent"""
- >x
- y
- > z
- t""".toAst == expected)
- test "Markdown quoted blocks: nested body blocks/elements work #1":
- let expected = dedent"""
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnBulletList
- rnBulletItem
- rnInner
- rnLeaf 'x'
- rnBulletItem
- rnInner
- rnLeaf 'y'
- """
- check(dedent"""
- > - x
- - y
- """.toAst == expected)
- # TODO: if bug #17340 point 28 is resolved then this may work:
- # check(dedent"""
- # > - x
- # - y
- # """.toAst == expected)
- check(dedent"""
- > - x
- > - y
- """.toAst == expected)
- check(dedent"""
- >
- > - x
- >
- > - y
- >
- """.toAst == expected)
- test "Markdown quoted blocks: nested body blocks/elements work #2":
- let expected = dedent"""
- rnAdmonition adType=note
- [nil]
- [nil]
- rnDefList
- rnDefItem
- rnDefName
- rnLeaf 'deflist'
- rnLeaf ':'
- rnDefBody
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=2
- rnInner
- rnLeaf 'quote'
- rnLeaf ' '
- rnLeaf 'continuation'
- """
- check(dedent"""
- .. Note:: deflist:
- >> quote
- continuation
- """.toAst(rstOptions = preferRst) == expected)
- check(dedent"""
- .. Note::
- deflist:
- >> quote
- continuation
- """.toAst(rstOptions = preferRst) == expected)
- check(dedent"""
- .. Note::
- deflist:
- >> quote
- >> continuation
- """.toAst(rstOptions = preferRst) == expected)
- # spaces are not significant between `>`:
- check(dedent"""
- .. Note::
- deflist:
- > > quote
- > > continuation
- """.toAst(rstOptions = preferRst) == expected)
- test "Markdown quoted blocks: de-indent handled well":
- check(dedent"""
- >
- > - x
- > - y
- >
- > Paragraph.
- """.toAst(rstOptions = preferRst) == dedent"""
- rnMarkdownBlockQuote
- rnMarkdownBlockQuoteItem quotationDepth=1
- rnInner
- rnBlockQuote
- rnBulletList
- rnBulletItem
- rnInner
- rnLeaf 'x'
- rnBulletItem
- rnInner
- rnLeaf 'y'
- rnParagraph
- rnLeaf 'Paragraph'
- rnLeaf '.'
- """)
- let expectCodeBlock = dedent"""
- rnCodeBlock
- [nil]
- rnFieldList
- rnField
- rnFieldName
- rnLeaf 'default-language'
- rnFieldBody
- rnLeaf 'Nim'
- rnLiteralBlock
- rnLeaf 'let a = 1
- ```'
- """
- test "Markdown footnotes":
- # Testing also 1) correct order of manually-numbered and automatically-
- # numbered footnotes; 2) no spaces between references (html & 3 below):
- check(dedent"""
- Paragraph [^1] [^html-hyphen][^3] and [^latex]
- [^1]: footnote1
- [^html-hyphen]: footnote2
- continuation2
- [^latex]: footnote4
- [^3]: footnote3
- continuation3
- """.toAst ==
- dedent"""
- rnInner
- rnInner
- rnLeaf 'Paragraph'
- rnLeaf ' '
- rnFootnoteRef
- rnInner
- rnLeaf '1'
- rnLeaf 'footnote-1'
- rnLeaf ' '
- rnFootnoteRef
- rnInner
- rnLeaf '2'
- rnLeaf 'footnote-htmlminushyphen'
- rnFootnoteRef
- rnInner
- rnLeaf '3'
- rnLeaf 'footnote-3'
- rnLeaf ' '
- rnLeaf 'and'
- rnLeaf ' '
- rnFootnoteRef
- rnInner
- rnLeaf '4'
- rnLeaf 'footnote-latex'
- rnFootnoteGroup
- rnFootnote anchor='footnote-1'
- rnInner
- rnLeaf '1'
- rnLeaf 'footnote1'
- rnFootnote anchor='footnote-htmlminushyphen'
- rnInner
- rnLeaf '2'
- rnInner
- rnLeaf 'footnote2'
- rnLeaf ' '
- rnLeaf 'continuation2'
- rnFootnote anchor='footnote-latex'
- rnInner
- rnLeaf '4'
- rnLeaf 'footnote4'
- rnFootnote anchor='footnote-3'
- rnInner
- rnLeaf '3'
- rnInner
- rnLeaf 'footnote3'
- rnLeaf ' '
- rnLeaf 'continuation3'
- """)
- test "Markdown code blocks with more > 3 backticks":
- check(dedent"""
- ````
- let a = 1
- ```
- ````""".toAst == expectCodeBlock)
- test "Markdown code blocks with ~~~":
- check(dedent"""
- ~~~
- let a = 1
- ```
- ~~~""".toAst == expectCodeBlock)
- check(dedent"""
- ~~~~~
- let a = 1
- ```
- ~~~~~""".toAst == expectCodeBlock)
- test "Markdown code blocks with Nim-specific arguments":
- check(dedent"""
- ```nim number-lines=1 test
- let a = 1
- ```""".toAst ==
- dedent"""
- rnCodeBlock
- rnDirArg
- rnLeaf 'nim'
- rnFieldList
- rnField
- rnFieldName
- rnLeaf 'number-lines'
- rnFieldBody
- rnLeaf '1'
- rnField
- rnFieldName
- rnLeaf 'test'
- rnFieldBody
- rnLiteralBlock
- rnLeaf 'let a = 1'
- """)
- check(dedent"""
- ```nim test = "nim c $1" number-lines = 1
- let a = 1
- ```""".toAst ==
- dedent"""
- rnCodeBlock
- rnDirArg
- rnLeaf 'nim'
- rnFieldList
- rnField
- rnFieldName
- rnLeaf 'test'
- rnFieldBody
- rnLeaf '"nim c $1"'
- rnField
- rnFieldName
- rnLeaf 'number-lines'
- rnFieldBody
- rnLeaf '1'
- rnLiteralBlock
- rnLeaf 'let a = 1'
- """)
- test "additional indentation < 4 spaces is handled fine":
- check(dedent"""
- Indentation
- ```nim
- let a = 1
- ```""".toAst ==
- dedent"""
- rnInner
- rnParagraph
- rnLeaf 'Indentation'
- rnParagraph
- rnCodeBlock
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf ' let a = 1'
- """)
- # | |
- # | \ indentation of exactly two spaces before 'let a = 1'
- test "no blank line is required before or after Markdown code block":
- let inputBacktick = dedent"""
- Some text
- ```
- CodeBlock()
- ```
- Other text"""
- let inputTilde = dedent"""
- Some text
- ~~~~~~~~~
- CodeBlock()
- ~~~~~~~~~
- Other text"""
- let expected = dedent"""
- rnInner
- rnParagraph
- rnLeaf 'Some'
- rnLeaf ' '
- rnLeaf 'text'
- rnParagraph
- rnCodeBlock
- [nil]
- rnFieldList
- rnField
- rnFieldName
- rnLeaf 'default-language'
- rnFieldBody
- rnLeaf 'Nim'
- rnLiteralBlock
- rnLeaf 'CodeBlock()'
- rnLeaf ' '
- rnLeaf 'Other'
- rnLeaf ' '
- rnLeaf 'text'
- """
- check inputBacktick.toAst == expected
- check inputTilde.toAst == expected
- test "option list has priority over definition list":
- 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"""
- -a desc1
- -b desc2
- """.toAst ==
- dedent"""
- rnOptionList
- rnOptionListItem order=1
- rnOptionGroup
- rnLeaf '-'
- rnLeaf 'a'
- rnDescription
- rnLeaf 'desc1'
- rnOptionListItem order=2
- rnOptionGroup
- rnLeaf '-'
- rnLeaf 'b'
- rnDescription
- rnLeaf 'desc2'
- """)
- test "definition list does not gobble up the following blocks":
- check(dedent"""
- defName
- defBody
- -b desc2
- """.toAst(rstOptions = preferRst) ==
- dedent"""
- rnInner
- rnDefList
- rnDefItem
- rnDefName
- rnLeaf 'defName'
- rnDefBody
- rnInner
- rnLeaf 'defBody'
- rnOptionList
- rnOptionListItem order=1
- rnOptionGroup
- rnLeaf '-'
- rnLeaf 'b'
- rnDescription
- rnLeaf 'desc2'
- """)
- test "definition lists work correctly with additional indentation in Markdown":
- check(dedent"""
- Paragraph:
- -c desc1
- -b desc2
- """.toAst() ==
- dedent"""
- rnInner
- rnInner
- rnLeaf 'Paragraph'
- rnLeaf ':'
- rnOptionList
- rnOptionListItem order=1
- rnOptionGroup
- rnLeaf '-'
- rnLeaf 'c'
- rnDescription
- rnLeaf 'desc1'
- rnOptionListItem order=2
- rnOptionGroup
- rnLeaf '-'
- rnLeaf 'b'
- rnDescription
- rnLeaf 'desc2'
- """)
- test "RST comment":
- check(dedent"""
- .. comment1
- comment2
- someParagraph""".toAst ==
- dedent"""
- rnLeaf 'someParagraph'
- """)
- check(dedent"""
- ..
- comment1
- comment2
- someParagraph""".toAst ==
- dedent"""
- rnLeaf 'someParagraph'
- """)
- test "check that additional line right after .. ends comment":
- check(dedent"""
- ..
- notAcomment1
- notAcomment2
- someParagraph""".toAst(rstOptions = preferRst) ==
- dedent"""
- rnInner
- rnBlockQuote
- rnInner
- rnLeaf 'notAcomment1'
- rnLeaf ' '
- rnLeaf 'notAcomment2'
- rnParagraph
- rnLeaf 'someParagraph'
- """)
- test "check that additional line right after .. ends comment (Markdown mode)":
- # in Markdown small indentation does not matter so this should
- # just be split to 2 paragraphs.
- check(dedent"""
- ..
- notAcomment1
- notAcomment2
- someParagraph""".toAst ==
- dedent"""
- rnInner
- rnInner
- rnLeaf 'notAcomment1'
- rnLeaf ' '
- rnLeaf 'notAcomment2'
- rnParagraph
- rnLeaf 'someParagraph'
- """)
- test "but blank lines after 2nd non-empty line don't end the comment":
- check(dedent"""
- ..
- comment1
- comment2
- someParagraph""".toAst ==
- dedent"""
- rnLeaf 'someParagraph'
- """)
- test "using .. as separator b/w directives and block quotes":
- check(dedent"""
- .. note:: someNote
- ..
- someBlockQuote""".toAst(rstOptions = preferRst) ==
- dedent"""
- rnInner
- rnAdmonition adType=note
- [nil]
- [nil]
- rnLeaf 'someNote'
- rnBlockQuote
- rnInner
- rnLeaf 'someBlockQuote'
- """)
- test "no redundant blank lines in literal blocks":
- check(dedent"""
- Check::
- code
- """.toAst(rstOptions = preferRst) ==
- dedent"""
- rnInner
- rnLeaf 'Check'
- rnLeaf ':'
- rnLiteralBlock
- rnLeaf 'code'
- """)
- test "Markdown indented code blocks":
- check(dedent"""
- See
- some code""".toAst ==
- dedent"""
- rnInner
- rnInner
- rnLeaf 'See'
- rnLiteralBlock
- rnLeaf 'some code'
- """)
- # not a code block -- no blank line before:
- check(dedent"""
- See
- some code""".toAst ==
- dedent"""
- rnInner
- rnLeaf 'See'
- rnLeaf ' '
- rnLeaf 'some'
- rnLeaf ' '
- rnLeaf 'code'
- """)
- suite "RST tables":
- test "formatting in tables works":
- check(
- dedent"""
- ========= ===
- `build` `a`
- ========= ===
- """.toAst ==
- dedent"""
- rnTable colCount=2
- rnTableRow
- rnTableDataCell
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf 'build'
- rnTableDataCell
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf 'a'
- """)
- test "tables with slightly overflowed cells cause an error (1)":
- var error = new string
- check(
- dedent"""
- ====== ======
- Inputs Output
- ====== ======
- """.toAst(rstOptions = pureRst, error = error) == "")
- check(error[] == "input(2, 2) Error: Illformed table: " &
- "this word crosses table column from the right")
- # In nimforum compatibility mode & Markdown we raise a warning instead:
- let expected = dedent"""
- rnTable colCount=2
- rnTableRow
- rnTableDataCell
- rnLeaf 'Inputs'
- rnTableDataCell
- rnLeaf 'Output'
- """
- for opt in [preferRst, preferMarkdown]:
- var warnings = new seq[string]
- check(
- dedent"""
- ====== ======
- Inputs Output
- ====== ======
- """.toAst(rstOptions = opt, warnings = warnings) == expected)
- check(warnings[] == @[
- "input(2, 2) Warning: RST style: this word crosses table column from the right"])
- test "tables with slightly overflowed cells cause an error (2)":
- var error = new string
- check("" == dedent"""
- ===== ===== ======
- Input Output
- ===== ===== ======
- False False False
- ===== ===== ======
- """.toAst(rstOptions = pureRst, error = error))
- check(error[] == "input(2, 8) Error: Illformed table: " &
- "this word crosses table column from the right")
- test "tables with slightly underflowed cells cause an error":
- var error = new string
- check("" == dedent"""
- ===== ===== ======
- Input Output
- ===== ===== ======
- False False False
- ===== ===== ======
- """.toAst(rstOptions = pureRst, error = error))
- check(error[] == "input(2, 7) Error: Illformed table: " &
- "this word crosses table column from the left")
- test "tables with unequal underlines should be reported (1)":
- var error = new string
- error[] = "none"
- check("" == dedent"""
- ===== ======
- Input Output
- ===== ======
- False False
- ===== =======
- """.toAst(rstOptions = pureRst, error = error))
- check(error[] == "input(5, 14) Error: Illformed table: " &
- "end of table column #2 should end at position 13")
- test "tables with unequal underlines should be reported (2)":
- var error = new string
- check("" == dedent"""
- ===== ======
- Input Output
- ===== =======
- False False
- ===== ======
- """.toAst(rstOptions = pureRst, error = error))
- check(error[] == "input(3, 14) Error: Illformed table: " &
- "end of table column #2 should end at position 13")
- test "tables with empty first cells":
- check(
- dedent"""
- = = =
- x y z
- t
- = = =
- """.toAst ==
- dedent"""
- rnTable colCount=3
- rnTableRow
- rnTableDataCell
- rnLeaf 'x'
- rnTableDataCell
- rnInner
- rnLeaf 'y'
- rnLeaf ' '
- rnTableDataCell
- rnInner
- rnLeaf 'z'
- rnLeaf ' '
- rnLeaf 't'
- """)
- test "tables with spanning cells & separators":
- check(
- dedent"""
- ===== ===== ======
- Inputs Output
- ------------ ------
- A B A or B
- ===== ===== ======
- False False False
- True False True
- ----- ----- ------
- False True True
- True True True
- ===== ===== ======
- """.toAst ==
- dedent"""
- rnTable colCount=3
- rnTableRow
- rnTableHeaderCell span=2
- rnLeaf 'Inputs'
- rnTableHeaderCell span=1
- rnLeaf 'Output'
- rnTableRow endsHeader
- rnTableHeaderCell
- rnLeaf 'A'
- rnTableHeaderCell
- rnLeaf 'B'
- rnTableHeaderCell
- rnInner
- rnLeaf 'A'
- rnLeaf ' '
- rnLeaf 'or'
- rnLeaf ' '
- rnLeaf 'B'
- rnTableRow
- rnTableDataCell
- rnLeaf 'False'
- rnTableDataCell
- rnLeaf 'False'
- rnTableDataCell
- rnLeaf 'False'
- rnTableRow
- rnTableDataCell span=1
- rnLeaf 'True'
- rnTableDataCell span=1
- rnLeaf 'False'
- rnTableDataCell span=1
- rnLeaf 'True'
- rnTableRow
- rnTableDataCell
- rnLeaf 'False'
- rnTableDataCell
- rnLeaf 'True'
- rnTableDataCell
- rnLeaf 'True'
- rnTableRow
- rnTableDataCell
- rnLeaf 'True'
- rnTableDataCell
- rnLeaf 'True'
- rnTableDataCell
- rnLeaf 'True'
- """)
- test "tables with spanning cells with uneqal underlines cause an error":
- var error = new string
- check(
- dedent"""
- ===== ===== ======
- Inputs Output
- ------------- ------
- A B A or B
- ===== ===== ======
- """.toAst(error=error) == "")
- check(error[] == "input(3, 1) Error: Illformed table: " &
- "spanning underline does not match main table columns")
- let expTable = dedent"""
- rnTable colCount=2
- rnTableRow
- rnTableDataCell
- rnLeaf 'Inputs'
- rnTableDataCell
- rnLeaf 'Output'
- """
- test "only tables with `=` columns specs are allowed (1)":
- var warnings = new seq[string]
- check(
- dedent"""
- ------ ------
- Inputs Output
- ------ ------
- """.toAst(warnings=warnings) ==
- expTable)
- check(warnings[] ==
- @["input(1, 1) Warning: RST style: " &
- "only tables with `=` columns specification are allowed",
- "input(3, 1) Warning: RST style: " &
- "only tables with `=` columns specification are allowed"])
- test "only tables with `=` columns specs are allowed (2)":
- var warnings = new seq[string]
- check(
- dedent"""
- ====== ======
- Inputs Output
- ~~~~~~ ~~~~~~
- """.toAst(warnings=warnings) ==
- expTable)
- check(warnings[] ==
- @["input(3, 1) Warning: RST style: "&
- "only tables with `=` columns specification are allowed"])
- suite "RST indentation":
- test "nested bullet lists":
- let input = dedent """
- * - bullet1
- - bullet2
- * - bullet3
- - bullet4
- """
- let output = input.toAst
- check(output == dedent"""
- rnBulletList
- rnBulletItem
- rnBulletList
- rnBulletItem
- rnInner
- rnLeaf 'bullet1'
- rnBulletItem
- rnInner
- rnLeaf 'bullet2'
- rnBulletItem
- rnBulletList
- rnBulletItem
- rnInner
- rnLeaf 'bullet3'
- rnBulletItem
- rnInner
- rnLeaf 'bullet4'
- """)
- test "nested markup blocks":
- let input = dedent"""
- #) .. Hint:: .. Error:: none
- #) .. Warning:: term0
- Definition0
- #) some
- paragraph1
- #) term1
- Definition1
- term2
- Definition2
- """
- check(input.toAst(rstOptions = preferRst) == dedent"""
- rnEnumList labelFmt=1)
- rnEnumItem
- rnAdmonition adType=hint
- [nil]
- [nil]
- rnAdmonition adType=error
- [nil]
- [nil]
- rnLeaf 'none'
- rnEnumItem
- rnAdmonition adType=warning
- [nil]
- [nil]
- rnDefList
- rnDefItem
- rnDefName
- rnLeaf 'term0'
- rnDefBody
- rnInner
- rnLeaf 'Definition0'
- rnEnumItem
- rnInner
- rnLeaf 'some'
- rnLeaf ' '
- rnLeaf 'paragraph1'
- rnEnumItem
- rnDefList
- rnDefItem
- rnDefName
- rnLeaf 'term1'
- rnDefBody
- rnInner
- rnLeaf 'Definition1'
- rnDefItem
- rnDefName
- rnLeaf 'term2'
- rnDefBody
- rnInner
- rnLeaf 'Definition2'
- """)
- test "code-block parsing":
- let input1 = dedent"""
- .. code-block:: nim
- :test: "nim c $1"
- template additive(typ: typedesc) =
- discard
- """
- let input2 = dedent"""
- .. code-block:: nim
- :test: "nim c $1"
- template additive(typ: typedesc) =
- discard
- """
- let input3 = dedent"""
- .. code-block:: nim
- :test: "nim c $1"
- template additive(typ: typedesc) =
- discard
- """
- let inputWrong = dedent"""
- .. code-block:: nim
- :test: "nim c $1"
- template additive(typ: typedesc) =
- discard
- """
- let ast = dedent"""
- rnCodeBlock
- rnDirArg
- rnLeaf 'nim'
- rnFieldList
- rnField
- rnFieldName
- rnLeaf 'test'
- rnFieldBody
- rnInner
- rnLeaf '"'
- rnLeaf 'nim'
- rnLeaf ' '
- rnLeaf 'c'
- rnLeaf ' '
- rnLeaf '$'
- rnLeaf '1'
- rnLeaf '"'
- rnField
- rnFieldName
- rnLeaf 'default-language'
- rnFieldBody
- rnLeaf 'Nim'
- rnLiteralBlock
- rnLeaf 'template additive(typ: typedesc) =
- discard'
- """
- check input1.toAst == ast
- check input2.toAst == ast
- check input3.toAst == ast
- # "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 "Markdown indentation":
- test "Markdown paragraph indentation":
- # Additional spaces (<=3) of indentation does not break the paragraph.
- # TODO: in 2nd case de-indentation causes paragraph to break, this is
- # reasonable but does not seem to conform the Markdown spec.
- check(dedent"""
- Start1
- stop1
- Start2
- stop2
- """.toAst ==
- dedent"""
- rnInner
- rnParagraph
- rnLeaf 'Start1'
- rnLeaf ' '
- rnLeaf 'stop1'
- rnParagraph
- rnLeaf 'Start2'
- rnParagraph
- rnLeaf 'stop2'
- rnLeaf ' '
- """)
- suite "Warnings":
- test "warnings for broken footnotes/links/substitutions":
- let input = dedent"""
- firstParagraph
- footnoteRef [som]_
- link `a broken Link`_
- substitution |undefined subst|
- link short.link_
- lastParagraph
- """
- var warnings = new seq[string]
- let output = input.toAst(rstOptions=preferRst, warnings=warnings)
- check(warnings[] == @[
- "input(3, 14) Warning: broken link 'citation-som'",
- "input(5, 7) Warning: broken link 'a broken Link'",
- "input(7, 15) Warning: unknown substitution 'undefined subst'",
- "input(9, 6) Warning: broken link 'short.link'"
- ])
- test "Pandoc Markdown concise link warning points to target":
- var warnings = new seq[string]
- check(
- "ref [here][target]".toAst(warnings=warnings) ==
- dedent"""
- rnInner
- rnLeaf 'ref'
- rnLeaf ' '
- rnPandocRef
- rnInner
- rnLeaf 'here'
- rnInner
- rnLeaf 'target'
- """)
- check warnings[] == @["input(1, 12) Warning: broken link 'target'"]
- test "With include directive and blank lines at the beginning":
- "other.rst".writeFile(dedent"""
- firstParagraph
- here brokenLink_""")
- let input = ".. include:: other.rst"
- var warnings = new seq[string]
- let output = input.toAst(warnings=warnings)
- check warnings[] == @["other.rst(5, 6) Warning: broken link 'brokenLink'"]
- check(output == dedent"""
- rnInner
- rnParagraph
- rnLeaf 'firstParagraph'
- rnParagraph
- rnLeaf 'here'
- rnLeaf ' '
- rnRstRef
- rnLeaf 'brokenLink'
- """)
- removeFile("other.rst")
- test "warnings for ambiguous links (references + anchors)":
- # Reference like `x`_ generates a link alias x that may clash with others
- let input = dedent"""
- Manual reference: `foo <#foo,string,string>`_
- .. _foo:
- Paragraph.
- Ref foo_
- """
- var warnings = new seq[string]
- let output = input.toAst(warnings=warnings)
- check(warnings[] == @[
- dedent """
- input(7, 5) Warning: ambiguous doc link `foo`
- clash:
- (3, 8): (manual directive anchor)
- (1, 45): (implicitly-generated hyperlink alias)"""
- ])
- # reference should be resolved to the manually set anchor:
- check(output ==
- dedent"""
- rnInner
- rnParagraph
- rnLeaf 'Manual'
- rnLeaf ' '
- rnLeaf 'reference'
- rnLeaf ':'
- rnLeaf ' '
- rnHyperlink
- rnInner
- rnLeaf 'foo'
- rnInner
- rnLeaf '#foo,string,string'
- rnParagraph anchor='foo'
- rnLeaf 'Paragraph'
- rnLeaf '.'
- rnParagraph
- rnLeaf 'Ref'
- rnLeaf ' '
- rnInternalRef
- rnInner
- rnLeaf 'foo'
- rnLeaf 'foo'
- rnLeaf ' '
- """)
- suite "RST include directive":
- test "Include whole":
- "other.rst".writeFile("**test1**")
- let input = ".. include:: other.rst"
- doAssert "<strong>test1</strong>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
- removeFile("other.rst")
- test "Include starting from":
- "other.rst".writeFile("""
- And this should **NOT** be visible in `docs.html`
- OtherStart
- *Visible*
- """)
- let input = """
- .. include:: other.rst
- :start-after: OtherStart
- """
- check "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
- removeFile("other.rst")
- test "Include everything before":
- "other.rst".writeFile("""
- *Visible*
- OtherEnd
- And this should **NOT** be visible in `docs.html`
- """)
- let input = """
- .. include:: other.rst
- :end-before: OtherEnd
- """
- doAssert "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
- removeFile("other.rst")
- test "Include everything between":
- "other.rst".writeFile("""
- And this should **NOT** be visible in `docs.html`
- OtherStart
- *Visible*
- OtherEnd
- And this should **NOT** be visible in `docs.html`
- """)
- let input = """
- .. include:: other.rst
- :start-after: OtherStart
- :end-before: OtherEnd
- """
- check "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
- removeFile("other.rst")
- test "Ignore premature ending string":
- "other.rst".writeFile("""
- OtherEnd
- And this should **NOT** be visible in `docs.html`
- OtherStart
- *Visible*
- OtherEnd
- And this should **NOT** be visible in `docs.html`
- """)
- let input = """
- .. include:: other.rst
- :start-after: OtherStart
- :end-before: OtherEnd
- """
- doAssert "<em>Visible</em>" == rstToHtml(input, {roSandboxDisabled}, defaultConfig())
- removeFile("other.rst")
- suite "RST escaping":
- test "backspaces":
- check("""\ this""".toAst == dedent"""
- rnLeaf 'this'
- """)
- check("""\\ this""".toAst == dedent"""
- rnInner
- rnLeaf '\'
- rnLeaf ' '
- rnLeaf 'this'
- """)
- check("""\\\ this""".toAst == dedent"""
- rnInner
- rnLeaf '\'
- rnLeaf 'this'
- """)
- check("""\\\\ this""".toAst == dedent"""
- rnInner
- rnLeaf '\'
- rnLeaf '\'
- rnLeaf ' '
- rnLeaf 'this'
- """)
- suite "RST inline markup":
- test "* and ** surrounded by spaces are not inline markup":
- check("a * b * c ** d ** e".toAst == dedent"""
- rnInner
- rnLeaf 'a'
- rnLeaf ' '
- rnLeaf '*'
- rnLeaf ' '
- rnLeaf 'b'
- rnLeaf ' '
- rnLeaf '*'
- rnLeaf ' '
- rnLeaf 'c'
- rnLeaf ' '
- rnLeaf '**'
- rnLeaf ' '
- rnLeaf 'd'
- rnLeaf ' '
- rnLeaf '**'
- rnLeaf ' '
- rnLeaf 'e'
- """)
- test "end-string has repeating symbols":
- check("*emphasis content****".toAst == dedent"""
- rnEmphasis
- rnLeaf 'emphasis'
- rnLeaf ' '
- rnLeaf 'content'
- rnLeaf '***'
- """)
- check("""*emphasis content\****""".toAst == dedent"""
- rnEmphasis
- rnLeaf 'emphasis'
- rnLeaf ' '
- rnLeaf 'content'
- rnLeaf '*'
- rnLeaf '**'
- """) # exact configuration of leafs with * is not really essential,
- # only total number of * is essential
- check("**strong content****".toAst == dedent"""
- rnStrongEmphasis
- rnLeaf 'strong'
- rnLeaf ' '
- rnLeaf 'content'
- rnLeaf '**'
- """)
- check("""**strong content*\****""".toAst == dedent"""
- rnStrongEmphasis
- rnLeaf 'strong'
- rnLeaf ' '
- rnLeaf 'content'
- rnLeaf '*'
- rnLeaf '*'
- rnLeaf '*'
- """)
- check("``lit content`````".toAst == dedent"""
- rnInlineLiteral
- rnLeaf 'lit'
- rnLeaf ' '
- rnLeaf 'content'
- rnLeaf '```'
- """)
- test "interpreted text parsing: code fragments":
- check(dedent"""
- .. default-role:: option
- `--gc:refc`""".toAst ==
- dedent"""
- rnInner
- rnDefaultRole
- rnDirArg
- rnLeaf 'option'
- [nil]
- [nil]
- rnParagraph
- rnCodeFragment
- rnInner
- rnLeaf '--'
- rnLeaf 'gc'
- rnLeaf ':'
- rnLeaf 'refc'
- rnLeaf 'option'
- """)
- test """interpreted text can be ended with \` """:
- let output = (".. default-role:: literal\n" & """`\``""").toAst
- check(output.endsWith """
- rnParagraph
- rnInlineLiteral
- rnLeaf '`'""" & "\n")
- let output2 = """`\``""".toAst
- check(output2 == dedent"""
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf '`'
- """)
- let output3 = """`proc \`+\``""".toAst
- check(output3 == dedent"""
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf 'proc `+`'
- """)
- check("""`\\`""".toAst ==
- dedent"""
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf '\\'
- """)
- test "Markdown-style code/backtick":
- # no whitespace is required before `
- check("`try`...`except`".toAst ==
- dedent"""
- rnInner
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf 'try'
- rnLeaf '...'
- rnInlineCode
- rnDirArg
- rnLeaf 'nim'
- [nil]
- rnLiteralBlock
- rnLeaf 'except'
- """)
- test """inline literals can contain \ anywhere""":
- check("""``\``""".toAst == dedent"""
- rnInlineLiteral
- rnLeaf '\'
- """)
- check("""``\\``""".toAst == dedent"""
- rnInlineLiteral
- rnLeaf '\'
- rnLeaf '\'
- """)
- check("""``\```""".toAst == dedent"""
- rnInlineLiteral
- rnLeaf '\'
- rnLeaf '`'
- """)
- check("""``\\```""".toAst == dedent"""
- rnInlineLiteral
- rnLeaf '\'
- rnLeaf '\'
- rnLeaf '`'
- """)
- check("""``\````""".toAst == dedent"""
- rnInlineLiteral
- rnLeaf '\'
- rnLeaf '`'
- rnLeaf '`'
- """)
- test "references with _ at the end":
- check(dedent"""
- .. _lnk: https
- lnk_""".toAst ==
- dedent"""
- rnHyperlink
- rnInner
- rnLeaf 'lnk'
- rnInner
- rnLeaf 'https'
- """)
- test "not a hyper link":
- check(dedent"""
- .. _lnk: https
- lnk___""".toAst ==
- dedent"""
- rnInner
- rnLeaf 'lnk'
- rnLeaf '___'
- """)
- test "no punctuation in the end of a standalone URI is allowed":
- check(dedent"""
- [see (http://no.org)], end""".toAst(rstOptions = preferRst) ==
- dedent"""
- rnInner
- rnLeaf '['
- rnLeaf 'see'
- rnLeaf ' '
- rnLeaf '('
- rnStandaloneHyperlink
- rnLeaf 'http://no.org'
- rnLeaf ')'
- rnLeaf ']'
- rnLeaf ','
- rnLeaf ' '
- rnLeaf 'end'
- """)
- # but `/` at the end is OK
- check(
- dedent"""
- See http://no.org/ end""".toAst ==
- dedent"""
- rnInner
- rnLeaf 'See'
- rnLeaf ' '
- rnStandaloneHyperlink
- rnLeaf 'http://no.org/'
- rnLeaf ' '
- rnLeaf 'end'
- """)
- # a more complex URL with some made-up ending '&='.
- # Github Markdown would include final &= and
- # so would rst2html.py in contradiction with RST spec.
- check(
- dedent"""
- See https://www.google.com/url?sa=t&source=web&cd=&cad=rja&url=https%3A%2F%2Fnim-lang.github.io%2FNim%2Frst.html%23features&usg=AO&= end""".toAst ==
- dedent"""
- rnInner
- rnLeaf 'See'
- rnLeaf ' '
- rnStandaloneHyperlink
- rnLeaf 'https://www.google.com/url?sa=t&source=web&cd=&cad=rja&url=https%3A%2F%2Fnim-lang.github.io%2FNim%2Frst.html%23features&usg=AO'
- rnLeaf '&'
- rnLeaf '='
- rnLeaf ' '
- rnLeaf 'end'
- """)
- test "Markdown-style link can be split to a few lines":
- check(dedent"""
- is [term-rewriting
- macros](manual.html#term-rewriting-macros)""".toAst ==
- dedent"""
- rnInner
- rnLeaf 'is'
- rnLeaf ' '
- rnHyperlink
- rnLeaf 'term-rewriting macros'
- rnLeaf 'manual.html#term-rewriting-macros'
- """)
- test "URL with balanced parentheses (Markdown rule)":
- # 2 balanced parens, 1 unbalanced:
- check(dedent"""
- https://en.wikipedia.org/wiki/APL_((programming_language)))""".toAst ==
- dedent"""
- rnInner
- rnStandaloneHyperlink
- rnLeaf 'https://en.wikipedia.org/wiki/APL_((programming_language))'
- rnLeaf ')'
- """)
- # the same for Markdown-style link:
- check(dedent"""
- [foo [bar]](https://en.wikipedia.org/wiki/APL_((programming_language))))""".toAst ==
- dedent"""
- rnInner
- rnHyperlink
- rnLeaf 'foo [bar]'
- rnLeaf 'https://en.wikipedia.org/wiki/APL_((programming_language))'
- rnLeaf ')'
- """)
- # unbalanced (here behavior is more RST-like actually):
- check(dedent"""
- https://en.wikipedia.org/wiki/APL_(programming_language(""".toAst ==
- dedent"""
- rnInner
- rnStandaloneHyperlink
- rnLeaf 'https://en.wikipedia.org/wiki/APL_(programming_language'
- rnLeaf '('
- """)
- # unbalanced [, but still acceptable:
- check(dedent"""
- [my {link example](http://example.com/bracket_(symbol_[))""".toAst ==
- dedent"""
- rnHyperlink
- rnLeaf 'my {link example'
- rnLeaf 'http://example.com/bracket_(symbol_[)'
- """)
- test "not a Markdown link":
- # bug #17340 (27) `f` will be considered as a protocol and blocked as unsafe
- var warnings = new seq[string]
- check("[T](f: var Foo)".toAst(warnings = warnings) ==
- dedent"""
- rnInner
- rnLeaf '['
- rnLeaf 'T'
- rnLeaf ']'
- rnLeaf '('
- rnLeaf 'f'
- rnLeaf ':'
- rnLeaf ' '
- rnLeaf 'var'
- rnLeaf ' '
- rnLeaf 'Foo'
- rnLeaf ')'
- """)
- check(warnings[] == @["input(1, 5) Warning: broken link 'f'"])
|