fragments_join.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. from .state_inline import StateInline
  2. def fragments_join(state: StateInline) -> None:
  3. """
  4. Clean up tokens after emphasis and strikethrough postprocessing:
  5. merge adjacent text nodes into one and re-calculate all token levels
  6. This is necessary because initially emphasis delimiter markers (``*, _, ~``)
  7. are treated as their own separate text tokens. Then emphasis rule either
  8. leaves them as text (needed to merge with adjacent text) or turns them
  9. into opening/closing tags (which messes up levels inside).
  10. """
  11. level = 0
  12. maximum = len(state.tokens)
  13. curr = last = 0
  14. while curr < maximum:
  15. # re-calculate levels after emphasis/strikethrough turns some text nodes
  16. # into opening/closing tags
  17. if state.tokens[curr].nesting < 0:
  18. level -= 1 # closing tag
  19. state.tokens[curr].level = level
  20. if state.tokens[curr].nesting > 0:
  21. level += 1 # opening tag
  22. if (
  23. state.tokens[curr].type == "text"
  24. and curr + 1 < maximum
  25. and state.tokens[curr + 1].type == "text"
  26. ):
  27. # collapse two adjacent text nodes
  28. state.tokens[curr + 1].content = (
  29. state.tokens[curr].content + state.tokens[curr + 1].content
  30. )
  31. else:
  32. if curr != last:
  33. state.tokens[last] = state.tokens[curr]
  34. last += 1
  35. curr += 1
  36. if curr != last:
  37. del state.tokens[last:]