Rst parser respect :start-after: and :end-before: in include directive (#12972)

* [FEATURE] rst parser respect :start-after: in include

Rst parser now respects `:start-after:` and `:end-before:` attributes
for `include` directive.

* [DOC] include directive parsing proc update

* [TEST] Added unit tests for include rst directive in `rst` module
This commit is contained in:
Kamanji 2020-01-05 12:01:21 +03:00 • committed by Andreas Rumpf
commit 9a5aaadda8
2 changed files with 118 additions and 10 deletions

View file

@ -1558,15 +1558,20 @@ proc parseDirBody(p: var RstParser, contentParser: SectionParser): PRstNode =
popInd(p)
proc dirInclude(p: var RstParser): PRstNode =
#
#The following options are recognized:
#
#start-after : text to find in the external data file
# Only the content after the first occurrence of the specified text will
# be included.
#end-before : text to find in the external data file
# Only the content before the first occurrence of the specified text
# (but after any after text) will be included.
##
## The following options are recognized:
##
## :start-after: text to find in the external data file
##
## Only the content after the first occurrence of the specified
## text will be included. If text is not found inclusion will
## start from beginning of the file
##
## :end-before: text to find in the external data file
##
## Only the content before the first occurrence of the specified
## text (but after any after text) will be included. If text is
## not found inclusion will happen until the end of the file.
#literal : flag (empty)
# The entire included text is inserted into the document as a single
# literal block (useful for program listings).
@ -1586,10 +1591,34 @@ proc dirInclude(p: var RstParser): PRstNode =
result = newRstNode(rnLiteralBlock)
add(result, newRstNode(rnLeaf, readFile(path)))
else:
let inputString = readFile(path).string()
let startPosition =
block:
let searchFor = n.getFieldValue("start-after").strip()
if searchFor != "":
let pos = inputString.find(searchFor)
if pos != -1: pos + searchFor.len()
else: 0
else:
0
let endPosition =
block:
let searchFor = n.getFieldValue("end-before").strip()
if searchFor != "":
let pos = inputString.find(searchFor, start = startPosition)
if pos != -1: pos - 1
else: 0
else:
inputString.len - 1
var q: RstParser
initParser(q, p.s)
q.filename = path
q.col += getTokens(readFile(path), false, q.tok)
q.col += getTokens(
inputString[startPosition..endPosition].strip(),
false,
q.tok)
# workaround a GCC bug; more like the interior pointer bug?
#if find(q.tok[high(q.tok)].symbol, "\0\x01\x02") > 0:
# InternalError("Too many binary zeros in include file")