index.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import {decodeNamedCharacterReference} from 'decode-named-character-reference'
  2. import {decodeNumericCharacterReference} from 'micromark-util-decode-numeric-character-reference'
  3. import {codes, constants} from 'micromark-util-symbol'
  4. const characterEscapeOrReference =
  5. /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi
  6. /**
  7. * Decode markdown strings (which occur in places such as fenced code info
  8. * strings, destinations, labels, and titles).
  9. *
  10. * The “string” content type allows character escapes and -references.
  11. * This decodes those.
  12. *
  13. * @param {string} value
  14. * Value to decode.
  15. * @returns {string}
  16. * Decoded value.
  17. */
  18. export function decodeString(value) {
  19. return value.replace(characterEscapeOrReference, decode)
  20. }
  21. /**
  22. * @param {string} $0
  23. * @param {string} $1
  24. * @param {string} $2
  25. * @returns {string}
  26. */
  27. function decode($0, $1, $2) {
  28. if ($1) {
  29. // Escape.
  30. return $1
  31. }
  32. // Reference.
  33. const head = $2.charCodeAt(0)
  34. if (head === codes.numberSign) {
  35. const head = $2.charCodeAt(1)
  36. const hex = head === codes.lowercaseX || head === codes.uppercaseX
  37. return decodeNumericCharacterReference(
  38. $2.slice(hex ? 2 : 1),
  39. hex ? constants.numericBaseHexadecimal : constants.numericBaseDecimal
  40. )
  41. }
  42. return decodeNamedCharacterReference($2) || $0
  43. }