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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. 'use strict'
  2. var decodeEntity = require('parse-entities/decode-entity.js')
  3. var assign = require('../constant/assign.js')
  4. var hasOwnProperty = require('../constant/has-own-property.js')
  5. var combineHtmlExtensions = require('../util/combine-html-extensions.js')
  6. var chunkedPush = require('../util/chunked-push.js')
  7. var miniflat = require('../util/miniflat.js')
  8. var normalizeIdentifier = require('../util/normalize-identifier.js')
  9. var normalizeUri = require('../util/normalize-uri.js')
  10. var safeFromInt = require('../util/safe-from-int.js')
  11. function _interopDefaultLegacy(e) {
  12. return e && typeof e === 'object' && 'default' in e ? e : {default: e}
  13. }
  14. var decodeEntity__default = /*#__PURE__*/ _interopDefaultLegacy(decodeEntity)
  15. // While micromark is a lexer/tokenizer, the common case of going from markdown
  16. // dealt with.
  17. // Technically, we can skip `>` and `"` in many cases, but CM includes them.
  18. var characterReferences = {
  19. '"': 'quot',
  20. '&': 'amp',
  21. '<': 'lt',
  22. '>': 'gt'
  23. } // These two are allowlists of essentially safe protocols for full URLs in
  24. // respectively the `href` (on `<a>`) and `src` (on `<img>`) attributes.
  25. // They are based on what is allowed on GitHub,
  26. // <https://github.com/syntax-tree/hast-util-sanitize/blob/9275b21/lib/github.json#L31>
  27. var protocolHref = /^(https?|ircs?|mailto|xmpp)$/i
  28. var protocolSrc = /^https?$/i
  29. function compileHtml(options) {
  30. // Configuration.
  31. // Includes `htmlExtensions` (an array of extensions), `defaultLineEnding` (a
  32. // preferred EOL), `allowDangerousProtocol` (whether to allow potential
  33. // dangerous protocols), and `allowDangerousHtml` (whether to allow potential
  34. // dangerous HTML).
  35. var settings = options || {} // Tags is needed because according to markdown, links and emphasis and
  36. // whatnot can exist in images, however, as HTML doesn’t allow content in
  37. // images, the tags are ignored in the `alt` attribute, but the content
  38. // remains.
  39. var tags = true // An object to track identifiers to media (URLs and titles) defined with
  40. // definitions.
  41. var definitions = {} // A lot of the handlers need to capture some of the output data, modify it
  42. // somehow, and then deal with it.
  43. // We do that by tracking a stack of buffers, that can be opened (with
  44. // `buffer`) and closed (with `resume`) to access them.
  45. var buffers = [[]] // As we can have links in images and the other way around, where the deepest
  46. // ones are closed first, we need to track which one we’re in.
  47. var mediaStack = [] // Same for tightness, which is specific to lists.
  48. // We need to track if we’re currently in a tight or loose container.
  49. var tightStack = []
  50. var defaultHandlers = {
  51. enter: {
  52. blockQuote: onenterblockquote,
  53. codeFenced: onentercodefenced,
  54. codeFencedFenceInfo: buffer,
  55. codeFencedFenceMeta: buffer,
  56. codeIndented: onentercodeindented,
  57. codeText: onentercodetext,
  58. content: onentercontent,
  59. definition: onenterdefinition,
  60. definitionDestinationString: onenterdefinitiondestinationstring,
  61. definitionLabelString: buffer,
  62. definitionTitleString: buffer,
  63. emphasis: onenteremphasis,
  64. htmlFlow: onenterhtmlflow,
  65. htmlText: onenterhtml,
  66. image: onenterimage,
  67. label: buffer,
  68. link: onenterlink,
  69. listItemMarker: onenterlistitemmarker,
  70. listItemValue: onenterlistitemvalue,
  71. listOrdered: onenterlistordered,
  72. listUnordered: onenterlistunordered,
  73. paragraph: onenterparagraph,
  74. reference: buffer,
  75. resource: onenterresource,
  76. resourceDestinationString: onenterresourcedestinationstring,
  77. resourceTitleString: buffer,
  78. setextHeading: onentersetextheading,
  79. strong: onenterstrong
  80. },
  81. exit: {
  82. atxHeading: onexitatxheading,
  83. atxHeadingSequence: onexitatxheadingsequence,
  84. autolinkEmail: onexitautolinkemail,
  85. autolinkProtocol: onexitautolinkprotocol,
  86. blockQuote: onexitblockquote,
  87. characterEscapeValue: onexitdata,
  88. characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker,
  89. characterReferenceMarkerNumeric: onexitcharacterreferencemarker,
  90. characterReferenceValue: onexitcharacterreferencevalue,
  91. codeFenced: onexitflowcode,
  92. codeFencedFence: onexitcodefencedfence,
  93. codeFencedFenceInfo: onexitcodefencedfenceinfo,
  94. codeFencedFenceMeta: resume,
  95. codeFlowValue: onexitcodeflowvalue,
  96. codeIndented: onexitflowcode,
  97. codeText: onexitcodetext,
  98. codeTextData: onexitdata,
  99. data: onexitdata,
  100. definition: onexitdefinition,
  101. definitionDestinationString: onexitdefinitiondestinationstring,
  102. definitionLabelString: onexitdefinitionlabelstring,
  103. definitionTitleString: onexitdefinitiontitlestring,
  104. emphasis: onexitemphasis,
  105. hardBreakEscape: onexithardbreak,
  106. hardBreakTrailing: onexithardbreak,
  107. htmlFlow: onexithtml,
  108. htmlFlowData: onexitdata,
  109. htmlText: onexithtml,
  110. htmlTextData: onexitdata,
  111. image: onexitmedia,
  112. label: onexitlabel,
  113. labelText: onexitlabeltext,
  114. lineEnding: onexitlineending,
  115. link: onexitmedia,
  116. listOrdered: onexitlistordered,
  117. listUnordered: onexitlistunordered,
  118. paragraph: onexitparagraph,
  119. reference: resume,
  120. referenceString: onexitreferencestring,
  121. resource: resume,
  122. resourceDestinationString: onexitresourcedestinationstring,
  123. resourceTitleString: onexitresourcetitlestring,
  124. setextHeading: onexitsetextheading,
  125. setextHeadingLineSequence: onexitsetextheadinglinesequence,
  126. setextHeadingText: onexitsetextheadingtext,
  127. strong: onexitstrong,
  128. thematicBreak: onexitthematicbreak
  129. }
  130. } // Combine the HTML extensions with the default handlers.
  131. // An HTML extension is an object whose fields are either `enter` or `exit`
  132. // (reflecting whether a token is entered or exited).
  133. // The values at such objects are names of tokens mapping to handlers.
  134. // Handlers are called, respectively when a token is opener or closed, with
  135. // that token, and a context as `this`.
  136. var handlers = combineHtmlExtensions(
  137. [defaultHandlers].concat(miniflat(settings.htmlExtensions))
  138. ) // Handlers do often need to keep track of some state.
  139. // That state is provided here as a key-value store (an object).
  140. var data = {
  141. tightStack: tightStack
  142. } // The context for handlers references a couple of useful functions.
  143. // In handlers from extensions, those can be accessed at `this`.
  144. // For the handlers here, they can be accessed directly.
  145. var context = {
  146. lineEndingIfNeeded: lineEndingIfNeeded,
  147. options: settings,
  148. encode: encode,
  149. raw: raw,
  150. tag: tag,
  151. buffer: buffer,
  152. resume: resume,
  153. setData: setData,
  154. getData: getData
  155. } // Generally, micromark copies line endings (`'\r'`, `'\n'`, `'\r\n'`) in the
  156. // markdown document over to the compiled HTML.
  157. // In some cases, such as `> a`, CommonMark requires that extra line endings
  158. // are added: `<blockquote>\n<p>a</p>\n</blockquote>`.
  159. // This variable hold the default line ending when given (or `undefined`),
  160. // and in the latter case will be updated to the first found line ending if
  161. // there is one.
  162. var lineEndingStyle = settings.defaultLineEnding // Return the function that handles a slice of events.
  163. return compile // Deal w/ a slice of events.
  164. // Return either the empty string if there’s nothing of note to return, or the
  165. // result when done.
  166. function compile(events) {
  167. // As definitions can come after references, we need to figure out the media
  168. // (urls and titles) defined by them before handling the references.
  169. // So, we do sort of what HTML does: put metadata at the start (in head), and
  170. // then put content after (`body`).
  171. var head = []
  172. var body = []
  173. var index
  174. var start
  175. var listStack
  176. var handler
  177. var result
  178. index = -1
  179. start = 0
  180. listStack = []
  181. while (++index < events.length) {
  182. // Figure out the line ending style used in the document.
  183. if (
  184. !lineEndingStyle &&
  185. (events[index][1].type === 'lineEnding' ||
  186. events[index][1].type === 'lineEndingBlank')
  187. ) {
  188. lineEndingStyle = events[index][2].sliceSerialize(events[index][1])
  189. } // Preprocess lists to infer whether the list is loose or not.
  190. if (
  191. events[index][1].type === 'listOrdered' ||
  192. events[index][1].type === 'listUnordered'
  193. ) {
  194. if (events[index][0] === 'enter') {
  195. listStack.push(index)
  196. } else {
  197. prepareList(events.slice(listStack.pop(), index))
  198. }
  199. } // Move definitions to the front.
  200. if (events[index][1].type === 'definition') {
  201. if (events[index][0] === 'enter') {
  202. body = chunkedPush(body, events.slice(start, index))
  203. start = index
  204. } else {
  205. head = chunkedPush(head, events.slice(start, index + 1))
  206. start = index + 1
  207. }
  208. }
  209. }
  210. head = chunkedPush(head, body)
  211. head = chunkedPush(head, events.slice(start))
  212. result = head
  213. index = -1 // Handle the start of the document, if defined.
  214. if (handlers.enter.null) {
  215. handlers.enter.null.call(context)
  216. } // Handle all events.
  217. while (++index < events.length) {
  218. handler = handlers[result[index][0]]
  219. if (hasOwnProperty.call(handler, result[index][1].type)) {
  220. handler[result[index][1].type].call(
  221. assign(
  222. {
  223. sliceSerialize: result[index][2].sliceSerialize
  224. },
  225. context
  226. ),
  227. result[index][1]
  228. )
  229. }
  230. } // Handle the end of the document, if defined.
  231. if (handlers.exit.null) {
  232. handlers.exit.null.call(context)
  233. }
  234. return buffers[0].join('')
  235. } // Figure out whether lists are loose or not.
  236. function prepareList(slice) {
  237. var length = slice.length - 1 // Skip close.
  238. var index = 0 // Skip open.
  239. var containerBalance = 0
  240. var loose
  241. var atMarker
  242. var event
  243. while (++index < length) {
  244. event = slice[index]
  245. if (event[1]._container) {
  246. atMarker = undefined
  247. if (event[0] === 'enter') {
  248. containerBalance++
  249. } else {
  250. containerBalance--
  251. }
  252. } else if (event[1].type === 'listItemPrefix') {
  253. if (event[0] === 'exit') {
  254. atMarker = true
  255. }
  256. } else if (event[1].type === 'linePrefix');
  257. else if (event[1].type === 'lineEndingBlank') {
  258. if (event[0] === 'enter' && !containerBalance) {
  259. if (atMarker) {
  260. atMarker = undefined
  261. } else {
  262. loose = true
  263. }
  264. }
  265. } else {
  266. atMarker = undefined
  267. }
  268. }
  269. slice[0][1]._loose = loose
  270. } // Set data into the key-value store.
  271. function setData(key, value) {
  272. data[key] = value
  273. } // Get data from the key-value store.
  274. function getData(key) {
  275. return data[key]
  276. } // Capture some of the output data.
  277. function buffer() {
  278. buffers.push([])
  279. } // Stop capturing and access the output data.
  280. function resume() {
  281. return buffers.pop().join('')
  282. } // Output (parts of) HTML tags.
  283. function tag(value) {
  284. if (!tags) return
  285. setData('lastWasTag', true)
  286. buffers[buffers.length - 1].push(value)
  287. } // Output raw data.
  288. function raw(value) {
  289. setData('lastWasTag')
  290. buffers[buffers.length - 1].push(value)
  291. } // Output an extra line ending.
  292. function lineEnding() {
  293. raw(lineEndingStyle || '\n')
  294. } // Output an extra line ending if the previous value wasn’t EOF/EOL.
  295. function lineEndingIfNeeded() {
  296. var buffer = buffers[buffers.length - 1]
  297. var slice = buffer[buffer.length - 1]
  298. var previous = slice ? slice.charCodeAt(slice.length - 1) : null
  299. if (previous === 10 || previous === 13 || previous === null) {
  300. return
  301. }
  302. lineEnding()
  303. } // Make a value safe for injection in HTML (except w/ `ignoreEncode`).
  304. function encode(value) {
  305. return getData('ignoreEncode') ? value : value.replace(/["&<>]/g, replace)
  306. function replace(value) {
  307. return '&' + characterReferences[value] + ';'
  308. }
  309. } // Make a value safe for injection as a URL.
  310. // This does encode unsafe characters with percent-encoding, skipping already
  311. // encoded sequences (`normalizeUri`).
  312. // Further unsafe characters are encoded as character references (`encode`).
  313. // Finally, if the URL includes an unknown protocol (such as a dangerous
  314. // example, `javascript:`), the value is ignored.
  315. function url(url, protocol) {
  316. var value = encode(normalizeUri(url || ''))
  317. var colon = value.indexOf(':')
  318. var questionMark = value.indexOf('?')
  319. var numberSign = value.indexOf('#')
  320. var slash = value.indexOf('/')
  321. if (
  322. settings.allowDangerousProtocol || // If there is no protocol, it’s relative.
  323. colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol.
  324. (slash > -1 && colon > slash) ||
  325. (questionMark > -1 && colon > questionMark) ||
  326. (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed.
  327. protocol.test(value.slice(0, colon))
  328. ) {
  329. return value
  330. }
  331. return ''
  332. } //
  333. // Handlers.
  334. //
  335. function onenterlistordered(token) {
  336. tightStack.push(!token._loose)
  337. lineEndingIfNeeded()
  338. tag('<ol')
  339. setData('expectFirstItem', true)
  340. }
  341. function onenterlistunordered(token) {
  342. tightStack.push(!token._loose)
  343. lineEndingIfNeeded()
  344. tag('<ul')
  345. setData('expectFirstItem', true)
  346. }
  347. function onenterlistitemvalue(token) {
  348. var value
  349. if (getData('expectFirstItem')) {
  350. value = parseInt(this.sliceSerialize(token), 10)
  351. if (value !== 1) {
  352. tag(' start="' + encode(String(value)) + '"')
  353. }
  354. }
  355. }
  356. function onenterlistitemmarker() {
  357. if (getData('expectFirstItem')) {
  358. tag('>')
  359. } else {
  360. onexitlistitem()
  361. }
  362. lineEndingIfNeeded()
  363. tag('<li>')
  364. setData('expectFirstItem') // “Hack” to prevent a line ending from showing up if the item is empty.
  365. setData('lastWasTag')
  366. }
  367. function onexitlistordered() {
  368. onexitlistitem()
  369. tightStack.pop()
  370. lineEnding()
  371. tag('</ol>')
  372. }
  373. function onexitlistunordered() {
  374. onexitlistitem()
  375. tightStack.pop()
  376. lineEnding()
  377. tag('</ul>')
  378. }
  379. function onexitlistitem() {
  380. if (getData('lastWasTag') && !getData('slurpAllLineEndings')) {
  381. lineEndingIfNeeded()
  382. }
  383. tag('</li>')
  384. setData('slurpAllLineEndings')
  385. }
  386. function onenterblockquote() {
  387. tightStack.push(false)
  388. lineEndingIfNeeded()
  389. tag('<blockquote>')
  390. }
  391. function onexitblockquote() {
  392. tightStack.pop()
  393. lineEndingIfNeeded()
  394. tag('</blockquote>')
  395. setData('slurpAllLineEndings')
  396. }
  397. function onenterparagraph() {
  398. if (!tightStack[tightStack.length - 1]) {
  399. lineEndingIfNeeded()
  400. tag('<p>')
  401. }
  402. setData('slurpAllLineEndings')
  403. }
  404. function onexitparagraph() {
  405. if (tightStack[tightStack.length - 1]) {
  406. setData('slurpAllLineEndings', true)
  407. } else {
  408. tag('</p>')
  409. }
  410. }
  411. function onentercodefenced() {
  412. lineEndingIfNeeded()
  413. tag('<pre><code')
  414. setData('fencesCount', 0)
  415. }
  416. function onexitcodefencedfenceinfo() {
  417. var value = resume()
  418. tag(' class="language-' + value + '"')
  419. }
  420. function onexitcodefencedfence() {
  421. if (!getData('fencesCount')) {
  422. tag('>')
  423. setData('fencedCodeInside', true)
  424. setData('slurpOneLineEnding', true)
  425. }
  426. setData('fencesCount', getData('fencesCount') + 1)
  427. }
  428. function onentercodeindented() {
  429. lineEndingIfNeeded()
  430. tag('<pre><code>')
  431. }
  432. function onexitflowcode() {
  433. // Send an extra line feed if we saw data.
  434. if (getData('flowCodeSeenData')) lineEndingIfNeeded()
  435. tag('</code></pre>')
  436. if (getData('fencesCount') < 2) lineEndingIfNeeded()
  437. setData('flowCodeSeenData')
  438. setData('fencesCount')
  439. setData('slurpOneLineEnding')
  440. }
  441. function onenterimage() {
  442. mediaStack.push({
  443. image: true
  444. })
  445. tags = undefined // Disallow tags.
  446. }
  447. function onenterlink() {
  448. mediaStack.push({})
  449. }
  450. function onexitlabeltext(token) {
  451. mediaStack[mediaStack.length - 1].labelId = this.sliceSerialize(token)
  452. }
  453. function onexitlabel() {
  454. mediaStack[mediaStack.length - 1].label = resume()
  455. }
  456. function onexitreferencestring(token) {
  457. mediaStack[mediaStack.length - 1].referenceId = this.sliceSerialize(token)
  458. }
  459. function onenterresource() {
  460. buffer() // We can have line endings in the resource, ignore them.
  461. mediaStack[mediaStack.length - 1].destination = ''
  462. }
  463. function onenterresourcedestinationstring() {
  464. buffer() // Ignore encoding the result, as we’ll first percent encode the url and
  465. // encode manually after.
  466. setData('ignoreEncode', true)
  467. }
  468. function onexitresourcedestinationstring() {
  469. mediaStack[mediaStack.length - 1].destination = resume()
  470. setData('ignoreEncode')
  471. }
  472. function onexitresourcetitlestring() {
  473. mediaStack[mediaStack.length - 1].title = resume()
  474. }
  475. function onexitmedia() {
  476. var index = mediaStack.length - 1 // Skip current.
  477. var media = mediaStack[index]
  478. var context =
  479. media.destination === undefined
  480. ? definitions[normalizeIdentifier(media.referenceId || media.labelId)]
  481. : media
  482. tags = true
  483. while (index--) {
  484. if (mediaStack[index].image) {
  485. tags = undefined
  486. break
  487. }
  488. }
  489. if (media.image) {
  490. tag('<img src="' + url(context.destination, protocolSrc) + '" alt="')
  491. raw(media.label)
  492. tag('"')
  493. } else {
  494. tag('<a href="' + url(context.destination, protocolHref) + '"')
  495. }
  496. tag(context.title ? ' title="' + context.title + '"' : '')
  497. if (media.image) {
  498. tag(' />')
  499. } else {
  500. tag('>')
  501. raw(media.label)
  502. tag('</a>')
  503. }
  504. mediaStack.pop()
  505. }
  506. function onenterdefinition() {
  507. buffer()
  508. mediaStack.push({})
  509. }
  510. function onexitdefinitionlabelstring(token) {
  511. // Discard label, use the source content instead.
  512. resume()
  513. mediaStack[mediaStack.length - 1].labelId = this.sliceSerialize(token)
  514. }
  515. function onenterdefinitiondestinationstring() {
  516. buffer()
  517. setData('ignoreEncode', true)
  518. }
  519. function onexitdefinitiondestinationstring() {
  520. mediaStack[mediaStack.length - 1].destination = resume()
  521. setData('ignoreEncode')
  522. }
  523. function onexitdefinitiontitlestring() {
  524. mediaStack[mediaStack.length - 1].title = resume()
  525. }
  526. function onexitdefinition() {
  527. var id = normalizeIdentifier(mediaStack[mediaStack.length - 1].labelId)
  528. resume()
  529. if (!hasOwnProperty.call(definitions, id)) {
  530. definitions[id] = mediaStack[mediaStack.length - 1]
  531. }
  532. mediaStack.pop()
  533. }
  534. function onentercontent() {
  535. setData('slurpAllLineEndings', true)
  536. }
  537. function onexitatxheadingsequence(token) {
  538. // Exit for further sequences.
  539. if (getData('headingRank')) return
  540. setData('headingRank', this.sliceSerialize(token).length)
  541. lineEndingIfNeeded()
  542. tag('<h' + getData('headingRank') + '>')
  543. }
  544. function onentersetextheading() {
  545. buffer()
  546. setData('slurpAllLineEndings')
  547. }
  548. function onexitsetextheadingtext() {
  549. setData('slurpAllLineEndings', true)
  550. }
  551. function onexitatxheading() {
  552. tag('</h' + getData('headingRank') + '>')
  553. setData('headingRank')
  554. }
  555. function onexitsetextheadinglinesequence(token) {
  556. setData(
  557. 'headingRank',
  558. this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2
  559. )
  560. }
  561. function onexitsetextheading() {
  562. var value = resume()
  563. lineEndingIfNeeded()
  564. tag('<h' + getData('headingRank') + '>')
  565. raw(value)
  566. tag('</h' + getData('headingRank') + '>')
  567. setData('slurpAllLineEndings')
  568. setData('headingRank')
  569. }
  570. function onexitdata(token) {
  571. raw(encode(this.sliceSerialize(token)))
  572. }
  573. function onexitlineending(token) {
  574. if (getData('slurpAllLineEndings')) {
  575. return
  576. }
  577. if (getData('slurpOneLineEnding')) {
  578. setData('slurpOneLineEnding')
  579. return
  580. }
  581. if (getData('inCodeText')) {
  582. raw(' ')
  583. return
  584. }
  585. raw(encode(this.sliceSerialize(token)))
  586. }
  587. function onexitcodeflowvalue(token) {
  588. raw(encode(this.sliceSerialize(token)))
  589. setData('flowCodeSeenData', true)
  590. }
  591. function onexithardbreak() {
  592. tag('<br />')
  593. }
  594. function onenterhtmlflow() {
  595. lineEndingIfNeeded()
  596. onenterhtml()
  597. }
  598. function onexithtml() {
  599. setData('ignoreEncode')
  600. }
  601. function onenterhtml() {
  602. if (settings.allowDangerousHtml) {
  603. setData('ignoreEncode', true)
  604. }
  605. }
  606. function onenteremphasis() {
  607. tag('<em>')
  608. }
  609. function onenterstrong() {
  610. tag('<strong>')
  611. }
  612. function onentercodetext() {
  613. setData('inCodeText', true)
  614. tag('<code>')
  615. }
  616. function onexitcodetext() {
  617. setData('inCodeText')
  618. tag('</code>')
  619. }
  620. function onexitemphasis() {
  621. tag('</em>')
  622. }
  623. function onexitstrong() {
  624. tag('</strong>')
  625. }
  626. function onexitthematicbreak() {
  627. lineEndingIfNeeded()
  628. tag('<hr />')
  629. }
  630. function onexitcharacterreferencemarker(token) {
  631. setData('characterReferenceType', token.type)
  632. }
  633. function onexitcharacterreferencevalue(token) {
  634. var value = this.sliceSerialize(token)
  635. value = getData('characterReferenceType')
  636. ? safeFromInt(
  637. value,
  638. getData('characterReferenceType') ===
  639. 'characterReferenceMarkerNumeric'
  640. ? 10
  641. : 16
  642. )
  643. : decodeEntity__default['default'](value)
  644. raw(encode(value))
  645. setData('characterReferenceType')
  646. }
  647. function onexitautolinkprotocol(token) {
  648. var uri = this.sliceSerialize(token)
  649. tag('<a href="' + url(uri, protocolHref) + '">')
  650. raw(encode(uri))
  651. tag('</a>')
  652. }
  653. function onexitautolinkemail(token) {
  654. var uri = this.sliceSerialize(token)
  655. tag('<a href="' + url('mailto:' + uri, protocolHref) + '">')
  656. raw(encode(uri))
  657. tag('</a>')
  658. }
  659. }
  660. module.exports = compileHtml