definition.mjs 3.1 KB

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