In this Engineering Notebook post I'll discuss recent work on
#2276 and
PR
#2303.
Work is almost finished. I'll merge the work into devel in a day or three.
Background
#2276 suggests adding @section-delims. Work has expanded to include:
- A thorough review of at_fast.scan_lines
- A project to cover at_fast.scan_lines with unit tests.
The
coverage tests revealed that @raw has been broken for about three
years!
Refactoring scan_lines
I "refactored" the sections in scan_lines to
make the use of various flags more clear. The start of the main loop of
scan_lines is now:
for i, line in enumerate(lines[start:]):
# Strip the line only once.
strip_line = line.strip()
if after ref:
<< handle afterref line>>
continue
if verbatim:
<< handle verbatim line >>
continue
if line == verbatim_line: # <delim>@verbatim.
verbatim = True
continue
<< finalize line >>
if not in_doc and not strip_line.startswith(sentinel): # Faster than a regex!
body.append(line)
continue
# These three sections might clear in_doc.
<< handle @others >>
<< handle section refs >>
<< handle node_start >>
if in_doc:
<< handle @c or @code >>
else:
<< handle @ or @doc >>
if line.startswith(comment_delim1 + '@-leo'):
# Faster than a regex!
# The @-leo sentinel adds *nothing* to the text.
i += 1
break
Imo, this new "rendering" of the code is way clearer than in devel: ordering dependencies are now explicit. Very little code actually changed because of this refactoring!
Complications
@last clearly does work in the devel branch, but the first versions of the new unit tests for @last failed! This mystery was solved by having unit tests ensure that the gnx in the generated node
(in the test) matches the root's gnx. Having the gnx's match makes the
unit tests much stronger.
The new << final checks >> section of at_fast.scan_lines is more complex than expected. Indeed, there is now a new, hacky,
root_gnx_adjusted flag. This flag is set only << handle node_start >>. Ironically, no unit test that handles gnx's correctly can exercise this code!
Summary
This post explains some of the complexities of scan_lines.
Félix will likely have to understand every
line of scan_lines in order to transliterate it.
scan_lines
is the one and only place in Leo where section references seem essential.
Without sections, the scan_lines would be too big to understand. Alas,
splitting scan_lines into methods would slow down Leo's read
code.
Edward