backticks.mjs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // Parse backticks
  2. export default function backtick (state, silent) {
  3. let pos = state.pos
  4. const ch = state.src.charCodeAt(pos)
  5. if (ch !== 0x60/* ` */) { return false }
  6. const start = pos
  7. pos++
  8. const max = state.posMax
  9. // scan marker length
  10. while (pos < max && state.src.charCodeAt(pos) === 0x60/* ` */) { pos++ }
  11. const marker = state.src.slice(start, pos)
  12. const openerLength = marker.length
  13. if (state.backticksScanned && (state.backticks[openerLength] || 0) <= start) {
  14. if (!silent) state.pending += marker
  15. state.pos += openerLength
  16. return true
  17. }
  18. let matchEnd = pos
  19. let matchStart
  20. // Nothing found in the cache, scan until the end of the line (or until marker is found)
  21. while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) {
  22. matchEnd = matchStart + 1
  23. // scan marker length
  24. while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60/* ` */) { matchEnd++ }
  25. const closerLength = matchEnd - matchStart
  26. if (closerLength === openerLength) {
  27. // Found matching closer length.
  28. if (!silent) {
  29. const token = state.push('code_inline', 'code', 0)
  30. token.markup = marker
  31. token.content = state.src.slice(pos, matchStart)
  32. .replace(/\n/g, ' ')
  33. .replace(/^ (.+) $/, '$1')
  34. }
  35. state.pos = matchEnd
  36. return true
  37. }
  38. // Some different length found, put it in cache as upper limit of where closer can be found
  39. state.backticks[closerLength] = matchStart
  40. }
  41. // Scanned through the end, didn't find anything
  42. state.backticksScanned = true
  43. if (!silent) state.pending += marker
  44. state.pos += openerLength
  45. return true
  46. }