@@ -1326,6 +1326,7 @@ def __init__(self, elements: T.Sequence[Node], w: float = 0.0,
13261326 if do_kern :
13271327 self .kern ()
13281328 self .hpack (w = w , m = m )
1329+ self .is_phantom = False
13291330
13301331 def is_char_node (self ) -> bool :
13311332 # See description in Node.is_char_node.
@@ -1716,6 +1717,11 @@ def ship(box: Box, xy: tuple[float, float] = (0, 0)) -> Output:
17161717 off_v = oy + box .height
17171718 output = Output (box )
17181719
1720+ phantom : list [bool ] = []
1721+ def render (node , * args ):
1722+ if not any (phantom ):
1723+ node .render (* args )
1724+
17191725 def clamp (value : float ) -> float :
17201726 return - 1e9 if value < - 1e9 else + 1e9 if value > + 1e9 else value
17211727
@@ -1729,9 +1735,11 @@ def hlist_out(box: Hlist) -> None:
17291735 base_line = cur_v
17301736 left_edge = cur_h
17311737
1738+ phantom .append (box .is_phantom )
1739+
17321740 for p in box .children :
17331741 if isinstance (p , Char ):
1734- p . render (output , cur_h + off_h , cur_v + off_v )
1742+ render (p , output , cur_h + off_h , cur_v + off_v )
17351743 cur_h += p .width
17361744 elif isinstance (p , Kern ):
17371745 cur_h += p .width
@@ -1762,9 +1770,9 @@ def hlist_out(box: Hlist) -> None:
17621770 rule_depth = box .depth
17631771 if rule_height > 0 and rule_width > 0 :
17641772 cur_v = base_line + rule_depth
1765- p . render (output ,
1766- cur_h + off_h , cur_v + off_v ,
1767- rule_width , rule_height )
1773+ render (p , output ,
1774+ cur_h + off_h , cur_v + off_v ,
1775+ rule_width , rule_height )
17681776 cur_v = base_line
17691777 cur_h += rule_width
17701778 elif isinstance (p , Glue ):
@@ -1782,6 +1790,8 @@ def hlist_out(box: Hlist) -> None:
17821790 rule_width += cur_g
17831791 cur_h += rule_width
17841792
1793+ phantom .pop ()
1794+
17851795 def vlist_out (box : Vlist ) -> None :
17861796 nonlocal cur_v , cur_h
17871797
@@ -1821,9 +1831,9 @@ def vlist_out(box: Vlist) -> None:
18211831 rule_height += rule_depth
18221832 if rule_height > 0 and rule_depth > 0 :
18231833 cur_v += rule_height
1824- p . render (output ,
1825- cur_h + off_h , cur_v + off_v ,
1826- rule_width , rule_height )
1834+ render (p , output ,
1835+ cur_h + off_h , cur_v + off_v ,
1836+ rule_width , rule_height )
18271837 elif isinstance (p , Glue ):
18281838 glue_spec = p .glue_spec
18291839 rule_height = glue_spec .width - cur_g
@@ -2159,6 +2169,10 @@ def csnames(group: str, names: Iterable[str]) -> Regex:
21592169
21602170 p .customspace = cmd (r"\hspace" , "{" + p .float_literal ("space" ) + "}" )
21612171
2172+ p .phantom = cmd (r"\phantom" , p .optional_group ("value" ))
2173+ p .llap = cmd (r"\llap" , p .optional_group ("value" ))
2174+ p .rlap = cmd (r"\rlap" , p .optional_group ("value" ))
2175+
21622176 p .accent = (
21632177 csnames ("accent" , [* self ._accent_map , * self ._wide_accents ])
21642178 - p .named_placeable ("sym" ))
@@ -2225,7 +2239,8 @@ def csnames(group: str, names: Iterable[str]) -> Regex:
22252239 r"\boldsymbol" , "{" + ZeroOrMore (p .simple )("value" ) + "}" )
22262240
22272241 p .placeable <<= (
2228- p .accent # Must be before symbol as all accents are symbols
2242+ p .phantom | p .llap | p .rlap
2243+ | p .accent # Must be before symbol as all accents are symbols
22292244 | p .symbol # Must be second to catch all named symbols and single
22302245 # chars not in a group
22312246 | p .function
@@ -2419,6 +2434,16 @@ def symbol(self, s: str, loc: int,
24192434 def unknown_symbol (self , s : str , loc : int , toks : ParseResults ) -> T .Any :
24202435 raise ParseFatalException (s , loc , f"Unknown symbol: { toks ['name' ]} " )
24212436
2437+ def phantom (self , toks : ParseResults ) -> T .Any :
2438+ toks ["value" ].is_phantom = True
2439+ return toks ["value" ]
2440+
2441+ def llap (self , toks : ParseResults ) -> T .Any :
2442+ return [Hlist ([Kern (- toks ["value" ].width ), toks ["value" ]])]
2443+
2444+ def rlap (self , toks : ParseResults ) -> T .Any :
2445+ return [Hlist ([toks ["value" ], Kern (- toks ["value" ].width )])]
2446+
24222447 _accent_map = {
24232448 r'hat' : r'\circumflexaccent' ,
24242449 r'breve' : r'\combiningbreve' ,
0 commit comments