Two independent changes:

1) formatter_functions.py: change a quoted string to an italic string so it is the same as in other functions.

2) ffml_processor.py: use look ahead in the parser to detect parse nodes with text that can be inlined.
This commit is contained in:
Charles Haley 2025-07-23 12:49:28 +01:00
parent 3b094d798c
commit 9f195c761e
2 changed files with 31 additions and 11 deletions

View File

@ -576,6 +576,16 @@ class FFMLProcessor:
'\\': NodeKinds.CHARACTER
}
can_be_inlined = ( NodeKinds.CODE_TEXT,
NodeKinds.ITALIC_TEXT,
NodeKinds.BOLD_TEXT,
NodeKinds.END_SUMMARY,
NodeKinds.GUI_LABEL,
NodeKinds.REF,
NodeKinds.URL,
NodeKinds.CHARACTER
)
def __init__(self):
self.document = DocumentNode()
self.input = None
@ -584,11 +594,10 @@ class FFMLProcessor:
def error(self, message):
raise ValueError(f'{message} on line {self.input_line} in "{self.document_name}"')
def find(self, for_what):
p = self.input.find(for_what, self.input_pos)
if p < 0:
return -1
return -1 if p < 0 else p - self.input_pos
def find(self, for_what, at_pos=-1):
pos = at_pos if at_pos >= 0 else self.input_pos
p = self.input.find(for_what, pos)
return -1 if p < 0 else p - pos
def move_pos(self, to_where):
for c in self.input[self.input_pos:self.input_pos+to_where]:
@ -614,13 +623,14 @@ class FFMLProcessor:
def startswith(self, txt):
return self.input.startswith(txt, self.input_pos)
def find_one_of(self):
def find_one_of(self, at_pos=-1):
positions = []
pos = at_pos if at_pos >= 0 else self.input_pos
for s in self.keywords:
p = self.find(s)
p = self.find(s, pos)
if p == 0:
return self.keywords[s]
positions.append(self.find(s))
positions.append(p)
positions = list(filter(lambda x: x >= 0, positions))
if positions:
return min(positions)
@ -731,7 +741,17 @@ class FFMLProcessor:
p = self.find_one_of()
if p > 0:
txt = self.text_to(p)
txt = txt[:-1].replace('\n', ' ') + txt[-1]
if txt != '\n':
# Look ahead to see if the next parse node's text can be
# inline with this text. If so, change a trailing newline
# to a trailing space.
last_char = txt[-1]
txt = txt[:-1].replace('\n', ' ')
if last_char == '\n' and self.find_one_of(self.input_pos + p) in self.can_be_inlined:
last_char = ' '
parent.add_child(TextNode(txt + last_char))
else:
# Bare newlines are passed through unchanged
parent.add_child(TextNode(txt))
self.move_pos(p)
elif p == NodeKinds.BLANK_LINE:

View File

@ -2445,7 +2445,7 @@ r'''
``virtual_libraries()`` -- return a comma-separated list of Virtual libraries that
contain this book.[/] This function works only in the GUI. If you want to use these
values in save-to-disk or send-to-device templates then you must make a custom
"Column built from other columns", use the function in that column's template,
`Column built from other columns`, use the function in that column's template,
and use that column's value in your save/send templates.
''')