annotate method

void annotate(
  1. Document doc
)

for each entry, modify the whole dom tree, and then next entry

Implementation

void annotate(Document doc) {
  final matchedEntries = <String, GlossaryItem>{};
  for (final entry in entries) {
    final name = entry.name;
    final regex = (_regexCache[name] ??= _makeRegExp(name));
    List<Node>? replacing;
    doc.visit((node) {
      if (node is Element && _isIgnored(node)) {
        return false;
      }
      if (node.nodeType != Node.TEXT_NODE) {
        return true;
      }
      final data = (node as Text).data;
      if (data.trim().isEmpty) {
        return true;
      }

      final e = _replaceNode(node, regex, (m) {
        matchedEntries[entry.name] = entry;
        return '<span class="glossary-item" data-target="glossary-${entry.id}">$name</span>';
      });
      if (e != null) {
        final parent = node.parent;
        parent?.insertBefore(e, node);
        final list = (replacing ??= <Node>[]);
        list.add(node);
      }
      return true;
    });

    /// remove replacing nodes after traversal
    replacing?.forEach((e) {
      e.remove();
    });
  }
  final container = doc.getElementById('body-container');
  if (container != null) {
    for (final entry in matchedEntries.values) {
      final desc = entry.desc;
      if (desc != null) {
        container.append(Element.html(
            '<div id="glossary-${entry.id}" class="glossary-detail">$desc</div>'));
      }
    }
  }
}