definition.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. 'use strict'
  2. var assert = require('assert')
  3. var codes = require('../character/codes.js')
  4. var markdownLineEnding = require('../character/markdown-line-ending.js')
  5. var markdownLineEndingOrSpace = require('../character/markdown-line-ending-or-space.js')
  6. var types = require('../constant/types.js')
  7. var normalizeIdentifier = require('../util/normalize-identifier.js')
  8. var factoryDestination = require('./factory-destination.js')
  9. var factoryLabel = require('./factory-label.js')
  10. var factorySpace = require('./factory-space.js')
  11. var factoryWhitespace = require('./factory-whitespace.js')
  12. var factoryTitle = require('./factory-title.js')
  13. function _interopDefaultLegacy(e) {
  14. return e && typeof e === 'object' && 'default' in e ? e : {default: e}
  15. }
  16. var assert__default = /*#__PURE__*/ _interopDefaultLegacy(assert)
  17. var definition = {
  18. name: 'definition',
  19. tokenize: tokenizeDefinition
  20. }
  21. var titleConstruct = {tokenize: tokenizeTitle, partial: true}
  22. function tokenizeDefinition(effects, ok, nok) {
  23. var self = this
  24. var identifier
  25. return start
  26. function start(code) {
  27. assert__default['default'](code === codes.leftSquareBracket, 'expected `[`')
  28. effects.enter(types.definition)
  29. return factoryLabel.call(
  30. self,
  31. effects,
  32. labelAfter,
  33. nok,
  34. types.definitionLabel,
  35. types.definitionLabelMarker,
  36. types.definitionLabelString
  37. )(code)
  38. }
  39. function labelAfter(code) {
  40. identifier = normalizeIdentifier(
  41. self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1)
  42. )
  43. if (code === codes.colon) {
  44. effects.enter(types.definitionMarker)
  45. effects.consume(code)
  46. effects.exit(types.definitionMarker)
  47. // Note: blank lines can’t exist in content.
  48. return factoryWhitespace(
  49. effects,
  50. factoryDestination(
  51. effects,
  52. effects.attempt(
  53. titleConstruct,
  54. factorySpace(effects, after, types.whitespace),
  55. factorySpace(effects, after, types.whitespace)
  56. ),
  57. nok,
  58. types.definitionDestination,
  59. types.definitionDestinationLiteral,
  60. types.definitionDestinationLiteralMarker,
  61. types.definitionDestinationRaw,
  62. types.definitionDestinationString
  63. )
  64. )
  65. }
  66. return nok(code)
  67. }
  68. function after(code) {
  69. if (code === codes.eof || markdownLineEnding(code)) {
  70. effects.exit(types.definition)
  71. if (self.parser.defined.indexOf(identifier) < 0) {
  72. self.parser.defined.push(identifier)
  73. }
  74. return ok(code)
  75. }
  76. return nok(code)
  77. }
  78. }
  79. function tokenizeTitle(effects, ok, nok) {
  80. return start
  81. function start(code) {
  82. return markdownLineEndingOrSpace(code)
  83. ? factoryWhitespace(effects, before)(code)
  84. : nok(code)
  85. }
  86. function before(code) {
  87. if (
  88. code === codes.quotationMark ||
  89. code === codes.apostrophe ||
  90. code === codes.leftParenthesis
  91. ) {
  92. return factoryTitle(
  93. effects,
  94. factorySpace(effects, after, types.whitespace),
  95. nok,
  96. types.definitionTitle,
  97. types.definitionTitleMarker,
  98. types.definitionTitleString
  99. )(code)
  100. }
  101. return nok(code)
  102. }
  103. function after(code) {
  104. return code === codes.eof || markdownLineEnding(code) ? ok(code) : nok(code)
  105. }
  106. }
  107. module.exports = definition