def graphviz_html_string(s, *, repl_nl=None, repl_colon=None, xmltext=None):
    """
    Workaround *pydot* parsing of node-id & labels by encoding as HTML.

    - `pydot` library does not quote DOT-keywords anywhere (pydot#111).
    - Char ``:`` on node-names denote port/compass-points and break IDs (pydot#224).
    - Non-strings are not quote_if_necessary by pydot.
    - NLs im tooltips of HTML-Table labels `need substitution with the XML-entity
      <see https://stackoverflow.com/a/27448551/548792>`_.
    - HTML-Label attributes (``xmlattr=True``) need both html-escape & quote.

    .. Attention::
        It does not correctly handle ``ID:port:compass-point`` format.

    See https://www.graphviz.org/doc/info/lang.html)
    """
    import html
    if s:
        s = html.escape(s)
        if repl_nl:
            s = s.replace('\n', '&#10;').replace('\t', '&#9;')
        if repl_colon:
            s = s.replace(':', '&#58;')
        if not xmltext:
            s = f'<{s}>'
    return s
