renderDocs function

DocHtmlResult renderDocs(
  1. List<Library> libraries
)

Renders a list of Library objects into sidebar and content HTML.

Each library's Library.getDocs and Library.description are used to produce the output. Libraries with no documented functions are skipped.

Implementation

DocHtmlResult renderDocs(List<Library> libraries) {
  final sidebarBuf = StringBuffer();
  final contentBuf = StringBuffer();
  final usedAnchors = <String>{};
  var sectionIndex = 0;

  for (final lib in libraries) {
    final docs = lib.getDocs();
    final valueDocs = lib.getValueDocs();
    if (docs.isEmpty &&
        lib.getTableDocs().isEmpty &&
        valueDocs.isEmpty &&
        lib.getAliasDocs().isEmpty &&
        lib.getEnumDocs().isEmpty) {
      continue;
    }
    final cat = _libraryDocName(lib, docs);
    final sectionId = 'section-$sectionIndex-${_escapeAttribute(cat)}';
    final anchors = <String, String>{
      for (final name in docs.keys) name: _uniqueAnchor(cat, name, usedAnchors),
      for (final name in valueDocs.keys)
        name: _uniqueAnchor(cat, name, usedAnchors),
    };
    sectionIndex++;

    sidebarBuf.writeln('<div class="section-group">');
    sidebarBuf.writeln(
      '<button class="section-toggle" type="button" '
      'aria-controls="$sectionId-nav" aria-expanded="true">'
      '<span class="toggle-icon" aria-hidden="true">v</span>'
      '<span>${_escape(cat)}</span></button>',
    );
    sidebarBuf.writeln('<div class="section-items" id="$sectionId-nav">');
    for (final name in docs.keys) {
      final href = _escapeAttribute(anchors[name]!);
      sidebarBuf.writeln('<a class="func" href="#$href">${_escape(name)}</a>');
    }
    for (final name in valueDocs.keys) {
      final href = _escapeAttribute(anchors[name]!);
      sidebarBuf.writeln('<a class="func" href="#$href">${_escape(name)}</a>');
    }
    sidebarBuf.writeln('</div>');
    sidebarBuf.writeln('</div>');

    contentBuf.writeln('<section class="section-group">');
    contentBuf.writeln(
      '<button class="section-toggle" type="button" '
      'aria-controls="$sectionId-content" aria-expanded="true">'
      '<span class="toggle-icon" aria-hidden="true">v</span>'
      '<span>${_escape(cat)}</span></button>',
    );
    contentBuf.writeln('<div class="section-items" id="$sectionId-content">');
    if (lib.description.isNotEmpty) {
      contentBuf.writeln(
        '<p class="library-desc">${_escape(lib.description)}</p>',
      );
    }

    for (final entry in valueDocs.entries) {
      final name = entry.key;
      final doc = entry.value;
      final anchor = anchors[name]!;

      contentBuf.writeln('<article class="func-entry">');
      contentBuf.writeln('<a id="${_escapeAttribute(anchor)}"></a>');
      contentBuf.writeln(
        '<div class="func-signature">${_escape(name)}: '
        '${_escape(doc.type)}</div>',
      );

      final badges = <String>[];
      if (doc.deprecated) {
        badges.add('<span class="badge badge-deprecated">deprecated</span>');
      }
      if (badges.isNotEmpty) {
        contentBuf.writeln('<div class="badges">${badges.join(' ')}</div>');
      }

      if (doc.deprecated) {
        contentBuf.writeln(
          '<div class="func-summary deprecated">${_escape(doc.summary)}</div>',
        );
      } else {
        contentBuf.writeln(
          '<div class="func-summary">${_escape(doc.summary)}</div>',
        );
      }
      if (doc.value != null) {
        contentBuf.writeln(
          '<div class="returns"><strong>Value:</strong> '
          '<code>${_escape(doc.value!)}</code></div>',
        );
      }
      if (doc.see != null) {
        contentBuf.writeln(
          '<div class="see"><strong>See:</strong> '
          '<code>${_escape(doc.see!)}</code></div>',
        );
      }
      if (doc.source != null) {
        contentBuf.writeln(
          '<div class="source"><strong>Source:</strong> '
          '<code>${_escape(doc.source!)}</code></div>',
        );
      }
      if (doc.version != null) {
        contentBuf.writeln(
          '<div class="version"><strong>Version:</strong> '
          '<code>${_escape(doc.version!)}</code></div>',
        );
      }
      contentBuf.writeln('</article>');
    }

    for (final entry in docs.entries) {
      final name = entry.key;
      final doc = entry.value;
      final sig = _signatureText(name, doc);
      final anchor = anchors[name]!;

      contentBuf.writeln('<article class="func-entry">');
      contentBuf.writeln('<a id="${_escapeAttribute(anchor)}"></a>');
      contentBuf.writeln('<div class="func-signature">${_escape(sig)}</div>');

      final badges = <String>[];
      if (doc.deprecated) {
        badges.add('<span class="badge badge-deprecated">deprecated</span>');
      }
      if (doc.async) {
        badges.add('<span class="badge badge-async">async</span>');
      }
      if (doc.nodiscard) {
        badges.add('<span class="badge badge-nodiscard">nodiscard</span>');
      }
      if (doc.scope != AccessScope.public) {
        badges.add('<span class="badge badge-scope">${doc.scope.name}</span>');
      }
      if (badges.isNotEmpty) {
        contentBuf.writeln('<div class="badges">${badges.join(' ')}</div>');
      }

      if (doc.deprecated) {
        contentBuf.writeln(
          '<div class="func-summary deprecated">${_escape(doc.summary)}</div>',
        );
      } else {
        contentBuf.writeln(
          '<div class="func-summary">${_escape(doc.summary)}</div>',
        );
      }
      if (doc.params.isNotEmpty) {
        contentBuf.write(_paramRowsHtml(doc.params));
      }
      if (doc.returns != null) {
        contentBuf.writeln(
          '<div class="returns"><strong>Returns:</strong> '
          '${_escape(doc.returns!)}</div>',
        );
      }
      if (doc.see != null) {
        contentBuf.writeln(
          '<div class="see"><strong>See:</strong> '
          '<code>${_escape(doc.see!)}</code></div>',
        );
      }
      if (doc.source != null) {
        contentBuf.writeln(
          '<div class="source"><strong>Source:</strong> '
          '<code>${_escape(doc.source!)}</code></div>',
        );
      }
      if (doc.version != null) {
        contentBuf.writeln(
          '<div class="version"><strong>Version:</strong> '
          '<code>${_escape(doc.version!)}</code></div>',
        );
      }
      if (doc.example != null) {
        contentBuf.writeln(
          '<pre class="language-lua"><code class="language-lua">'
          '${_escape(doc.example!)}</code></pre>',
        );
      }
      contentBuf.writeln('</article>');
    }
    contentBuf.writeln('</div>');
    contentBuf.writeln('</section>');
  }

  return DocHtmlResult(
    sidebar: sidebarBuf.toString(),
    content: contentBuf.toString(),
  );
}