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 7.5KB

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