autolink.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. 'use strict'
  2. var assert = require('assert')
  3. var asciiAlpha = require('../character/ascii-alpha.js')
  4. var asciiAlphanumeric = require('../character/ascii-alphanumeric.js')
  5. var asciiAtext = require('../character/ascii-atext.js')
  6. var asciiControl = require('../character/ascii-control.js')
  7. var codes = require('../character/codes.js')
  8. var constants = require('../constant/constants.js')
  9. var types = require('../constant/types.js')
  10. function _interopDefaultLegacy(e) {
  11. return e && typeof e === 'object' && 'default' in e ? e : {default: e}
  12. }
  13. var assert__default = /*#__PURE__*/ _interopDefaultLegacy(assert)
  14. var autolink = {
  15. name: 'autolink',
  16. tokenize: tokenizeAutolink
  17. }
  18. function tokenizeAutolink(effects, ok, nok) {
  19. var size = 1
  20. return start
  21. function start(code) {
  22. assert__default['default'](code === codes.lessThan, 'expected `<`')
  23. effects.enter(types.autolink)
  24. effects.enter(types.autolinkMarker)
  25. effects.consume(code)
  26. effects.exit(types.autolinkMarker)
  27. effects.enter(types.autolinkProtocol)
  28. return open
  29. }
  30. function open(code) {
  31. if (asciiAlpha(code)) {
  32. effects.consume(code)
  33. return schemeOrEmailAtext
  34. }
  35. return asciiAtext(code) ? emailAtext(code) : nok(code)
  36. }
  37. function schemeOrEmailAtext(code) {
  38. return code === codes.plusSign ||
  39. code === codes.dash ||
  40. code === codes.dot ||
  41. asciiAlphanumeric(code)
  42. ? schemeInsideOrEmailAtext(code)
  43. : emailAtext(code)
  44. }
  45. function schemeInsideOrEmailAtext(code) {
  46. if (code === codes.colon) {
  47. effects.consume(code)
  48. return urlInside
  49. }
  50. if (
  51. (code === codes.plusSign ||
  52. code === codes.dash ||
  53. code === codes.dot ||
  54. asciiAlphanumeric(code)) &&
  55. size++ < constants.autolinkSchemeSizeMax
  56. ) {
  57. effects.consume(code)
  58. return schemeInsideOrEmailAtext
  59. }
  60. return emailAtext(code)
  61. }
  62. function urlInside(code) {
  63. if (code === codes.greaterThan) {
  64. effects.exit(types.autolinkProtocol)
  65. return end(code)
  66. }
  67. if (code === codes.space || code === codes.lessThan || asciiControl(code)) {
  68. return nok(code)
  69. }
  70. effects.consume(code)
  71. return urlInside
  72. }
  73. function emailAtext(code) {
  74. if (code === codes.atSign) {
  75. effects.consume(code)
  76. size = 0
  77. return emailAtSignOrDot
  78. }
  79. if (asciiAtext(code)) {
  80. effects.consume(code)
  81. return emailAtext
  82. }
  83. return nok(code)
  84. }
  85. function emailAtSignOrDot(code) {
  86. return asciiAlphanumeric(code) ? emailLabel(code) : nok(code)
  87. }
  88. function emailLabel(code) {
  89. if (code === codes.dot) {
  90. effects.consume(code)
  91. size = 0
  92. return emailAtSignOrDot
  93. }
  94. if (code === codes.greaterThan) {
  95. // Exit, then change the type.
  96. effects.exit(types.autolinkProtocol).type = types.autolinkEmail
  97. return end(code)
  98. }
  99. return emailValue(code)
  100. }
  101. function emailValue(code) {
  102. if (
  103. (code === codes.dash || asciiAlphanumeric(code)) &&
  104. size++ < constants.autolinkDomainSizeMax
  105. ) {
  106. effects.consume(code)
  107. return code === codes.dash ? emailValue : emailLabel
  108. }
  109. return nok(code)
  110. }
  111. function end(code) {
  112. assert__default['default'].equal(code, codes.greaterThan, 'expected `>`')
  113. effects.enter(types.autolinkMarker)
  114. effects.consume(code)
  115. effects.exit(types.autolinkMarker)
  116. effects.exit(types.autolink)
  117. return ok
  118. }
  119. }
  120. module.exports = autolink