installReferenceHandlers method
void
installReferenceHandlers()
Implementation
void installReferenceHandlers() {
register(["label"], (cmd, ctx, stream) {
final arg = ctx.parseArgument() ?? TextNode("\\label");
final key = switch (arg) {
TextNode() => arg.content,
GroupNode() => ParseUtils.extractText(arg.childrenNodes),
_ => "",
};
return LabelNode(key);
});
register(["ref"], (cmd, ctx, stream) {
final arg = ctx.parseArgument() ?? TextNode("\\ref");
final key = switch (arg) {
TextNode() => arg.content,
GroupNode() => ParseUtils.extractText(arg.childrenNodes),
_ => "",
};
return RefNode(key);
});
register(["eqref"], (cmd, ctx, stream) {
final arg = ctx.parseArgument() ?? TextNode("\\eqref");
final key = switch (arg) {
TextNode() => arg.content,
GroupNode() => ParseUtils.extractText(arg.childrenNodes),
_ => "",
};
return EqRefNode(key);
});
register(["tag"], (cmd, ctx, stream) {
// Check if \tag is followed by *
final peekToken = stream.peek();
final starred =
peekToken is TextToken && peekToken.content.startsWith("*");
if (starred) {
final textToken = stream.peek() as TextToken;
stream.advance();
final remaining = textToken.content.replaceFirst(RegExp(r'^\*'), '');
if (remaining.isNotEmpty) {
// Unlikely to happen, kept for safety
}
}
final arg = ctx.parseArgument() ?? TextNode("");
return TagNode(arg, starred: starred);
});
register(["notag", "nonumber"], (_, __, ___) {
return TagNode(GroupNode([]), starred: true);
});
register(["intertext", "shortintertext"], (_, ctx, __) {
final arg = ctx.parseArgument() ?? TextNode("");
final text = arg is GroupNode
? ParseUtils.extractText(arg.childrenNodes)
: ParseUtils.extractText([arg]);
return TextModeNode(text);
});
register(["substack"], (_, ctx, stream) {
if (stream.peek() is! LeftBraceToken) {
return TextNode("\\substack");
}
stream.advance(); // consume {
final rows = <List<LatexNode>>[];
var currentRow = <LatexNode>[];
while (!stream.isEOF()) {
final token = stream.peek();
if (token is RightBraceToken) {
stream.advance();
break;
} else if (token is NewLineToken) {
stream.advance();
rows.add(List.from(currentRow));
currentRow = <LatexNode>[];
} else {
final node = ctx.parseExpression();
if (node != null) currentRow.add(node);
}
}
if (currentRow.isNotEmpty) {
rows.add(currentRow);
}
return SubstackNode(rows);
});
}