escape.mjs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Process escaped chars and hardbreaks
  2. import { isSpace } from '../common/utils.mjs'
  3. const ESCAPED = []
  4. for (let i = 0; i < 256; i++) { ESCAPED.push(0) }
  5. '\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-'
  6. .split('').forEach(function (ch) { ESCAPED[ch.charCodeAt(0)] = 1 })
  7. export default function escape (state, silent) {
  8. let pos = state.pos
  9. const max = state.posMax
  10. if (state.src.charCodeAt(pos) !== 0x5C/* \ */) return false
  11. pos++
  12. // '\' at the end of the inline block
  13. if (pos >= max) return false
  14. let ch1 = state.src.charCodeAt(pos)
  15. if (ch1 === 0x0A) {
  16. if (!silent) {
  17. state.push('hardbreak', 'br', 0)
  18. }
  19. pos++
  20. // skip leading whitespaces from next line
  21. while (pos < max) {
  22. ch1 = state.src.charCodeAt(pos)
  23. if (!isSpace(ch1)) break
  24. pos++
  25. }
  26. state.pos = pos
  27. return true
  28. }
  29. let escapedStr = state.src[pos]
  30. if (ch1 >= 0xD800 && ch1 <= 0xDBFF && pos + 1 < max) {
  31. const ch2 = state.src.charCodeAt(pos + 1)
  32. if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
  33. escapedStr += state.src[pos + 1]
  34. pos++
  35. }
  36. }
  37. const origStr = '\\' + escapedStr
  38. if (!silent) {
  39. const token = state.push('text_special', '', 0)
  40. if (ch1 < 256 && ESCAPED[ch1] !== 0) {
  41. token.content = escapedStr
  42. } else {
  43. token.content = origStr
  44. }
  45. token.markup = origStr
  46. token.info = 'escape'
  47. }
  48. state.pos = pos + 1
  49. return true
  50. }