Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

label-end.js 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. 'use strict'
  2. var assert = require('assert')
  3. var codes = require('../character/codes.js')
  4. var markdownLineEndingOrSpace = require('../character/markdown-line-ending-or-space.js')
  5. var constants = require('../constant/constants.js')
  6. var types = require('../constant/types.js')
  7. var chunkedPush = require('../util/chunked-push.js')
  8. var chunkedSplice = require('../util/chunked-splice.js')
  9. var normalizeIdentifier = require('../util/normalize-identifier.js')
  10. var resolveAll = require('../util/resolve-all.js')
  11. var shallow = require('../util/shallow.js')
  12. var factoryDestination = require('./factory-destination.js')
  13. var factoryLabel = require('./factory-label.js')
  14. var factoryTitle = require('./factory-title.js')
  15. var factoryWhitespace = require('./factory-whitespace.js')
  16. function _interopDefaultLegacy(e) {
  17. return e && typeof e === 'object' && 'default' in e ? e : {default: e}
  18. }
  19. var assert__default = /*#__PURE__*/ _interopDefaultLegacy(assert)
  20. var labelEnd = {
  21. name: 'labelEnd',
  22. tokenize: tokenizeLabelEnd,
  23. resolveTo: resolveToLabelEnd,
  24. resolveAll: resolveAllLabelEnd
  25. }
  26. var resourceConstruct = {tokenize: tokenizeResource}
  27. var fullReferenceConstruct = {tokenize: tokenizeFullReference}
  28. var collapsedReferenceConstruct = {tokenize: tokenizeCollapsedReference}
  29. function resolveAllLabelEnd(events) {
  30. var index = -1
  31. var token
  32. while (++index < events.length) {
  33. token = events[index][1]
  34. if (
  35. !token._used &&
  36. (token.type === types.labelImage ||
  37. token.type === types.labelLink ||
  38. token.type === types.labelEnd)
  39. ) {
  40. // Remove the marker.
  41. events.splice(index + 1, token.type === types.labelImage ? 4 : 2)
  42. token.type = types.data
  43. index++
  44. }
  45. }
  46. return events
  47. }
  48. function resolveToLabelEnd(events, context) {
  49. var index = events.length
  50. var offset = 0
  51. var group
  52. var label
  53. var text
  54. var token
  55. var open
  56. var close
  57. var media
  58. // Find an opening.
  59. while (index--) {
  60. token = events[index][1]
  61. if (open) {
  62. // If we see another link, or inactive link label, we’ve been here before.
  63. if (
  64. token.type === types.link ||
  65. (token.type === types.labelLink && token._inactive)
  66. ) {
  67. break
  68. }
  69. // Mark other link openings as inactive, as we can’t have links in
  70. // links.
  71. if (events[index][0] === 'enter' && token.type === types.labelLink) {
  72. token._inactive = true
  73. }
  74. } else if (close) {
  75. if (
  76. events[index][0] === 'enter' &&
  77. (token.type === types.labelImage || token.type === types.labelLink) &&
  78. !token._balanced
  79. ) {
  80. open = index
  81. if (token.type !== types.labelLink) {
  82. offset = 2
  83. break
  84. }
  85. }
  86. } else if (token.type === types.labelEnd) {
  87. close = index
  88. }
  89. }
  90. group = {
  91. type: events[open][1].type === types.labelLink ? types.link : types.image,
  92. start: shallow(events[open][1].start),
  93. end: shallow(events[events.length - 1][1].end)
  94. }
  95. label = {
  96. type: types.label,
  97. start: shallow(events[open][1].start),
  98. end: shallow(events[close][1].end)
  99. }
  100. text = {
  101. type: types.labelText,
  102. start: shallow(events[open + offset + 2][1].end),
  103. end: shallow(events[close - 2][1].start)
  104. }
  105. media = [
  106. ['enter', group, context],
  107. ['enter', label, context]
  108. ]
  109. // Opening marker.
  110. media = chunkedPush(media, events.slice(open + 1, open + offset + 3))
  111. // Text open.
  112. media = chunkedPush(media, [['enter', text, context]])
  113. // Between.
  114. media = chunkedPush(
  115. media,
  116. resolveAll(
  117. context.parser.constructs.insideSpan.null,
  118. events.slice(open + offset + 4, close - 3),
  119. context
  120. )
  121. )
  122. // Text close, marker close, label close.
  123. media = chunkedPush(media, [
  124. ['exit', text, context],
  125. events[close - 2],
  126. events[close - 1],
  127. ['exit', label, context]
  128. ])
  129. // Reference, resource, or so.
  130. media = chunkedPush(media, events.slice(close + 1))
  131. // Media close.
  132. media = chunkedPush(media, [['exit', group, context]])
  133. chunkedSplice(events, open, events.length, media)
  134. return events
  135. }
  136. function tokenizeLabelEnd(effects, ok, nok) {
  137. var self = this
  138. var index = self.events.length
  139. var labelStart
  140. var defined
  141. // Find an opening.
  142. while (index--) {
  143. if (
  144. (self.events[index][1].type === types.labelImage ||
  145. self.events[index][1].type === types.labelLink) &&
  146. !self.events[index][1]._balanced
  147. ) {
  148. labelStart = self.events[index][1]
  149. break
  150. }
  151. }
  152. return start
  153. function start(code) {
  154. assert__default['default'](
  155. code === codes.rightSquareBracket,
  156. 'expected `]`'
  157. )
  158. if (!labelStart) {
  159. return nok(code)
  160. }
  161. // It’s a balanced bracket, but contains a link.
  162. if (labelStart._inactive) return balanced(code)
  163. defined =
  164. self.parser.defined.indexOf(
  165. normalizeIdentifier(
  166. self.sliceSerialize({start: labelStart.end, end: self.now()})
  167. )
  168. ) > -1
  169. effects.enter(types.labelEnd)
  170. effects.enter(types.labelMarker)
  171. effects.consume(code)
  172. effects.exit(types.labelMarker)
  173. effects.exit(types.labelEnd)
  174. return afterLabelEnd
  175. }
  176. function afterLabelEnd(code) {
  177. // Resource: `[asd](fgh)`.
  178. if (code === codes.leftParenthesis) {
  179. return effects.attempt(
  180. resourceConstruct,
  181. ok,
  182. defined ? ok : balanced
  183. )(code)
  184. }
  185. // Collapsed (`[asd][]`) or full (`[asd][fgh]`) reference?
  186. if (code === codes.leftSquareBracket) {
  187. return effects.attempt(
  188. fullReferenceConstruct,
  189. ok,
  190. defined
  191. ? effects.attempt(collapsedReferenceConstruct, ok, balanced)
  192. : balanced
  193. )(code)
  194. }
  195. // Shortcut reference: `[asd]`?
  196. return defined ? ok(code) : balanced(code)
  197. }
  198. function balanced(code) {
  199. labelStart._balanced = true
  200. return nok(code)
  201. }
  202. }
  203. function tokenizeResource(effects, ok, nok) {
  204. return start
  205. function start(code) {
  206. assert__default['default'].equal(
  207. code,
  208. codes.leftParenthesis,
  209. 'expected left paren'
  210. )
  211. effects.enter(types.resource)
  212. effects.enter(types.resourceMarker)
  213. effects.consume(code)
  214. effects.exit(types.resourceMarker)
  215. return factoryWhitespace(effects, open)
  216. }
  217. function open(code) {
  218. if (code === codes.rightParenthesis) {
  219. return end(code)
  220. }
  221. return factoryDestination(
  222. effects,
  223. destinationAfter,
  224. nok,
  225. types.resourceDestination,
  226. types.resourceDestinationLiteral,
  227. types.resourceDestinationLiteralMarker,
  228. types.resourceDestinationRaw,
  229. types.resourceDestinationString,
  230. constants.linkResourceDestinationBalanceMax
  231. )(code)
  232. }
  233. function destinationAfter(code) {
  234. return markdownLineEndingOrSpace(code)
  235. ? factoryWhitespace(effects, between)(code)
  236. : end(code)
  237. }
  238. function between(code) {
  239. if (
  240. code === codes.quotationMark ||
  241. code === codes.apostrophe ||
  242. code === codes.leftParenthesis
  243. ) {
  244. return factoryTitle(
  245. effects,
  246. factoryWhitespace(effects, end),
  247. nok,
  248. types.resourceTitle,
  249. types.resourceTitleMarker,
  250. types.resourceTitleString
  251. )(code)
  252. }
  253. return end(code)
  254. }
  255. function end(code) {
  256. if (code === codes.rightParenthesis) {
  257. effects.enter(types.resourceMarker)
  258. effects.consume(code)
  259. effects.exit(types.resourceMarker)
  260. effects.exit(types.resource)
  261. return ok
  262. }
  263. return nok(code)
  264. }
  265. }
  266. function tokenizeFullReference(effects, ok, nok) {
  267. var self = this
  268. return start
  269. function start(code) {
  270. assert__default['default'].equal(
  271. code,
  272. codes.leftSquareBracket,
  273. 'expected left bracket'
  274. )
  275. return factoryLabel.call(
  276. self,
  277. effects,
  278. afterLabel,
  279. nok,
  280. types.reference,
  281. types.referenceMarker,
  282. types.referenceString
  283. )(code)
  284. }
  285. function afterLabel(code) {
  286. return self.parser.defined.indexOf(
  287. normalizeIdentifier(
  288. self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1)
  289. )
  290. ) < 0
  291. ? nok(code)
  292. : ok(code)
  293. }
  294. }
  295. function tokenizeCollapsedReference(effects, ok, nok) {
  296. return start
  297. function start(code) {
  298. assert__default['default'].equal(
  299. code,
  300. codes.leftSquareBracket,
  301. 'expected left bracket'
  302. )
  303. effects.enter(types.reference)
  304. effects.enter(types.referenceMarker)
  305. effects.consume(code)
  306. effects.exit(types.referenceMarker)
  307. return open
  308. }
  309. function open(code) {
  310. if (code === codes.rightSquareBracket) {
  311. effects.enter(types.referenceMarker)
  312. effects.consume(code)
  313. effects.exit(types.referenceMarker)
  314. effects.exit(types.reference)
  315. return ok
  316. }
  317. return nok(code)
  318. }
  319. }
  320. module.exports = labelEnd