class_docstr: Render Spans as SVGs.
class_docstr_tok: ["Render","Spans","as","SVGs","."]
docstr: Render the markup from per-token information
docstr_tok: ["Render","the","markup","from","per-token","information"]
code: def _render_markup(self, per_token_info: List[Dict[str, Any]]) -> str:
      """Render the markup from per-token information"""
      markup = ""
      for token in per_token_info:
          entities = sorted(
              token["entities"], key=lambda d: d["render_slot"]
          )
          # Whitespace tokens disrupt the vertical space (no line height) so that the
          # span indicators get misaligned. We don't render them as individual
          # tokens anyway, so we'll just not display a span indicator either.
          is_whitespace = token["text"].strip() == ""
          if entities and not is_whitespace:
              slices = self._get_span_slices(token["entities"])
              starts = self._get_span_starts(token["entities"])
              total_height = (
                  self.top_offset
                  + self.span_label_offset
                  + (self.offset_step * (len(entities) - 1))
              )
              markup += self.span_template.format(
                  text=escape_html(token["text"]),
                  span_slices=slices,
                  span_starts=starts,
                  total_height=total_height,
              )
          else:
              markup += escape_html(token["text"] + " ")
      return markup
  
imports: import uuid
  from typing import Any, Dict, List, Optional, Tuple, Union
  from ..errors import Errors
  from ..util import escape_html, minify_html, registry
  from .templates import TPL_DEP_ARCS, TPL_DEP_SVG, TPL_DEP_WORDS, TPL_DEP_WORDS_LEMMA, TPL_ENT, TPL_ENT_RTL, TPL_ENTS, TPL_FIGURE, TPL_KB_LINK, TPL_PAGE, TPL_SPAN, TPL_SPAN_RTL, TPL_SPAN_SLICE, TPL_SPAN_SLICE_RTL, TPL_SPAN_START, TPL_SPAN_START_RTL, TPL_SPANS, TPL_TITLE
label_desc: Use image node_id 5 for calling the SpanRenderer obj's underlying member method code with example usage: obj._render_markup(per_token_info) and returns: markup