Markdown indented code blocks (#20473)

* Implement Markdown indented code blocks

Additional indentation of 4 spaces makes a block an "indented code block"
(monospaced text without syntax highlighting).
Also `::` RST syntax for code blocks is disabled.

So instead of
```rst
see::

  Some code
```

the code block should be written as
```markdown
see:

    Some code
```

* Migrate RST literal blocks :: to Markdown's ones
This commit is contained in:
Andrey Makarov 2022-10-05 21:03:10 +03:00 • committed by GitHub
commit 6505bd347d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 697 additions and 603 deletions

View file

@ -75,10 +75,10 @@ proc toLangSymbol*(linkText: PRstNode): LangSymbol =
## Parses `linkText` into a more structured form using a state machine.
##
## This proc is designed to allow link syntax with operators even
## without escaped backticks inside::
## without escaped backticks inside:
##
## `proc *`_
## `proc []`_
## `proc *`_
## `proc []`_
##
## This proc should be kept in sync with the `renderTypes` proc from
## ``compiler/typesrenderer.nim``.

View file

@ -2172,7 +2172,7 @@ proc whichSection(p: RstParser): RstNodeKind =
# for punctuation sequences that can be both tkAdornment and tkPunct
if isMarkdownCodeBlock(p):
return rnCodeBlock
elif currentTok(p).symbol == "::":
elif isRst(p) and currentTok(p).symbol == "::":
return rnLiteralBlock
elif currentTok(p).symbol == ".." and
nextTok(p).kind in {tkWhite, tkIndent}:
@ -2362,8 +2362,10 @@ proc parseParagraph(p: var RstParser, result: PRstNode) =
of tkIndent:
if nextTok(p).kind == tkIndent:
inc p.idx
break
elif currentTok(p).ival == currInd(p):
break # blank line breaks paragraph for both Md & Rst
elif currentTok(p).ival == currInd(p) or (
isMd(p) and currentTok(p).ival > currInd(p)):
# (Md allows adding additional indentation inside paragraphs)
inc p.idx
case whichSection(p)
of rnParagraph, rnLeaf, rnHeadline, rnMarkdownHeadline,
@ -2377,7 +2379,8 @@ proc parseParagraph(p: var RstParser, result: PRstNode) =
else:
break
of tkPunct:
if (let literalBlockKind = whichRstLiteralBlock(p);
if isRst(p) and (
let literalBlockKind = whichRstLiteralBlock(p);
literalBlockKind != lbNone):
result.add newLeaf(":")
inc p.idx # skip '::'
@ -2932,11 +2935,11 @@ proc parseSection(p: var RstParser, result: PRstNode) =
elif currentTok(p).ival > currInd(p):
if roPreferMarkdown in p.s.options: # Markdown => normal paragraphs
if currentTok(p).ival - currInd(p) >= 4:
rstMessage(p, mwRstStyle,
"Markdown indented code not implemented")
pushInd(p, currentTok(p).ival)
parseSection(p, result)
popInd(p)
result.add parseLiteralBlock(p)
else:
pushInd(p, currentTok(p).ival)
parseSection(p, result)
popInd(p)
else: # RST mode => block quotes
pushInd(p, currentTok(p).ival)
var a = newRstNodeA(p, rnBlockQuote)

View file

@ -377,13 +377,13 @@ proc renderRstToJsonNode(node: PRstNode): JsonNode =
proc renderRstToJson*(node: PRstNode): string =
## Writes the given RST node as JSON that is in the form
## ::
## {
## "kind":string node.kind,
## "text":optional string node.text,
## "level":optional int node.level,
## "sons":optional node array
## }
##
## {
## "kind":string node.kind,
## "text":optional string node.text,
## "level":optional int node.level,
## "sons":optional node array
## }
renderRstToJsonNode(node).pretty
proc renderRstToText*(node: PRstNode): string =