visitElementBefore method
Called when an Element has been reached, before its children have been visited.
Returns false to skip its children.
Implementation
@override
bool visitElementBefore(md.Element element) {
switch (element.tag) {
case 'h1':
_enterHeading(theme.h1);
return true;
case 'h2':
_enterHeading(theme.h2);
return true;
case 'h3':
_enterHeading(theme.h3);
return true;
case 'h4':
_enterHeading(theme.h4);
return true;
case 'h5':
_enterHeading(theme.h5);
return true;
case 'h6':
_enterHeading(theme.h6);
return true;
case 'p':
_ensureNewline();
_enterParagraph();
return true;
case 'blockquote':
final style = _cascadeBlock(
_blockStack.last.style,
theme.blockQuote,
toBlock: false,
);
_enterBlock(style, _currentWidth);
return true;
case 'ul':
case 'ol':
_listCounters.add(0);
_listIsOrdered.add(element.tag == 'ol');
_ensureNewline();
var style = theme.list.style;
if (theme.list.levelIndent != null && theme.list.levelIndent! > 0) {
style = GlamourBlockStyle(
style: style.style,
margin: (style.margin ?? 0) + theme.list.levelIndent!,
indent: style.indent,
indentToken: style.indentToken,
);
}
final merged = _cascadeBlock(
_blockStack.last.style,
style,
toBlock: false,
);
_enterBlock(merged, _currentWidth);
return true;
case 'li':
_ensureNewline();
_visitListItem(element);
return true;
case 'strong':
_inlineStack.add(theme.strong);
return true;
case 'em':
_inlineStack.add(theme.emph);
return true;
case 'code':
_inlineStack.add(theme.code.style);
return true;
case 'a':
_inlineStack.add(theme.linkText);
_linkStack.add(element.attributes['href'] ?? '');
return true;
case 'hr':
_ensureNewline();
final format = theme.horizontalRule.format ?? '--------';
_writeRaw('\x1b[0m'); // Reset before HR
_writeRaw(theme.horizontalRule.toStyle.render(format));
_ensureNewline();
return true;
case 'input':
// Handle task list checkboxes
final type = element.attributes['type'];
if (type == 'checkbox') {
final checked = element.attributes['checked'] == 'true';
_writeStyled(
checked ? theme.task.ticked : theme.task.unticked,
theme.task.style,
);
return false; // Don't visit children
}
return true;
case 'table':
_tableHeaders.clear();
_tableRows.clear();
_currentRow.clear();
return true;
case 'thead':
_inTableHead = true;
return true;
case 'tbody':
_inTableHead = false;
return true;
case 'tr':
// End current row
if (_currentRow.isNotEmpty) {
if (_inTableHead) {
_tableHeaders.addAll(_currentRow);
} else {
_tableRows.add(List.from(_currentRow));
}
_currentRow.clear();
}
return true;
case 'th':
_inTableCell = true;
return true;
case 'td':
_inTableCell = true;
return true;
default:
return true;
}
}