Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mdast-util-from-markdown

Package Overview
Dependencies
Maintainers
2
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mdast-util-from-markdown - npm Package Compare versions

Comparing version 0.8.0 to 0.8.1

dist/index.js

773

index.js
'use strict'
module.exports = fromMarkdown
var decode = require('parse-entities/decode-entity')
var toString = require('mdast-util-to-string')
var codes = require('micromark/dist/character/codes')
var constants = require('micromark/dist/constant/constants')
var own = require('micromark/dist/constant/has-own-property')
var types = require('micromark/dist/constant/types')
var normalizeIdentifier = require('micromark/dist/util/normalize-identifier')
var safeFromInt = require('micromark/dist/util/safe-from-int')
var parser = require('micromark/dist/parse')
var preprocessor = require('micromark/dist/preprocess')
var postprocess = require('micromark/dist/postprocess')
function fromMarkdown(value, encoding, options) {
if (typeof encoding !== 'string') {
options = encoding
encoding = undefined
}
return compiler(options)(
postprocess(
parser(options).document().write(preprocessor()(value, encoding, true))
)
)
}
// Note this compiler only understand complete buffering, not streaming.
function compiler(options) {
var settings = options || {}
var config = configure(
{
canContainEols: [
'emphasis',
'fragment',
'heading',
'paragraph',
'strong'
],
enter: {
autolink: opener(link),
autolinkProtocol: onenterdata,
autolinkEmail: onenterdata,
atxHeading: opener(heading),
blockQuote: opener(blockQuote),
characterEscape: onenterdata,
characterReference: onenterdata,
codeFenced: opener(codeFlow),
codeFencedFenceInfo: buffer,
codeFencedFenceMeta: buffer,
codeIndented: opener(codeFlow, buffer),
codeText: opener(codeText, buffer),
codeTextData: onenterdata,
data: onenterdata,
codeFlowValue: onenterdata,
definition: opener(definition),
definitionDestinationString: buffer,
definitionLabelString: buffer,
definitionTitleString: buffer,
emphasis: opener(emphasis),
hardBreakEscape: opener(hardBreak),
hardBreakTrailing: opener(hardBreak),
htmlFlow: opener(html, buffer),
htmlFlowData: onenterdata,
htmlText: opener(html, buffer),
htmlTextData: onenterdata,
image: opener(image),
label: buffer,
link: opener(link),
listItem: opener(listItem),
listItemValue: onenterlistitemvalue,
listOrdered: opener(list, onenterlistordered),
listUnordered: opener(list),
paragraph: opener(paragraph),
reference: onenterreference,
referenceString: buffer,
resourceDestinationString: buffer,
resourceTitleString: buffer,
setextHeading: opener(heading),
strong: opener(strong),
thematicBreak: opener(thematicBreak)
},
exit: {
atxHeading: closer(),
atxHeadingSequence: onexitatxheadingsequence,
autolink: closer(),
autolinkEmail: onexitautolinkemail,
autolinkProtocol: onexitautolinkprotocol,
blockQuote: closer(),
characterEscapeValue: onexitdata,
characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker,
characterReferenceMarkerNumeric: onexitcharacterreferencemarker,
characterReferenceValue: closer(onexitcharacterreferencevalue),
codeFenced: closer(onexitcodefenced),
codeFencedFence: onexitcodefencedfence,
codeFencedFenceInfo: onexitcodefencedfenceinfo,
codeFencedFenceMeta: onexitcodefencedfencemeta,
codeFlowValue: onexitdata,
codeIndented: closer(onexitcodeindented),
codeText: closer(onexitcodetext),
codeTextData: onexitdata,
data: onexitdata,
definition: closer(),
definitionDestinationString: onexitdefinitiondestinationstring,
definitionLabelString: onexitdefinitionlabelstring,
definitionTitleString: onexitdefinitiontitlestring,
emphasis: closer(),
hardBreakEscape: closer(onexithardbreak),
hardBreakTrailing: closer(onexithardbreak),
htmlFlow: closer(onexithtmlflow),
htmlFlowData: onexitdata,
htmlText: closer(onexithtmltext),
htmlTextData: onexitdata,
image: closer(onexitimage),
label: onexitlabel,
labelText: onexitlabeltext,
lineEnding: onexitlineending,
link: closer(onexitlink),
listItem: closer(),
listOrdered: closer(),
listUnordered: closer(),
paragraph: closer(),
referenceString: onexitreferencestring,
resourceDestinationString: onexitresourcedestinationstring,
resourceTitleString: onexitresourcetitlestring,
resource: onexitresource,
setextHeading: closer(onexitsetextheading),
setextHeadingLineSequence: onexitsetextheadinglinesequence,
setextHeadingText: onexitsetextheadingtext,
strong: closer(),
thematicBreak: closer()
}
},
settings.mdastExtensions || []
)
var data = {}
return compile
function compile(events) {
var stack = [{type: 'root', children: []}]
var index = -1
var listStack = []
var length
var handler
var listStart
var event
while (++index < events.length) {
event = events[index]
// We preprocess lists to add `listItem` tokens, and to infer whether
// items the list itself are spread out.
if (
event[1].type === types.listOrdered ||
event[1].type === types.listUnordered
) {
if (event[0] === 'enter') {
listStack.push(index)
} else {
listStart = listStack.pop(index)
index = prepareList(events, listStart, index)
}
}
}
index = -1
length = events.length
while (++index < length) {
handler = config[events[index][0]]
if (own.call(handler, events[index][1].type)) {
handler[events[index][1].type].call(
{
stack: stack,
config: config,
enter: enter,
exit: exit,
buffer: buffer,
resume: resume,
sliceSerialize: events[index][2].sliceSerialize,
setData: setData,
getData: getData
},
events[index][1]
)
}
}
// Figure out `root` position.
stack[0].position = {
start: point(
length ? events[0][1].start : {line: 1, column: 1, offset: 0}
),
end: point(
length
? events[events.length - 2][1].end
: {line: 1, column: 1, offset: 0}
)
}
return stack[0]
}
function prepareList(events, start, length) {
var index = start - 1
var containerBalance = -1
var listSpread = false
var listItem
var tailIndex
var lineIndex
var tailEvent
var event
var firstBlankLineIndex
var atMarker
while (++index <= length) {
event = events[index]
if (
event[1].type === types.listUnordered ||
event[1].type === types.listOrdered ||
event[1].type === types.blockQuote
) {
if (event[0] === 'enter') {
containerBalance++
} else {
containerBalance--
}
atMarker = undefined
} else if (event[1].type === types.lineEndingBlank) {
if (event[0] === 'enter') {
if (
listItem &&
!atMarker &&
!containerBalance &&
!firstBlankLineIndex
) {
firstBlankLineIndex = index
}
atMarker = undefined
}
} else if (
event[1].type === types.linePrefix ||
event[1].type === types.listItemValue ||
event[1].type === types.listItemMarker ||
event[1].type === types.listItemPrefix ||
event[1].type === types.listItemPrefixWhitespace
) {
// Empty.
} else {
atMarker = undefined
}
if (
(!containerBalance &&
event[0] === 'enter' &&
event[1].type === types.listItemPrefix) ||
(containerBalance === -1 &&
event[0] === 'exit' &&
(event[1].type === types.listUnordered ||
event[1].type === types.listOrdered))
) {
if (listItem) {
tailIndex = index
lineIndex = undefined
while (tailIndex--) {
tailEvent = events[tailIndex]
if (
tailEvent[1].type === types.lineEnding ||
tailEvent[1].type === types.lineEndingBlank
) {
if (tailEvent[0] === 'exit') continue
if (lineIndex) {
events[lineIndex][1].type = types.lineEndingBlank
listSpread = true
}
tailEvent[1].type = types.lineEnding
lineIndex = tailIndex
} else if (
tailEvent[1].type === types.linePrefix ||
tailEvent[1].type === types.blockQuotePrefix ||
tailEvent[1].type === types.blockQuotePrefixWhitespace ||
tailEvent[1].type === types.blockQuoteMarker ||
tailEvent[1].type === types.listItemIndent
) {
// Empty
} else {
break
}
}
if (
firstBlankLineIndex &&
(!lineIndex || firstBlankLineIndex < lineIndex)
) {
listItem._spread = true
}
// Fix position.
listItem.end = point(
lineIndex ? events[lineIndex][1].start : event[1].end
)
events.splice(lineIndex || index, 0, ['exit', listItem, event[2]])
index++
length++
}
// Create a new list item.
if (event[1].type === types.listItemPrefix) {
listItem = {
type: 'listItem',
_spread: false,
start: point(event[1].start)
}
events.splice(index, 0, ['enter', listItem, event[2]])
index++
length++
firstBlankLineIndex = undefined
atMarker = true
}
}
}
events[start][1]._spread = listSpread
return length
}
function setData(key, value) {
data[key] = value
}
function getData(key) {
return data[key]
}
function point(d) {
return {line: d.line, column: d.column, offset: d.offset}
}
function opener(create, and) {
return open
function open(token) {
enter.call(this, create(token), token)
if (and) and.call(this, token)
}
}
function buffer() {
this.stack.push({type: 'fragment', children: []})
}
function enter(node, token) {
this.stack[this.stack.length - 1].children.push(node)
this.stack.push(node)
node.position = {start: point(token.start)}
return node
}
function closer(and) {
return close
function close(token) {
if (and) and.call(this, token)
exit.call(this, token)
}
}
function exit(token) {
var node = this.stack.pop()
node.position.end = point(token.end)
return node
}
function resume() {
var value = toString(this.stack.pop())
return value
}
//
// Handlers.
//
function onenterlistordered() {
setData('expectingFirstListItemValue', true)
}
function onenterlistitemvalue(token) {
if (getData('expectingFirstListItemValue')) {
this.stack[this.stack.length - 2].start = parseInt(
this.sliceSerialize(token),
constants.numericBaseDecimal
)
setData('expectingFirstListItemValue')
}
}
function onexitcodefencedfenceinfo() {
var data = this.resume()
this.stack[this.stack.length - 1].lang = data
}
function onexitcodefencedfencemeta() {
var data = this.resume()
this.stack[this.stack.length - 1].meta = data
}
function onexitcodefencedfence() {
// Exit if this is the closing fence.
if (getData('flowCodeInside')) return
this.buffer()
setData('flowCodeInside', true)
}
function onexitcodefenced() {
var data = this.resume()
this.stack[this.stack.length - 1].value = data.replace(
/^(\r?\n|\r)|(\r?\n|\r)$/g,
''
)
setData('flowCodeInside')
}
function onexitcodeindented() {
var data = this.resume()
this.stack[this.stack.length - 1].value = data
}
function onexitdefinitionlabelstring(token) {
// Discard label, use the source content instead.
var label = this.resume()
this.stack[this.stack.length - 1].label = label
this.stack[this.stack.length - 1].identifier = normalizeIdentifier(
this.sliceSerialize(token)
).toLowerCase()
}
function onexitdefinitiontitlestring() {
var data = this.resume()
this.stack[this.stack.length - 1].title = data
}
function onexitdefinitiondestinationstring() {
var data = this.resume()
this.stack[this.stack.length - 1].url = data
}
function onexitatxheadingsequence(token) {
if (!this.stack[this.stack.length - 1].depth) {
this.stack[this.stack.length - 1].depth = this.sliceSerialize(
token
).length
}
}
function onexitsetextheadingtext() {
setData('setextHeadingSlurpLineEnding', true)
}
function onexitsetextheadinglinesequence(token) {
this.stack[this.stack.length - 1].depth =
this.sliceSerialize(token).charCodeAt(0) === codes.equalsTo ? 1 : 2
}
function onexitsetextheading() {
setData('setextHeadingSlurpLineEnding')
}
function onenterdata(token) {
var siblings = this.stack[this.stack.length - 1].children
var tail = siblings[siblings.length - 1]
if (!tail || tail.type !== 'text') {
// Add a new text node.
tail = text()
tail.position = {start: point(token.start)}
this.stack[this.stack.length - 1].children.push(tail)
}
this.stack.push(tail)
}
function onexitdata(token) {
var tail = this.stack.pop()
tail.value += this.sliceSerialize(token)
tail.position.end = point(token.end)
}
function onexitlineending(token) {
var context = this.stack[this.stack.length - 1]
// If we’re at a hard break, include the line ending in there.
if (getData('atHardBreak')) {
context.children[context.children.length - 1].position.end = point(
token.end
)
setData('atHardBreak')
return
}
if (getData('setextHeadingSlurpLineEnding')) {
return
}
if (config.canContainEols.indexOf(context.type) !== -1) {
onenterdata.call(this, token)
onexitdata.call(this, token)
}
}
function onexithardbreak() {
setData('atHardBreak', true)
}
function onexithtmlflow() {
var data = this.resume()
this.stack[this.stack.length - 1].value = data
}
function onexithtmltext() {
var data = this.resume()
this.stack[this.stack.length - 1].value = data
}
function onexitcodetext() {
var data = this.resume()
this.stack[this.stack.length - 1].value = data
}
function onexitlink() {
var context = this.stack[this.stack.length - 1]
// To do: clean.
if (getData('inReference')) {
context.type += 'Reference'
context.referenceType = getData('referenceType') || 'shortcut'
delete context.url
delete context.title
} else {
delete context.identifier
delete context.label
delete context.referenceType
}
setData('referenceType')
}
function onexitimage() {
var context = this.stack[this.stack.length - 1]
// To do: clean.
if (getData('inReference')) {
context.type += 'Reference'
context.referenceType = getData('referenceType') || 'shortcut'
delete context.url
delete context.title
} else {
delete context.identifier
delete context.label
delete context.referenceType
}
setData('referenceType')
}
function onexitlabeltext(token) {
this.stack[this.stack.length - 2].identifier = normalizeIdentifier(
this.sliceSerialize(token)
).toLowerCase()
}
function onexitlabel() {
var fragment = this.stack[this.stack.length - 1]
var value = this.resume()
this.stack[this.stack.length - 1].label = value
// Assume a reference.
setData('inReference', true)
if (this.stack[this.stack.length - 1].type === 'link') {
this.stack[this.stack.length - 1].children = fragment.children
} else {
this.stack[this.stack.length - 1].alt = value
}
}
function onexitresourcedestinationstring() {
var data = this.resume()
this.stack[this.stack.length - 1].url = data
}
function onexitresourcetitlestring() {
var data = this.resume()
this.stack[this.stack.length - 1].title = data
}
function onexitresource() {
setData('inReference')
}
function onenterreference() {
setData('referenceType', 'collapsed')
}
function onexitreferencestring(token) {
var label = this.resume()
this.stack[this.stack.length - 1].label = label
this.stack[this.stack.length - 1].identifier = normalizeIdentifier(
this.sliceSerialize(token)
).toLowerCase()
setData('referenceType', 'full')
}
function onexitcharacterreferencemarker(token) {
setData('characterReferenceType', token.type)
}
function onexitcharacterreferencevalue(token) {
var data = this.sliceSerialize(token)
var type = getData('characterReferenceType')
var value
if (type) {
value = safeFromInt(
data,
type === types.characterReferenceMarkerNumeric
? constants.numericBaseDecimal
: constants.numericBaseHexadecimal
)
setData('characterReferenceType')
} else {
value = decode(data)
}
this.stack[this.stack.length - 1].value += value
}
function onexitautolinkprotocol(token) {
onexitdata.call(this, token)
this.stack[this.stack.length - 1].url = this.sliceSerialize(token)
}
function onexitautolinkemail(token) {
onexitdata.call(this, token)
this.stack[this.stack.length - 1].url =
'mailto:' + this.sliceSerialize(token)
}
//
// Creaters.
//
function blockQuote() {
return {type: 'blockquote', children: []}
}
function codeFlow() {
return {type: 'code', lang: null, meta: null, value: ''}
}
function codeText() {
return {type: 'inlineCode', value: ''}
}
function definition() {
return {
type: 'definition',
identifier: '',
label: null,
title: null,
url: ''
}
}
function emphasis() {
return {type: 'emphasis', children: []}
}
function heading() {
return {type: 'heading', depth: undefined, children: []}
}
function hardBreak() {
return {type: 'break'}
}
function html() {
return {type: 'html', value: ''}
}
function image() {
return {type: 'image', title: null, url: '', alt: null}
}
function link() {
return {type: 'link', title: null, url: '', children: []}
}
function list(token) {
return {
type: 'list',
ordered: token.type === 'listOrdered',
start: null,
spread: token._spread,
children: []
}
}
function listItem(token) {
return {
type: 'listItem',
spread: token._spread,
checked: null,
children: []
}
}
function paragraph() {
return {type: 'paragraph', children: []}
}
function strong() {
return {type: 'strong', children: []}
}
function text() {
return {type: 'text', value: ''}
}
function thematicBreak() {
return {type: 'thematicBreak'}
}
}
function configure(config, extensions) {
var length = extensions.length
var index = -1
while (++index < length) {
extension(config, extensions[index])
}
return config
}
function extension(config, extension) {
var key
var left
var right
for (key in extension) {
left = own.call(config, key) ? config[key] : (config[key] = {})
right = extension[key]
if (key === 'canContainEols') {
config[key] = [].concat(left, right)
} else {
Object.assign(left, right)
}
}
}
module.exports = require('./dist')
{
"name": "mdast-util-from-markdown",
"version": "0.8.0",
"version": "0.8.1",
"description": "mdast utility to parse markdown",

@@ -30,2 +30,4 @@ "license": "MIT",

"files": [
"dist/",
"lib/",
"index.js",

@@ -42,2 +44,4 @@ "types/index.d.ts"

"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"browserify": "^17.0.0",

@@ -53,13 +57,15 @@ "commonmark.json": "^0.29.0",

"rehype-stringify": "^8.0.0",
"remark-cli": "^8.0.0",
"remark-preset-wooorm": "^7.0.0",
"remark-cli": "^9.0.0",
"remark-preset-wooorm": "^8.0.0",
"tape": "^5.0.0",
"tinyify": "^3.0.0",
"unified": "^9.0.0",
"xo": "^0.33.0"
"xo": "^0.34.0"
},
"scripts": {
"prepare": "if [ -d \"micromark\" ] ; then\ncd \"micromark\" && git pull\nelse\ngit clone https://github.com/micromark/micromark.git\nfi",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"generate-dist": "babel lib/ --out-dir dist/ --quiet --retain-lines --plugins ./micromark/script/babel-transform-constants.js; prettier dist/ --loglevel error --write",
"generate-size": "browserify . -p tinyify -s mdast-util-from-markdown -o mdast-util-from-markdown.min.js; gzip-size mdast-util-from-markdown.min.js",
"generate": "npm run generate-size",
"generate": "npm run generate-dist && npm run generate-size",
"test-api": "node test",

@@ -95,3 +101,6 @@ "test-coverage": "nyc --reporter lcov tape test/index.js",

"unicorn/prefer-set-has": "off"
}
},
"ignores": [
"types/"
]
},

@@ -98,0 +107,0 @@ "remarkConfig": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc