      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["label"])
              if entities:
                  slices = self._get_span_slices(token["entities"])
                  starts = self._get_span_starts(token["entities"])
                  total_height = (
                      self.top_offset
                      + self.span_label_offset
 
</s> remove         for entity, step in zip(entities, itertools.count(step=self.offset_step)):
 </s> add         for entity in entities: </s> remove         for entity, step in zip(entities, itertools.count(step=self.offset_step)):
 </s> add         for entity in entities:
            # rather than iterate over multiples of offset_step, we use entity['render_slot']
            # to determine the vertical position, since that tells where
            # the span starts vertically so we can extend it horizontally,
            # past other spans that might have already ended </s> remove                 bg=color, top_offset=self.top_offset + step
 </s> add                 bg=color,
                top_offset=top_offset,
            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:
      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:
            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
keep keep keep keep replace replace keep keep keep keep keep
 displaCy Spans Vertical Alignment Fix 2 (#11092)

* add in span render slot fix

* fix spacing off by one

* rm demo

* adjust comments

* fix whitespace and overlap issue 
spacy/displacy/render.py