factory-destination.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. 'use strict'
  2. var asciiControl = require('../character/ascii-control.js')
  3. var codes = require('../character/codes.js')
  4. var markdownLineEndingOrSpace = require('../character/markdown-line-ending-or-space.js')
  5. var markdownLineEnding = require('../character/markdown-line-ending.js')
  6. var constants = require('../constant/constants.js')
  7. var types = require('../constant/types.js')
  8. // eslint-disable-next-line max-params
  9. function destinationFactory(
  10. effects,
  11. ok,
  12. nok,
  13. type,
  14. literalType,
  15. literalMarkerType,
  16. rawType,
  17. stringType,
  18. max
  19. ) {
  20. var limit = max || Infinity
  21. var balance = 0
  22. return start
  23. function start(code) {
  24. if (code === codes.lessThan) {
  25. effects.enter(type)
  26. effects.enter(literalType)
  27. effects.enter(literalMarkerType)
  28. effects.consume(code)
  29. effects.exit(literalMarkerType)
  30. return destinationEnclosedBefore
  31. }
  32. if (asciiControl(code) || code === codes.rightParenthesis) {
  33. return nok(code)
  34. }
  35. effects.enter(type)
  36. effects.enter(rawType)
  37. effects.enter(stringType)
  38. effects.enter(types.chunkString, {contentType: constants.contentTypeString})
  39. return destinationRaw(code)
  40. }
  41. function destinationEnclosedBefore(code) {
  42. if (code === codes.greaterThan) {
  43. effects.enter(literalMarkerType)
  44. effects.consume(code)
  45. effects.exit(literalMarkerType)
  46. effects.exit(literalType)
  47. effects.exit(type)
  48. return ok
  49. }
  50. effects.enter(stringType)
  51. effects.enter(types.chunkString, {contentType: constants.contentTypeString})
  52. return destinationEnclosed(code)
  53. }
  54. function destinationEnclosed(code) {
  55. if (code === codes.greaterThan) {
  56. effects.exit(types.chunkString)
  57. effects.exit(stringType)
  58. return destinationEnclosedBefore(code)
  59. }
  60. if (
  61. code === codes.eof ||
  62. code === codes.lessThan ||
  63. markdownLineEnding(code)
  64. ) {
  65. return nok(code)
  66. }
  67. effects.consume(code)
  68. return code === codes.backslash
  69. ? destinationEnclosedEscape
  70. : destinationEnclosed
  71. }
  72. function destinationEnclosedEscape(code) {
  73. if (
  74. code === codes.lessThan ||
  75. code === codes.greaterThan ||
  76. code === codes.backslash
  77. ) {
  78. effects.consume(code)
  79. return destinationEnclosed
  80. }
  81. return destinationEnclosed(code)
  82. }
  83. function destinationRaw(code) {
  84. if (code === codes.leftParenthesis) {
  85. if (++balance > limit) return nok(code)
  86. effects.consume(code)
  87. return destinationRaw
  88. }
  89. if (code === codes.rightParenthesis) {
  90. if (!balance--) {
  91. effects.exit(types.chunkString)
  92. effects.exit(stringType)
  93. effects.exit(rawType)
  94. effects.exit(type)
  95. return ok(code)
  96. }
  97. effects.consume(code)
  98. return destinationRaw
  99. }
  100. if (code === codes.eof || markdownLineEndingOrSpace(code)) {
  101. if (balance) return nok(code)
  102. effects.exit(types.chunkString)
  103. effects.exit(stringType)
  104. effects.exit(rawType)
  105. effects.exit(type)
  106. return ok(code)
  107. }
  108. if (asciiControl(code)) return nok(code)
  109. effects.consume(code)
  110. return code === codes.backslash ? destinationRawEscape : destinationRaw
  111. }
  112. function destinationRawEscape(code) {
  113. if (
  114. code === codes.leftParenthesis ||
  115. code === codes.rightParenthesis ||
  116. code === codes.backslash
  117. ) {
  118. effects.consume(code)
  119. return destinationRaw
  120. }
  121. return destinationRaw(code)
  122. }
  123. }
  124. module.exports = destinationFactory