escape.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """
  2. Process escaped chars and hardbreaks
  3. """
  4. from ..common.utils import isStrSpace
  5. from .state_inline import StateInline
  6. def escape(state: StateInline, silent: bool) -> bool:
  7. """Process escaped chars and hardbreaks."""
  8. pos = state.pos
  9. maximum = state.posMax
  10. if state.src[pos] != "\\":
  11. return False
  12. pos += 1
  13. # '\' at the end of the inline block
  14. if pos >= maximum:
  15. return False
  16. ch1 = state.src[pos]
  17. ch1_ord = ord(ch1)
  18. if ch1 == "\n":
  19. if not silent:
  20. state.push("hardbreak", "br", 0)
  21. pos += 1
  22. # skip leading whitespaces from next line
  23. while pos < maximum:
  24. ch = state.src[pos]
  25. if not isStrSpace(ch):
  26. break
  27. pos += 1
  28. state.pos = pos
  29. return True
  30. escapedStr = state.src[pos]
  31. if ch1_ord >= 0xD800 and ch1_ord <= 0xDBFF and pos + 1 < maximum:
  32. ch2 = state.src[pos + 1]
  33. ch2_ord = ord(ch2)
  34. if ch2_ord >= 0xDC00 and ch2_ord <= 0xDFFF:
  35. escapedStr += ch2
  36. pos += 1
  37. origStr = "\\" + escapedStr
  38. if not silent:
  39. token = state.push("text_special", "", 0)
  40. token.content = escapedStr if ch1 in _ESCAPED else origStr
  41. token.markup = origStr
  42. token.info = "escape"
  43. state.pos = pos + 1
  44. return True
  45. _ESCAPED = {
  46. "!",
  47. '"',
  48. "#",
  49. "$",
  50. "%",
  51. "&",
  52. "'",
  53. "(",
  54. ")",
  55. "*",
  56. "+",
  57. ",",
  58. "-",
  59. ".",
  60. "/",
  61. ":",
  62. ";",
  63. "<",
  64. "=",
  65. ">",
  66. "?",
  67. "@",
  68. "[",
  69. "\\",
  70. "]",
  71. "^",
  72. "_",
  73. "`",
  74. "{",
  75. "|",
  76. "}",
  77. "~",
  78. }