planning
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s

This commit is contained in:
2024-10-14 09:15:30 +02:00
parent bcba00a730
commit 6e64e138e2
21059 changed files with 2317811 additions and 1 deletions

18
node_modules/remark-stringify/index.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
'use strict'
var unherit = require('unherit')
var xtend = require('xtend')
var Compiler = require('./lib/compiler.js')
module.exports = stringify
stringify.Compiler = Compiler
function stringify(options) {
var Local = unherit(Compiler)
Local.prototype.options = xtend(
Local.prototype.options,
this.data('settings'),
options
)
this.Compiler = Local
}

63
node_modules/remark-stringify/lib/compiler.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
'use strict'
var xtend = require('xtend')
var toggle = require('state-toggle')
module.exports = Compiler
// Construct a new compiler.
function Compiler(tree, file) {
this.inLink = false
this.inTable = false
this.tree = tree
this.file = file
this.options = xtend(this.options)
this.setOptions({})
}
var proto = Compiler.prototype
// Enter and exit helpers. */
proto.enterLink = toggle('inLink', false)
proto.enterTable = toggle('inTable', false)
proto.enterLinkReference = require('./util/enter-link-reference')
// Configuration.
proto.options = require('./defaults')
proto.setOptions = require('./set-options')
proto.compile = require('./macro/compile')
proto.visit = require('./macro/one')
proto.all = require('./macro/all')
proto.block = require('./macro/block')
proto.visitOrderedItems = require('./macro/ordered-items')
proto.visitUnorderedItems = require('./macro/unordered-items')
// Expose visitors.
proto.visitors = {
root: require('./visitors/root'),
text: require('./visitors/text'),
heading: require('./visitors/heading'),
paragraph: require('./visitors/paragraph'),
blockquote: require('./visitors/blockquote'),
list: require('./visitors/list'),
listItem: require('./visitors/list-item'),
inlineCode: require('./visitors/inline-code'),
code: require('./visitors/code'),
html: require('./visitors/html'),
thematicBreak: require('./visitors/thematic-break'),
strong: require('./visitors/strong'),
emphasis: require('./visitors/emphasis'),
break: require('./visitors/break'),
delete: require('./visitors/delete'),
link: require('./visitors/link'),
linkReference: require('./visitors/link-reference'),
imageReference: require('./visitors/image-reference'),
definition: require('./visitors/definition'),
image: require('./visitors/image'),
footnote: require('./visitors/footnote'),
footnoteReference: require('./visitors/footnote-reference'),
footnoteDefinition: require('./visitors/footnote-definition'),
table: require('./visitors/table'),
tableCell: require('./visitors/table-cell')
}

28
node_modules/remark-stringify/lib/defaults.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
'use strict'
module.exports = {
gfm: true,
commonmark: false,
pedantic: false,
entities: 'false',
setext: false,
closeAtx: false,
looseTable: false,
spacedTable: true,
paddedTable: true,
stringLength: stringLength,
incrementListMarker: true,
fences: false,
fence: '`',
bullet: '-',
listItemIndent: 'tab',
rule: '*',
ruleSpaces: true,
ruleRepetition: 3,
strong: '*',
emphasis: '_'
}
function stringLength(value) {
return value.length
}

299
node_modules/remark-stringify/lib/escape.js generated vendored Normal file
View File

@@ -0,0 +1,299 @@
'use strict'
var decimal = require('is-decimal')
var alphanumeric = require('is-alphanumeric')
var whitespace = require('is-whitespace-character')
var escapes = require('markdown-escapes')
var prefix = require('./util/entity-prefix-length')
module.exports = factory
var tab = '\t'
var lineFeed = '\n'
var space = ' '
var numberSign = '#'
var ampersand = '&'
var leftParenthesis = '('
var rightParenthesis = ')'
var asterisk = '*'
var plusSign = '+'
var dash = '-'
var dot = '.'
var colon = ':'
var lessThan = '<'
var greaterThan = '>'
var leftSquareBracket = '['
var backslash = '\\'
var rightSquareBracket = ']'
var underscore = '_'
var graveAccent = '`'
var verticalBar = '|'
var tilde = '~'
var exclamationMark = '!'
var entities = {
'<': '&lt;',
':': '&#x3A;',
'&': '&amp;',
'|': '&#x7C;',
'~': '&#x7E;'
}
var shortcut = 'shortcut'
var mailto = 'mailto'
var https = 'https'
var http = 'http'
var blankExpression = /\n\s*$/
// Factory to escape characters.
function factory(options) {
return escape
// Escape punctuation characters in a nodes value.
function escape(value, node, parent) {
var self = this
var gfm = options.gfm
var commonmark = options.commonmark
var pedantic = options.pedantic
var markers = commonmark ? [dot, rightParenthesis] : [dot]
var siblings = parent && parent.children
var index = siblings && siblings.indexOf(node)
var prev = siblings && siblings[index - 1]
var next = siblings && siblings[index + 1]
var length = value.length
var escapable = escapes(options)
var position = -1
var queue = []
var escaped = queue
var afterNewLine
var character
var wordCharBefore
var wordCharAfter
var offset
var replace
if (prev) {
afterNewLine = text(prev) && blankExpression.test(prev.value)
} else {
afterNewLine =
!parent || parent.type === 'root' || parent.type === 'paragraph'
}
while (++position < length) {
character = value.charAt(position)
replace = false
if (character === '\n') {
afterNewLine = true
} else if (
character === backslash ||
character === graveAccent ||
character === asterisk ||
(character === exclamationMark &&
value.charAt(position + 1) === leftSquareBracket) ||
character === leftSquareBracket ||
character === lessThan ||
(character === ampersand && prefix(value.slice(position)) > 0) ||
(character === rightSquareBracket && self.inLink) ||
(gfm && character === tilde && value.charAt(position + 1) === tilde) ||
(gfm &&
character === verticalBar &&
(self.inTable || alignment(value, position))) ||
(character === underscore &&
// Delegate leading/trailing underscores to the multinode version below.
position > 0 &&
position < length - 1 &&
(pedantic ||
!alphanumeric(value.charAt(position - 1)) ||
!alphanumeric(value.charAt(position + 1)))) ||
(gfm && !self.inLink && character === colon && protocol(queue.join('')))
) {
replace = true
} else if (afterNewLine) {
if (
character === greaterThan ||
character === numberSign ||
character === asterisk ||
character === dash ||
character === plusSign
) {
replace = true
} else if (decimal(character)) {
offset = position + 1
while (offset < length) {
if (!decimal(value.charAt(offset))) {
break
}
offset++
}
if (markers.indexOf(value.charAt(offset)) !== -1) {
next = value.charAt(offset + 1)
if (!next || next === space || next === tab || next === lineFeed) {
queue.push(value.slice(position, offset))
position = offset
character = value.charAt(position)
replace = true
}
}
}
}
if (afterNewLine && !whitespace(character)) {
afterNewLine = false
}
queue.push(replace ? one(character) : character)
}
// Multi-node versions.
if (siblings && text(node)) {
// Check for an opening parentheses after a link-reference (which can be
// joined by white-space).
if (prev && prev.referenceType === shortcut) {
position = -1
length = escaped.length
while (++position < length) {
character = escaped[position]
if (character === space || character === tab) {
continue
}
if (character === leftParenthesis || character === colon) {
escaped[position] = one(character)
}
break
}
// If the current node is all spaces / tabs, preceded by a shortcut,
// and followed by a text starting with `(`, escape it.
if (
text(next) &&
position === length &&
next.value.charAt(0) === leftParenthesis
) {
escaped.push(backslash)
}
}
// Ensure non-auto-links are not seen as links. This pattern needs to
// check the preceding nodes too.
if (
gfm &&
!self.inLink &&
text(prev) &&
value.charAt(0) === colon &&
protocol(prev.value.slice(-6))
) {
escaped[0] = one(colon)
}
// Escape ampersand if it would otherwise start an entity.
if (
text(next) &&
value.charAt(length - 1) === ampersand &&
prefix(ampersand + next.value) !== 0
) {
escaped[escaped.length - 1] = one(ampersand)
}
// Escape exclamation marks immediately followed by links.
if (
next &&
next.type === 'link' &&
value.charAt(length - 1) === exclamationMark
) {
escaped[escaped.length - 1] = one(exclamationMark)
}
// Escape double tildes in GFM.
if (
gfm &&
text(next) &&
value.charAt(length - 1) === tilde &&
next.value.charAt(0) === tilde
) {
escaped.splice(escaped.length - 1, 0, backslash)
}
// Escape underscores, but not mid-word (unless in pedantic mode).
wordCharBefore = text(prev) && alphanumeric(prev.value.slice(-1))
wordCharAfter = text(next) && alphanumeric(next.value.charAt(0))
if (length === 1) {
if (
value === underscore &&
(pedantic || !wordCharBefore || !wordCharAfter)
) {
escaped.unshift(backslash)
}
} else {
if (
value.charAt(0) === underscore &&
(pedantic || !wordCharBefore || !alphanumeric(value.charAt(1)))
) {
escaped.unshift(backslash)
}
if (
value.charAt(length - 1) === underscore &&
(pedantic ||
!wordCharAfter ||
!alphanumeric(value.charAt(length - 2)))
) {
escaped.splice(escaped.length - 1, 0, backslash)
}
}
}
return escaped.join('')
function one(character) {
return escapable.indexOf(character) === -1
? entities[character]
: backslash + character
}
}
}
// Check if `index` in `value` is inside an alignment row.
function alignment(value, index) {
var start = value.lastIndexOf(lineFeed, index)
var end = value.indexOf(lineFeed, index)
var char
end = end === -1 ? value.length : end
while (++start < end) {
char = value.charAt(start)
if (
char !== colon &&
char !== dash &&
char !== space &&
char !== verticalBar
) {
return false
}
}
return true
}
// Check if `node` is a text node.
function text(node) {
return node && node.type === 'text'
}
// Check if `value` ends in a protocol.
function protocol(value) {
var val = value.slice(-6).toLowerCase()
return val === mailto || val.slice(-5) === https || val.slice(-4) === http
}

18
node_modules/remark-stringify/lib/macro/all.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
'use strict'
module.exports = all
// Visit all children of `parent`.
function all(parent) {
var self = this
var children = parent.children
var length = children.length
var results = []
var index = -1
while (++index < length) {
results[index] = self.visit(children[index], parent)
}
return results
}

54
node_modules/remark-stringify/lib/macro/block.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
'use strict'
module.exports = block
var lineFeed = '\n'
var blank = lineFeed + lineFeed
var triple = blank + lineFeed
var comment = blank + '<!---->' + blank
// Stringify a block node with block children (e.g., `root` or `blockquote`).
// Knows about code following a list, or adjacent lists with similar bullets,
// and places an extra line feed between them.
function block(node) {
var self = this
var options = self.options
var fences = options.fences
var gap = options.commonmark ? comment : triple
var values = []
var children = node.children
var length = children.length
var index = -1
var prev
var child
while (++index < length) {
prev = child
child = children[index]
if (prev) {
// A list preceding another list that are equally ordered, or a
// list preceding an indented code block, need a gap between them,
// so as not to see them as one list, or content of the list,
// respectively.
//
// In commonmark, only something that breaks both up can do that,
// so we opt for an empty, invisible comment. In other flavours,
// two blank lines are fine.
if (
prev.type === 'list' &&
((child.type === 'list' && prev.ordered === child.ordered) ||
(child.type === 'code' && (!child.lang && !fences)))
) {
values.push(gap)
} else {
values.push(blank)
}
}
values.push(self.visit(child, node))
}
return values.join('')
}

10
node_modules/remark-stringify/lib/macro/compile.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
'use strict'
var compact = require('mdast-util-compact')
module.exports = compile
// Stringify the given tree.
function compile() {
return this.visit(compact(this.tree, this.options.commonmark))
}

20
node_modules/remark-stringify/lib/macro/one.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
'use strict'
module.exports = one
function one(node, parent) {
var self = this
var visitors = self.visitors
// Fail on unknown nodes.
if (typeof visitors[node.type] !== 'function') {
self.file.fail(
new Error(
'Missing compiler for node of type `' + node.type + '`: `' + node + '`'
),
node
)
}
return visitors[node.type].call(self, node, parent)
}

View File

@@ -0,0 +1,43 @@
'use strict'
module.exports = orderedItems
var lineFeed = '\n'
var dot = '.'
var blank = lineFeed + lineFeed
// Visit ordered list items.
//
// Starts the list with
// `node.start` and increments each following list item
// bullet by one:
//
// 2. foo
// 3. bar
//
// In `incrementListMarker: false` mode, does not increment
// each marker and stays on `node.start`:
//
// 1. foo
// 1. bar
function orderedItems(node) {
var self = this
var fn = self.visitors.listItem
var increment = self.options.incrementListMarker
var values = []
var start = node.start
var children = node.children
var length = children.length
var index = -1
var bullet
start = start == null ? 1 : start
while (++index < length) {
bullet = (increment ? start + index : start) + dot
values[index] = fn.call(self, children[index], node, index, bullet)
}
return values.join(node.spread ? blank : lineFeed)
}

View File

@@ -0,0 +1,24 @@
'use strict'
module.exports = unorderedItems
var lineFeed = '\n'
var blank = lineFeed + lineFeed
// Visit unordered list items. Uses `options.bullet` as each items bullet.
function unorderedItems(node) {
var self = this
var bullet = self.options.bullet
var fn = self.visitors.listItem
var children = node.children
var length = children.length
var index = -1
var values = []
while (++index < length) {
values[index] = fn.call(self, children[index], node, index, bullet)
}
return values.join(node.spread ? blank : lineFeed)
}

160
node_modules/remark-stringify/lib/set-options.js generated vendored Normal file
View File

@@ -0,0 +1,160 @@
'use strict'
var xtend = require('xtend')
var encode = require('stringify-entities')
var defaults = require('./defaults')
var escapeFactory = require('./escape')
var identity = require('./util/identity')
module.exports = setOptions
// Map of applicable enums.
var maps = {
entities: {true: true, false: true, numbers: true, escape: true},
bullet: {'*': true, '-': true, '+': true},
rule: {'-': true, _: true, '*': true},
listItemIndent: {tab: true, mixed: true, 1: true},
emphasis: {_: true, '*': true},
strong: {_: true, '*': true},
fence: {'`': true, '~': true}
}
// Expose `validate`.
var validate = {
boolean: validateBoolean,
string: validateString,
number: validateNumber,
function: validateFunction
}
// Set options. Does not overwrite previously set options.
function setOptions(options) {
var self = this
var current = self.options
var ruleRepetition
var key
if (options == null) {
options = {}
} else if (typeof options === 'object') {
options = xtend(options)
} else {
throw new Error('Invalid value `' + options + '` for setting `options`')
}
for (key in defaults) {
validate[typeof defaults[key]](options, key, current[key], maps[key])
}
ruleRepetition = options.ruleRepetition
if (ruleRepetition && ruleRepetition < 3) {
raise(ruleRepetition, 'options.ruleRepetition')
}
self.encode = encodeFactory(String(options.entities))
self.escape = escapeFactory(options)
self.options = options
return self
}
// Validate a value to be boolean. Defaults to `def`. Raises an exception with
// `context[name]` when not a boolean.
function validateBoolean(context, name, def) {
var value = context[name]
if (value == null) {
value = def
}
if (typeof value !== 'boolean') {
raise(value, 'options.' + name)
}
context[name] = value
}
// Validate a value to be boolean. Defaults to `def`. Raises an exception with
// `context[name]` when not a boolean.
function validateNumber(context, name, def) {
var value = context[name]
if (value == null) {
value = def
}
if (isNaN(value)) {
raise(value, 'options.' + name)
}
context[name] = value
}
// Validate a value to be in `map`. Defaults to `def`. Raises an exception
// with `context[name]` when not in `map`.
function validateString(context, name, def, map) {
var value = context[name]
if (value == null) {
value = def
}
value = String(value)
if (!(value in map)) {
raise(value, 'options.' + name)
}
context[name] = value
}
// Validate a value to be function. Defaults to `def`. Raises an exception
// with `context[name]` when not a function.
function validateFunction(context, name, def) {
var value = context[name]
if (value == null) {
value = def
}
if (typeof value !== 'function') {
raise(value, 'options.' + name)
}
context[name] = value
}
// Factory to encode HTML entities. Creates a no-operation function when
// `type` is `'false'`, a function which encodes using named references when
// `type` is `'true'`, and a function which encodes using numbered references
// when `type` is `'numbers'`.
function encodeFactory(type) {
var options = {}
if (type === 'false') {
return identity
}
if (type === 'true') {
options.useNamedReferences = true
}
if (type === 'escape') {
options.escapeOnly = true
options.useNamedReferences = true
}
return wrapped
// Encode HTML entities using the bound options.
function wrapped(value) {
return encode(value, options)
}
}
// Throw an exception with in its `message` `value` and `name`.
function raise(value, name) {
throw new Error('Invalid value `' + value + '` for setting `' + name + '`')
}

View File

@@ -0,0 +1,67 @@
'use strict'
var entityPrefixLength = require('./entity-prefix-length')
module.exports = copy
var ampersand = '&'
var punctuationExppresion = /[-!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~_]/
// For shortcut and collapsed reference links, the contents is also an
// identifier, so we need to restore the original encoding and escaping
// that were present in the source string.
//
// This function takes the unescaped & unencoded value from shortcuts
// child nodes and the identifier and encodes the former according to
// the latter.
function copy(value, identifier) {
var length = value.length
var count = identifier.length
var result = []
var position = 0
var index = 0
var start
while (index < length) {
// Take next non-punctuation characters from `value`.
start = index
while (index < length && !punctuationExppresion.test(value.charAt(index))) {
index += 1
}
result.push(value.slice(start, index))
// Advance `position` to the next punctuation character.
while (
position < count &&
!punctuationExppresion.test(identifier.charAt(position))
) {
position += 1
}
// Take next punctuation characters from `identifier`.
start = position
while (
position < count &&
punctuationExppresion.test(identifier.charAt(position))
) {
if (identifier.charAt(position) === ampersand) {
position += entityPrefixLength(identifier.slice(position))
}
position += 1
}
result.push(identifier.slice(start, position))
// Advance `index` to the next non-punctuation character.
while (index < length && punctuationExppresion.test(value.charAt(index))) {
index += 1
}
}
return result.join('')
}

View File

@@ -0,0 +1,17 @@
'use strict'
module.exports = enclose
var quotationMark = '"'
var apostrophe = "'"
// There is currently no way to support nested delimiters across Markdown.pl,
// CommonMark, and GitHub (RedCarpet). The following code supports Markdown.pl
// and GitHub.
// CommonMark is not supported when mixing double- and single quotes inside a
// title.
function enclose(title) {
var delimiter =
title.indexOf(quotationMark) === -1 ? quotationMark : apostrophe
return delimiter + title + delimiter
}

33
node_modules/remark-stringify/lib/util/enclose-uri.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
'use strict'
var count = require('ccount')
module.exports = enclose
var leftParenthesis = '('
var rightParenthesis = ')'
var lessThan = '<'
var greaterThan = '>'
var expression = /\s/
// Wrap `url` in angle brackets when needed, or when
// forced.
// In links, images, and definitions, the URL part needs
// to be enclosed when it:
//
// - has a length of `0`
// - contains white-space
// - has more or less opening than closing parentheses
function enclose(uri, always) {
if (
always ||
uri.length === 0 ||
expression.test(uri) ||
count(uri, leftParenthesis) !== count(uri, rightParenthesis)
) {
return lessThan + uri + greaterThan
}
return uri
}

View File

@@ -0,0 +1,33 @@
'use strict'
var identity = require('./identity')
module.exports = enter
// Shortcut and collapsed link references need no escaping and encoding during
// the processing of child nodes (it must be implied from identifier).
//
// This toggler turns encoding and escaping off for shortcut and collapsed
// references.
//
// Implies `enterLink`.
function enter(compiler, node) {
var encode = compiler.encode
var escape = compiler.escape
var exitLink = compiler.enterLink()
if (node.referenceType !== 'shortcut' && node.referenceType !== 'collapsed') {
return exitLink
}
compiler.escape = identity
compiler.encode = identity
return exit
function exit() {
compiler.encode = encode
compiler.escape = escape
exitLink()
}
}

View File

@@ -0,0 +1,23 @@
'use strict'
var decode = require('parse-entities')
module.exports = length
var ampersand = '&'
// Returns the length of HTML entity that is a prefix of the given string
// (excluding the ampersand), 0 if it does not start with an entity.
function length(value) {
var prefix
/* istanbul ignore if - Currently also tested for at implemention, but we
* keep it here because thats proper. */
if (value.charAt(0) !== ampersand) {
return 0
}
prefix = value.split(ampersand, 2).join(ampersand)
return prefix.length - decode(prefix).length
}

7
node_modules/remark-stringify/lib/util/identity.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
'use strict'
module.exports = identity
function identity(value) {
return value
}

27
node_modules/remark-stringify/lib/util/label.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict'
module.exports = label
var leftSquareBracket = '['
var rightSquareBracket = ']'
var shortcut = 'shortcut'
var collapsed = 'collapsed'
// Stringify a reference label.
// Because link references are easily, mistakingly, created (for example,
// `[foo]`), reference nodes have an extra property depicting how it looked in
// the original document, so stringification can cause minimal changes.
function label(node) {
var type = node.referenceType
if (type === shortcut) {
return ''
}
return (
leftSquareBracket +
(type === collapsed ? '' : node.label || node.identifier) +
rightSquareBracket
)
}

26
node_modules/remark-stringify/lib/util/pad.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
'use strict'
var repeat = require('repeat-string')
module.exports = pad
var lineFeed = '\n'
var space = ' '
var tabSize = 4
// Pad `value` with `level * tabSize` spaces. Respects lines. Ignores empty
// lines.
function pad(value, level) {
var values = value.split(lineFeed)
var index = values.length
var padding = repeat(space, level * tabSize)
while (index--) {
if (values[index].length !== 0) {
values[index] = padding + values[index]
}
}
return values.join(lineFeed)
}

View File

@@ -0,0 +1,22 @@
'use strict'
module.exports = blockquote
var lineFeed = '\n'
var space = ' '
var greaterThan = '>'
function blockquote(node) {
var values = this.block(node).split(lineFeed)
var result = []
var length = values.length
var index = -1
var value
while (++index < length) {
value = values[index]
result[index] = (value ? space : '') + value
}
return greaterThan + result.join(lineFeed + greaterThan)
}

14
node_modules/remark-stringify/lib/visitors/break.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
'use strict'
module.exports = lineBreak
var backslash = '\\'
var lineFeed = '\n'
var space = ' '
var commonmark = backslash + lineFeed
var normal = space + space + lineFeed
function lineBreak() {
return this.options.commonmark ? commonmark : normal
}

79
node_modules/remark-stringify/lib/visitors/code.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
'use strict'
var streak = require('longest-streak')
var repeat = require('repeat-string')
var pad = require('../util/pad')
module.exports = code
var lineFeed = '\n'
var space = ' '
// Stringify code.
// Creates indented code when:
//
// - No language tag exists
// - Not in `fences: true` mode
// - A non-empty value exists
//
// Otherwise, GFM fenced code is created:
//
// ````markdown
// ```js
// foo();
// ```
// ````
//
// When in ``fence: `~` `` mode, uses tildes as fences:
//
// ```markdown
// ~~~js
// foo();
// ~~~
// ```
//
// Knows about internal fences:
//
// `````markdown
// ````markdown
// ```javascript
// foo();
// ```
// ````
// `````
function code(node, parent) {
var self = this
var value = node.value
var options = self.options
var marker = options.fence
var info = node.lang || ''
var fence
if (info && node.meta) {
info += space + node.meta
}
info = self.encode(self.escape(info, node))
// Without (needed) fences.
if (!info && !options.fences && value) {
// Throw when pedantic, in a list item which isnt compiled using a tab.
if (
parent &&
parent.type === 'listItem' &&
options.listItemIndent !== 'tab' &&
options.pedantic
) {
self.file.fail(
'Cannot indent code properly. See https://git.io/fxKR8',
node.position
)
}
return pad(value, 1)
}
fence = repeat(marker, Math.max(streak(value, marker) + 1, 3))
return fence + info + lineFeed + value + lineFeed + fence
}

View File

@@ -0,0 +1,36 @@
'use strict'
var uri = require('../util/enclose-uri')
var title = require('../util/enclose-title')
module.exports = definition
var space = ' '
var colon = ':'
var leftSquareBracket = '['
var rightSquareBracket = ']'
// Stringify an URL definition.
//
// Is smart about enclosing `url` (see `encloseURI()`) and `title` (see
// `encloseTitle()`).
//
// ```markdown
// [foo]: <foo at bar dot com> 'An "example" e-mail'
// ```
function definition(node) {
var content = uri(node.url)
if (node.title) {
content += space + title(node.title)
}
return (
leftSquareBracket +
(node.label || node.identifier) +
rightSquareBracket +
colon +
space +
content
)
}

11
node_modules/remark-stringify/lib/visitors/delete.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
'use strict'
module.exports = strikethrough
var tilde = '~'
var fence = tilde + tilde
function strikethrough(node) {
return fence + this.all(node).join('') + fence
}

38
node_modules/remark-stringify/lib/visitors/emphasis.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
'use strict'
module.exports = emphasis
var underscore = '_'
var asterisk = '*'
// Stringify an `emphasis`.
//
// The marker used is configurable through `emphasis`, which defaults to an
// underscore (`'_'`) but also accepts an asterisk (`'*'`):
//
// ```markdown
// *foo*
// ```
//
// In `pedantic` mode, text which itself contains an underscore will cause the
// marker to default to an asterisk instead:
//
// ```markdown
// *foo_bar*
// ```
function emphasis(node) {
var marker = this.options.emphasis
var content = this.all(node).join('')
// When in pedantic mode, prevent using underscore as the marker when there
// are underscores in the content.
if (
this.options.pedantic &&
marker === underscore &&
content.indexOf(marker) !== -1
) {
marker = asterisk
}
return marker + content + marker
}

View File

@@ -0,0 +1,30 @@
'use strict'
var repeat = require('repeat-string')
var lineFeed = '\n'
var space = ' '
var colon = ':'
var leftSquareBracket = '['
var rightSquareBracket = ']'
var caret = '^'
var tabSize = 4
var blank = lineFeed + lineFeed
var indent = repeat(space, tabSize)
module.exports = footnoteDefinition
function footnoteDefinition(node) {
var content = this.all(node).join(blank + indent)
return (
leftSquareBracket +
caret +
(node.label || node.identifier) +
rightSquareBracket +
colon +
space +
content
)
}

View File

@@ -0,0 +1,16 @@
'use strict'
module.exports = footnoteReference
var leftSquareBracket = '['
var rightSquareBracket = ']'
var caret = '^'
function footnoteReference(node) {
return (
leftSquareBracket +
caret +
(node.label || node.identifier) +
rightSquareBracket
)
}

13
node_modules/remark-stringify/lib/visitors/footnote.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
'use strict'
module.exports = footnote
var leftSquareBracket = '['
var rightSquareBracket = ']'
var caret = '^'
function footnote(node) {
return (
leftSquareBracket + caret + this.all(node).join('') + rightSquareBracket
)
}

51
node_modules/remark-stringify/lib/visitors/heading.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
'use strict'
var repeat = require('repeat-string')
module.exports = heading
var lineFeed = '\n'
var space = ' '
var numberSign = '#'
var dash = '-'
var equalsTo = '='
// Stringify a heading.
//
// In `setext: true` mode and when `depth` is smaller than three, creates a
// setext header:
//
// ```markdown
// Foo
// ===
// ```
//
// Otherwise, an ATX header is generated:
//
// ```markdown
// ### Foo
// ```
//
// In `closeAtx: true` mode, the header is closed with hashes:
//
// ```markdown
// ### Foo ###
// ```
function heading(node) {
var self = this
var depth = node.depth
var setext = self.options.setext
var closeAtx = self.options.closeAtx
var content = self.all(node).join('')
var prefix
if (setext && depth < 3) {
return (
content + lineFeed + repeat(depth === 1 ? equalsTo : dash, content.length)
)
}
prefix = repeat(numberSign, node.depth)
return prefix + space + content + (closeAtx ? space + prefix : '')
}

7
node_modules/remark-stringify/lib/visitors/html.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
'use strict'
module.exports = html
function html(node) {
return node.value
}

View File

@@ -0,0 +1,19 @@
'use strict'
var label = require('../util/label')
module.exports = imageReference
var leftSquareBracket = '['
var rightSquareBracket = ']'
var exclamationMark = '!'
function imageReference(node) {
return (
exclamationMark +
leftSquareBracket +
(this.encode(node.alt, node) || '') +
rightSquareBracket +
label(node)
)
}

47
node_modules/remark-stringify/lib/visitors/image.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
'use strict'
var uri = require('../util/enclose-uri')
var title = require('../util/enclose-title')
module.exports = image
var space = ' '
var leftParenthesis = '('
var rightParenthesis = ')'
var leftSquareBracket = '['
var rightSquareBracket = ']'
var exclamationMark = '!'
// Stringify an image.
//
// Is smart about enclosing `url` (see `encloseURI()`) and `title` (see
// `encloseTitle()`).
//
// ```markdown
// ![foo](</fav icon.png> 'My "favourite" icon')
// ```
//
// Supports named entities in `url`, `alt`, and `title` when in
// `settings.encode` mode.
function image(node) {
var self = this
var content = uri(self.encode(node.url || '', node))
var exit = self.enterLink()
var alt = self.encode(self.escape(node.alt || '', node))
exit()
if (node.title) {
content += space + title(self.encode(node.title, node))
}
return (
exclamationMark +
leftSquareBracket +
alt +
rightSquareBracket +
leftParenthesis +
content +
rightParenthesis
)
}

View File

@@ -0,0 +1,41 @@
'use strict'
var streak = require('longest-streak')
var repeat = require('repeat-string')
module.exports = inlineCode
var space = ' '
var graveAccent = '`'
// Stringify inline code.
//
// Knows about internal ticks (`\``), and ensures one more tick is used to
// enclose the inline code:
//
// ````markdown
// ```foo ``bar`` baz```
// ````
//
// Even knows about inital and final ticks:
//
// ``markdown
// `` `foo ``
// `` foo` ``
// ```
function inlineCode(node) {
var value = node.value
var ticks = repeat(graveAccent, streak(value, graveAccent) + 1)
var start = ticks
var end = ticks
if (value.charAt(0) === graveAccent) {
start += space
}
if (value.charAt(value.length - 1) === graveAccent) {
end = space + end
}
return start + value + end
}

View File

@@ -0,0 +1,27 @@
'use strict'
var copy = require('../util/copy-identifier-encoding')
var label = require('../util/label')
module.exports = linkReference
var leftSquareBracket = '['
var rightSquareBracket = ']'
var shortcut = 'shortcut'
var collapsed = 'collapsed'
function linkReference(node) {
var self = this
var type = node.referenceType
var exit = self.enterLinkReference(self, node)
var value = self.all(node).join('')
exit()
if (type === shortcut || type === collapsed) {
value = copy(value, node.label || node.identifier)
}
return leftSquareBracket + value + rightSquareBracket + label(node)
}

65
node_modules/remark-stringify/lib/visitors/link.js generated vendored Normal file
View File

@@ -0,0 +1,65 @@
'use strict'
var uri = require('../util/enclose-uri')
var title = require('../util/enclose-title')
module.exports = link
var space = ' '
var leftSquareBracket = '['
var rightSquareBracket = ']'
var leftParenthesis = '('
var rightParenthesis = ')'
// Expression for a protocol:
// See <http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax>.
var protocol = /^[a-z][a-z+.-]+:\/?/i
// Stringify a link.
//
// When no title exists, the compiled `children` equal `url`, and `url` starts
// with a protocol, an auto link is created:
//
// ```markdown
// <http://example.com>
// ```
//
// Otherwise, is smart about enclosing `url` (see `encloseURI()`) and `title`
// (see `encloseTitle()`).
// ```
//
// ```markdown
// [foo](<foo at bar dot com> 'An "example" e-mail')
// ```
//
// Supports named entities in the `url` and `title` when in `settings.encode`
// mode.
function link(node) {
var self = this
var content = self.encode(node.url || '', node)
var exit = self.enterLink()
var escaped = self.encode(self.escape(node.url || '', node))
var value = self.all(node).join('')
exit()
if (node.title == null && protocol.test(content) && escaped === value) {
// Backslash escapes do not work in autolinks, so we do not escape.
return uri(self.encode(node.url), true)
}
content = uri(content)
if (node.title) {
content += space + title(self.encode(self.escape(node.title, node), node))
}
return (
leftSquareBracket +
value +
rightSquareBracket +
leftParenthesis +
content +
rightParenthesis
)
}

View File

@@ -0,0 +1,75 @@
'use strict'
var repeat = require('repeat-string')
var pad = require('../util/pad')
module.exports = listItem
var lineFeed = '\n'
var space = ' '
var leftSquareBracket = '['
var rightSquareBracket = ']'
var lowercaseX = 'x'
var ceil = Math.ceil
var blank = lineFeed + lineFeed
var tabSize = 4
// Stringify a list item.
//
// Prefixes the content with a checked checkbox when `checked: true`:
//
// ```markdown
// [x] foo
// ```
//
// Prefixes the content with an unchecked checkbox when `checked: false`:
//
// ```markdown
// [ ] foo
// ```
function listItem(node, parent, position, bullet) {
var self = this
var style = self.options.listItemIndent
var marker = bullet || self.options.bullet
var spread = node.spread == null ? true : node.spread
var checked = node.checked
var children = node.children
var length = children.length
var values = []
var index = -1
var value
var indent
var spacing
while (++index < length) {
values[index] = self.visit(children[index], node)
}
value = values.join(spread ? blank : lineFeed)
if (typeof checked === 'boolean') {
// Note: Id like to be able to only add the space between the check and
// the value, but unfortunately github does not support empty list-items
// with a checkbox :(
value =
leftSquareBracket +
(checked ? lowercaseX : space) +
rightSquareBracket +
space +
value
}
if (style === '1' || (style === 'mixed' && value.indexOf(lineFeed) === -1)) {
indent = marker.length + 1
spacing = space
} else {
indent = ceil((marker.length + 1) / tabSize) * tabSize
spacing = repeat(space, indent - marker.length)
}
return value
? marker + spacing + pad(value, indent / tabSize).slice(indent)
: marker
}

8
node_modules/remark-stringify/lib/visitors/list.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
'use strict'
module.exports = list
function list(node) {
var fn = node.ordered ? this.visitOrderedItems : this.visitUnorderedItems
return fn.call(this, node)
}

View File

@@ -0,0 +1,7 @@
'use strict'
module.exports = paragraph
function paragraph(node) {
return this.all(node).join('')
}

11
node_modules/remark-stringify/lib/visitors/root.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
'use strict'
module.exports = root
var lineFeed = '\n'
// Stringify a root.
// Adds a final newline to ensure valid POSIX files. */
function root(node) {
return this.block(node) + lineFeed
}

18
node_modules/remark-stringify/lib/visitors/strong.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
'use strict'
var repeat = require('repeat-string')
module.exports = strong
// Stringify a `strong`.
//
// The marker used is configurable by `strong`, which defaults to an asterisk
// (`'*'`) but also accepts an underscore (`'_'`):
//
// ```markdown
// __foo__
// ```
function strong(node) {
var marker = repeat(this.options.strong, 2)
return marker + this.all(node).join('') + marker
}

View File

@@ -0,0 +1,7 @@
'use strict'
module.exports = tableCell
function tableCell(node) {
return this.all(node).join('')
}

68
node_modules/remark-stringify/lib/visitors/table.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
'use strict'
var markdownTable = require('markdown-table')
module.exports = table
var space = ' '
var verticalBar = '|'
// Stringify table.
//
// Creates a fenced table by default, but not in `looseTable: true` mode:
//
// ```markdown
// Foo | Bar
// :-: | ---
// Baz | Qux
//
// NOTE: Be careful with `looseTable: true` mode, as a loose table inside an
// indented code block on GitHub renders as an actual table!
//
// Creates a spaced table by default, but not in `spacedTable: false`:
//
// ```markdown
// |Foo|Bar|
// |:-:|---|
// |Baz|Qux|
// ```
function table(node) {
var self = this
var options = self.options
var loose = options.looseTable
var spaced = options.spacedTable
var pad = options.paddedTable
var stringLength = options.stringLength
var rows = node.children
var index = rows.length
var exit = self.enterTable()
var result = []
var start
var end
while (index--) {
result[index] = self.all(rows[index])
}
exit()
if (loose) {
start = ''
end = ''
} else if (spaced) {
start = verticalBar + space
end = space + verticalBar
} else {
start = verticalBar
end = verticalBar
}
return markdownTable(result, {
align: node.align,
pad: pad,
start: start,
end: end,
stringLength: stringLength,
delimiter: spaced ? space + verticalBar + space : verticalBar
})
}

19
node_modules/remark-stringify/lib/visitors/text.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
'use strict'
module.exports = text
// Stringify text.
// Supports named entities in `settings.encode: true` mode:
//
// ```markdown
// AT&amp;T
// ```
//
// Supports numbered entities in `settings.encode: numbers` mode:
//
// ```markdown
// AT&#x26;T
// ```
function text(node, parent) {
return this.encode(this.escape(node.value, node, parent), node)
}

View File

@@ -0,0 +1,31 @@
'use strict'
var repeat = require('repeat-string')
module.exports = thematic
var space = ' '
// Stringify a `thematic-break`.
// The character used is configurable through `rule`: (`'_'`):
//
// ```markdown
// ___
// ```
//
// The number of repititions is defined through `ruleRepetition` (`6`):
//
// ```markdown
// ******
// ```
//
// Whether spaces delimit each character, is configured through `ruleSpaces`
// (`true`):
// ```markdown
// * * *
// ```
function thematic() {
var options = this.options
var rule = repeat(options.rule, options.ruleRepetition)
return options.ruleSpaces ? rule.split('').join(space) : rule
}

View File

@@ -0,0 +1,250 @@
'use strict'
module.exports = markdownTable
var dotRe = /\./
var lastDotRe = /\.[^.]*$/
// Characters.
var space = ' '
var lineFeed = '\n'
var dash = '-'
var dot = '.'
var colon = ':'
var lowercaseC = 'c'
var lowercaseL = 'l'
var lowercaseR = 'r'
var verticalBar = '|'
var minCellSize = 3
// Create a table from a matrix of strings.
function markdownTable(table, options) {
var settings = options || {}
var delimiter = settings.delimiter
var start = settings.start
var end = settings.end
var alignment = settings.align
var calculateStringLength = settings.stringLength || lengthNoop
var cellCount = 0
var rowIndex = -1
var rowLength = table.length
var sizes = []
var align
var rule
var rows
var row
var cells
var index
var position
var size
var value
var spacing
var before
var after
alignment = alignment ? alignment.concat() : []
if (delimiter === null || delimiter === undefined) {
delimiter = space + verticalBar + space
}
if (start === null || start === undefined) {
start = verticalBar + space
}
if (end === null || end === undefined) {
end = space + verticalBar
}
while (++rowIndex < rowLength) {
row = table[rowIndex]
index = -1
if (row.length > cellCount) {
cellCount = row.length
}
while (++index < cellCount) {
position = row[index] ? dotindex(row[index]) : null
if (!sizes[index]) {
sizes[index] = minCellSize
}
if (position > sizes[index]) {
sizes[index] = position
}
}
}
if (typeof alignment === 'string') {
alignment = pad(cellCount, alignment).split('')
}
// Make sure only valid alignments are used.
index = -1
while (++index < cellCount) {
align = alignment[index]
if (typeof align === 'string') {
align = align.charAt(0).toLowerCase()
}
if (
align !== lowercaseL &&
align !== lowercaseR &&
align !== lowercaseC &&
align !== dot
) {
align = ''
}
alignment[index] = align
}
rowIndex = -1
rows = []
while (++rowIndex < rowLength) {
row = table[rowIndex]
index = -1
cells = []
while (++index < cellCount) {
value = row[index]
value = stringify(value)
if (alignment[index] === dot) {
position = dotindex(value)
size =
sizes[index] +
(dotRe.test(value) ? 0 : 1) -
(calculateStringLength(value) - position)
cells[index] = value + pad(size - 1)
} else {
cells[index] = value
}
}
rows[rowIndex] = cells
}
sizes = []
rowIndex = -1
while (++rowIndex < rowLength) {
cells = rows[rowIndex]
index = -1
while (++index < cellCount) {
value = cells[index]
if (!sizes[index]) {
sizes[index] = minCellSize
}
size = calculateStringLength(value)
if (size > sizes[index]) {
sizes[index] = size
}
}
}
rowIndex = -1
while (++rowIndex < rowLength) {
cells = rows[rowIndex]
index = -1
if (settings.pad !== false) {
while (++index < cellCount) {
value = cells[index]
position = sizes[index] - (calculateStringLength(value) || 0)
spacing = pad(position)
if (alignment[index] === lowercaseR || alignment[index] === dot) {
value = spacing + value
} else if (alignment[index] === lowercaseC) {
position /= 2
if (position % 1 === 0) {
before = position
after = position
} else {
before = position + 0.5
after = position - 0.5
}
value = pad(before) + value + pad(after)
} else {
value += spacing
}
cells[index] = value
}
}
rows[rowIndex] = cells.join(delimiter)
}
if (settings.rule !== false) {
index = -1
rule = []
while (++index < cellCount) {
// When `pad` is false, make the rule the same size as the first row.
if (settings.pad === false) {
value = table[0][index]
spacing = calculateStringLength(stringify(value))
spacing = spacing > minCellSize ? spacing : minCellSize
} else {
spacing = sizes[index]
}
align = alignment[index]
// When `align` is left, don't add colons.
value = align === lowercaseR || align === '' ? dash : colon
value += pad(spacing - 2, dash)
value += align !== lowercaseL && align !== '' ? colon : dash
rule[index] = value
}
rows.splice(1, 0, rule.join(delimiter))
}
return start + rows.join(end + lineFeed + start) + end
}
function stringify(value) {
return value === null || value === undefined ? '' : String(value)
}
// Get the length of `value`.
function lengthNoop(value) {
return String(value).length
}
// Get a string consisting of `length` `character`s.
function pad(length, character) {
return new Array(length + 1).join(character || space)
}
// Get the position of the last dot in `value`.
function dotindex(value) {
var match = lastDotRe.exec(value)
return match ? match.index + 1 : value.length
}

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,76 @@
{
"name": "markdown-table",
"version": "1.1.3",
"description": "Markdown/ASCII tables",
"license": "MIT",
"keywords": [
"text",
"markdown",
"table",
"align",
"ascii",
"rows",
"tabular"
],
"repository": "wooorm/markdown-table",
"bugs": "https://github.com/wooorm/markdown-table/issues",
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"files": [
"index.js"
],
"dependencies": {},
"devDependencies": {
"browserify": "^16.0.0",
"chalk": "^2.0.0",
"nyc": "^14.0.0",
"prettier": "^1.12.1",
"remark-cli": "^6.0.0",
"remark-preset-wooorm": "^4.0.0",
"strip-ansi": "^5.0.0",
"tape": "^4.4.0",
"tinyify": "^2.5.0",
"xo": "^0.24.0"
},
"scripts": {
"format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix",
"build-bundle": "browserify . -s markdownTable -o markdown-table.js",
"build-mangle": "browserify . -s markdownTable -p tinyify -o markdown-table.min.js",
"build": "npm run build-bundle && npm run build-mangle",
"test-api": "node test",
"test-coverage": "nyc --reporter lcov tape test.js",
"test": "npm run format && npm run build && npm run test-coverage"
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"esnext": false,
"rules": {
"complexity": "off",
"max-depth": "off"
},
"ignores": [
"markdown-table.js"
]
},
"nyc": {
"check-coverage": true,
"lines": 100,
"functions": 100,
"branches": 100
}
}

View File

@@ -0,0 +1,180 @@
# markdown-table
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
Generate fancy [Markdown][fancy]/ASCII tables.
## Installation
[npm][]:
```bash
npm install markdown-table
```
## Usage
Normal usage (defaults to left-alignment):
```javascript
var table = require('markdown-table')
table([
['Branch', 'Commit'],
['master', '0123456789abcdef'],
['staging', 'fedcba9876543210']
])
```
Yields:
```markdown
| Branch | Commit |
| ------- | ---------------- |
| master | 0123456789abcdef |
| staging | fedcba9876543210 |
```
With alignment:
```javascript
table(
[
['Beep', 'No.', 'Boop'],
['beep', '1024', 'xyz'],
['boop', '3388450', 'tuv'],
['foo', '10106', 'qrstuv'],
['bar', '45', 'lmno']
],
{
align: ['l', 'c', 'r']
}
)
```
Yields:
```markdown
| Beep | No. | Boop |
| :--- | :-----: | -----: |
| beep | 1024 | xyz |
| boop | 3388450 | tuv |
| foo | 10106 | qrstuv |
| bar | 45 | lmno |
```
Alignment on dots:
```javascript
table([['No.'], ['0.1.2'], ['11.22.33'], ['5.6.'], ['1.22222']], {
align: '.'
})
```
Yields:
```markdown
| No. |
| :---------: |
| 0.1.2 |
| 11.22.33 |
| 5.6. |
| 1.22222 |
```
## API
### `markdownTable(table[, options])`
Turns a given matrix of strings (an array of arrays of strings) into a table.
##### `options`
###### `options.align`
One style for all columns, or styles for their respective columns (`string` or
`Array.<string>`). Each style is either `'l'` (left), `'r'` (right), `'c'`
(centre), or `'.'` (dot). Other values are treated as `''`, which doesnt place
the colon but does left align. _Only the lowercased first character is used,
so `Right` is fine._
###### `options.delimiter`
Value to insert between cells (`string`, default: `' | '`). Careful, setting
this to a non-pipe breaks GitHub Flavoured Markdown.
###### `options.start`
Value to insert at the beginning of every row (`string`, default: `'| '`).
###### `options.end`
Value to insert at the end of every row (`string`, default: `' |'`).
###### `options.rule`
Whether to display a rule between the header and the body of the table
(`boolean`, default: `true`). Careful, will break GitHub Flavoured Markdown
when `false`.
###### `options.stringLength`
Method to detect the length of a cell (`Function`, default: `s => s.length`).
ANSI-sequences mess up tables on terminals. To fix this, you have to
pass in a `stringLength` option to detect the “visible” length of a
cell.
```javascript
var strip = require('strip-ansi')
function stringLength(cell) {
return strip(cell).length
}
```
###### `options.pad`
Whether to pad the markdown for table cells to make them the same width
(`boolean`, default: `true`). Setting this to false will cause the table
rows to remain staggered.
## Inspiration
The original idea and basic implementation was inspired by James
Hallidays [text-table][] library.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definitions -->
[build-badge]: https://img.shields.io/travis/wooorm/markdown-table.svg
[build]: https://travis-ci.org/wooorm/markdown-table
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/markdown-table.svg
[coverage]: https://codecov.io/github/wooorm/markdown-table
[downloads-badge]: https://img.shields.io/npm/dm/markdown-table.svg
[downloads]: https://www.npmjs.com/package/markdown-table
[size-badge]: https://img.shields.io/bundlephobia/minzip/markdown-table.svg
[size]: https://bundlephobia.com/result?p=markdown-table
[npm]: https://docs.npmjs.com/cli/install
[license]: license
[author]: https://wooorm.com
[fancy]: https://help.github.com/articles/github-flavored-markdown/#tables
[text-table]: https://github.com/substack/text-table

View File

@@ -0,0 +1,30 @@
'use strict'
/* eslint-env browser */
var el
var semicolon = 59 // ';'
module.exports = decodeEntity
function decodeEntity(characters) {
var entity = '&' + characters + ';'
var char
el = el || document.createElement('i')
el.innerHTML = entity
char = el.textContent
// Some entities do not require the closing semicolon (`&not` - for instance),
// which leads to situations where parsing the assumed entity of &notit; will
// result in the string `¬it;`. When we encounter a trailing semicolon after
// parsing and the entity to decode was not a semicolon (`&semi;`), we can
// assume that the matching was incomplete
if (char.charCodeAt(char.length - 1) === semicolon && characters !== 'semi') {
return false
}
// If the decoded string is equal to the input, the entity was not valid
return char === entity ? false : char
}

View File

@@ -0,0 +1,13 @@
'use strict'
var characterEntities = require('character-entities')
module.exports = decodeEntity
var own = {}.hasOwnProperty
function decodeEntity(characters) {
return own.call(characterEntities, characters)
? characterEntities[characters]
: false
}

View File

@@ -0,0 +1,450 @@
'use strict'
var legacy = require('character-entities-legacy')
var invalid = require('character-reference-invalid')
var decimal = require('is-decimal')
var hexadecimal = require('is-hexadecimal')
var alphanumerical = require('is-alphanumerical')
var decodeEntity = require('./decode-entity')
module.exports = parseEntities
var own = {}.hasOwnProperty
var fromCharCode = String.fromCharCode
var noop = Function.prototype
// Default settings.
var defaults = {
warning: null,
reference: null,
text: null,
warningContext: null,
referenceContext: null,
textContext: null,
position: {},
additional: null,
attribute: false,
nonTerminated: true
}
// Characters.
var tab = 9 // '\t'
var lineFeed = 10 // '\n'
var formFeed = 12 // '\f'
var space = 32 // ' '
var ampersand = 38 // '&'
var semicolon = 59 // ';'
var lessThan = 60 // '<'
var equalsTo = 61 // '='
var numberSign = 35 // '#'
var uppercaseX = 88 // 'X'
var lowercaseX = 120 // 'x'
var replacementCharacter = 65533 // '<27>'
// Reference types.
var name = 'named'
var hexa = 'hexadecimal'
var deci = 'decimal'
// Map of bases.
var bases = {}
bases[hexa] = 16
bases[deci] = 10
// Map of types to tests.
// Each type of character reference accepts different characters.
// This test is used to detect whether a reference has ended (as the semicolon
// is not strictly needed).
var tests = {}
tests[name] = alphanumerical
tests[deci] = decimal
tests[hexa] = hexadecimal
// Warning types.
var namedNotTerminated = 1
var numericNotTerminated = 2
var namedEmpty = 3
var numericEmpty = 4
var namedUnknown = 5
var numericDisallowed = 6
var numericProhibited = 7
// Warning messages.
var messages = {}
messages[namedNotTerminated] =
'Named character references must be terminated by a semicolon'
messages[numericNotTerminated] =
'Numeric character references must be terminated by a semicolon'
messages[namedEmpty] = 'Named character references cannot be empty'
messages[numericEmpty] = 'Numeric character references cannot be empty'
messages[namedUnknown] = 'Named character references must be known'
messages[numericDisallowed] =
'Numeric character references cannot be disallowed'
messages[numericProhibited] =
'Numeric character references cannot be outside the permissible Unicode range'
// Wrap to ensure clean parameters are given to `parse`.
function parseEntities(value, options) {
var settings = {}
var option
var key
if (!options) {
options = {}
}
for (key in defaults) {
option = options[key]
settings[key] =
option === null || option === undefined ? defaults[key] : option
}
if (settings.position.indent || settings.position.start) {
settings.indent = settings.position.indent || []
settings.position = settings.position.start
}
return parse(value, settings)
}
// Parse entities.
// eslint-disable-next-line complexity
function parse(value, settings) {
var additional = settings.additional
var nonTerminated = settings.nonTerminated
var handleText = settings.text
var handleReference = settings.reference
var handleWarning = settings.warning
var textContext = settings.textContext
var referenceContext = settings.referenceContext
var warningContext = settings.warningContext
var pos = settings.position
var indent = settings.indent || []
var length = value.length
var index = 0
var lines = -1
var column = pos.column || 1
var line = pos.line || 1
var queue = ''
var result = []
var entityCharacters
var namedEntity
var terminated
var characters
var character
var reference
var following
var warning
var reason
var output
var entity
var begin
var start
var type
var test
var prev
var next
var diff
var end
if (typeof additional === 'string') {
additional = additional.charCodeAt(0)
}
// Cache the current point.
prev = now()
// Wrap `handleWarning`.
warning = handleWarning ? parseError : noop
// Ensure the algorithm walks over the first character and the end (inclusive).
index--
length++
while (++index < length) {
// If the previous character was a newline.
if (character === lineFeed) {
column = indent[lines] || 1
}
character = value.charCodeAt(index)
if (character === ampersand) {
following = value.charCodeAt(index + 1)
// The behaviour depends on the identity of the next character.
if (
following === tab ||
following === lineFeed ||
following === formFeed ||
following === space ||
following === ampersand ||
following === lessThan ||
following !== following ||
(additional && following === additional)
) {
// Not a character reference.
// No characters are consumed, and nothing is returned.
// This is not an error, either.
queue += fromCharCode(character)
column++
continue
}
start = index + 1
begin = start
end = start
if (following === numberSign) {
// Numerical entity.
end = ++begin
// The behaviour further depends on the next character.
following = value.charCodeAt(end)
if (following === uppercaseX || following === lowercaseX) {
// ASCII hex digits.
type = hexa
end = ++begin
} else {
// ASCII digits.
type = deci
}
} else {
// Named entity.
type = name
}
entityCharacters = ''
entity = ''
characters = ''
test = tests[type]
end--
while (++end < length) {
following = value.charCodeAt(end)
if (!test(following)) {
break
}
characters += fromCharCode(following)
// Check if we can match a legacy named reference.
// If so, we cache that as the last viable named reference.
// This ensures we do not need to walk backwards later.
if (type === name && own.call(legacy, characters)) {
entityCharacters = characters
entity = legacy[characters]
}
}
terminated = value.charCodeAt(end) === semicolon
if (terminated) {
end++
namedEntity = type === name ? decodeEntity(characters) : false
if (namedEntity) {
entityCharacters = characters
entity = namedEntity
}
}
diff = 1 + end - start
if (!terminated && !nonTerminated) {
// Empty.
} else if (!characters) {
// An empty (possible) entity is valid, unless its numeric (thus an
// ampersand followed by an octothorp).
if (type !== name) {
warning(numericEmpty, diff)
}
} else if (type === name) {
// An ampersand followed by anything unknown, and not terminated, is
// invalid.
if (terminated && !entity) {
warning(namedUnknown, 1)
} else {
// If theres something after an entity name which is not known, cap
// the reference.
if (entityCharacters !== characters) {
end = begin + entityCharacters.length
diff = 1 + end - begin
terminated = false
}
// If the reference is not terminated, warn.
if (!terminated) {
reason = entityCharacters ? namedNotTerminated : namedEmpty
if (settings.attribute) {
following = value.charCodeAt(end)
if (following === equalsTo) {
warning(reason, diff)
entity = null
} else if (alphanumerical(following)) {
entity = null
} else {
warning(reason, diff)
}
} else {
warning(reason, diff)
}
}
}
reference = entity
} else {
if (!terminated) {
// All non-terminated numeric entities are not rendered, and trigger a
// warning.
warning(numericNotTerminated, diff)
}
// When terminated and number, parse as either hexadecimal or decimal.
reference = parseInt(characters, bases[type])
// Trigger a warning when the parsed number is prohibited, and replace
// with replacement character.
if (prohibited(reference)) {
warning(numericProhibited, diff)
reference = fromCharCode(replacementCharacter)
} else if (reference in invalid) {
// Trigger a warning when the parsed number is disallowed, and replace
// by an alternative.
warning(numericDisallowed, diff)
reference = invalid[reference]
} else {
// Parse the number.
output = ''
// Trigger a warning when the parsed number should not be used.
if (disallowed(reference)) {
warning(numericDisallowed, diff)
}
// Stringify the number.
if (reference > 0xffff) {
reference -= 0x10000
output += fromCharCode((reference >>> (10 & 0x3ff)) | 0xd800)
reference = 0xdc00 | (reference & 0x3ff)
}
reference = output + fromCharCode(reference)
}
}
// Found it!
// First eat the queued characters as normal text, then eat an entity.
if (reference) {
flush()
prev = now()
index = end - 1
column += end - start + 1
result.push(reference)
next = now()
next.offset++
if (handleReference) {
handleReference.call(
referenceContext,
reference,
{start: prev, end: next},
value.slice(start - 1, end)
)
}
prev = next
} else {
// If we could not find a reference, queue the checked characters (as
// normal characters), and move the pointer to their end.
// This is possible because we can be certain neither newlines nor
// ampersands are included.
characters = value.slice(start - 1, end)
queue += characters
column += characters.length
index = end - 1
}
} else {
// Handle anything other than an ampersand, including newlines and EOF.
if (
character === 10 // Line feed
) {
line++
lines++
column = 0
}
if (character === character) {
queue += fromCharCode(character)
column++
} else {
flush()
}
}
}
// Return the reduced nodes, and any possible warnings.
return result.join('')
// Get current position.
function now() {
return {
line: line,
column: column,
offset: index + (pos.offset || 0)
}
}
// “Throw” a parse-error: a warning.
function parseError(code, offset) {
var position = now()
position.column += offset
position.offset += offset
handleWarning.call(warningContext, messages[code], position, code)
}
// Flush `queue` (normal text).
// Macro invoked before each entity and at the end of `value`.
// Does nothing when `queue` is empty.
function flush() {
if (queue) {
result.push(queue)
if (handleText) {
handleText.call(textContext, queue, {start: prev, end: now()})
}
queue = ''
}
}
}
// Check if `character` is outside the permissible unicode range.
function prohibited(code) {
return (code >= 0xd800 && code <= 0xdfff) || code > 0x10ffff
}
// Check if `character` is disallowed.
function disallowed(code) {
return (
(code >= 0x0001 && code <= 0x0008) ||
code === 0x000b ||
(code >= 0x000d && code <= 0x001f) ||
(code >= 0x007f && code <= 0x009f) ||
(code >= 0xfdd0 && code <= 0xfdef) ||
(code & 0xffff) === 0xffff ||
(code & 0xffff) === 0xfffe
)
}

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Titus Wormer <mailto:tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,91 @@
{
"name": "parse-entities",
"version": "1.2.2",
"description": "Parse HTML character references: fast, spec-compliant, positional information",
"license": "MIT",
"keywords": [
"parse",
"html",
"character",
"reference",
"entity",
"entities"
],
"repository": "wooorm/parse-entities",
"bugs": "https://github.com/wooorm/parse-entities/issues",
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"browser": {
"./decode-entity.js": "./decode-entity.browser.js"
},
"react-native": {
"./decode-entity.js": "./decode-entity.js"
},
"files": [
"index.js",
"decode-entity.js",
"decode-entity.browser.js"
],
"dependencies": {
"character-entities": "^1.0.0",
"character-entities-legacy": "^1.0.0",
"character-reference-invalid": "^1.0.0",
"is-alphanumerical": "^1.0.0",
"is-decimal": "^1.0.0",
"is-hexadecimal": "^1.0.0"
},
"devDependencies": {
"browserify": "^16.0.0",
"nyc": "^14.0.0",
"prettier": "^1.12.1",
"remark-cli": "^6.0.0",
"remark-preset-wooorm": "^4.0.0",
"tape": "^4.2.0",
"tape-run": "^6.0.0",
"tinyify": "^2.4.3",
"xo": "^0.24.0"
},
"scripts": {
"format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix",
"build-bundle": "browserify . -s parseEntities > parse-entities.js",
"build-mangle": "browserify . -s parseEntities -p tinyify > parse-entities.min.js",
"build": "npm run build-bundle && npm run build-mangle",
"test-api": "node test",
"test-coverage": "nyc --reporter lcov tape test.js",
"test-browser": "browserify test.js | tape-run",
"test": "npm run format && npm run build && npm run test-coverage && npm run test-browser"
},
"nyc": {
"check-coverage": true,
"lines": 100,
"functions": 100,
"branches": 100
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"esnext": false,
"rules": {
"no-self-compare": "off",
"guard-for-in": "off",
"max-depth": "off"
},
"ignores": [
"parse-entities.js"
]
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
}
}

View File

@@ -0,0 +1,217 @@
# parse-entities
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
Parse HTML character references: fast, spec-compliant, positional
information.
## Installation
[npm][]:
```bash
npm install parse-entities
```
## Usage
```js
var decode = require('parse-entities')
decode('alpha &amp bravo')
// => alpha & bravo
decode('charlie &copycat; delta')
// => charlie ©cat; delta
decode('echo &copy; foxtrot &#8800; golf &#x1D306; hotel')
// => echo © foxtrot ≠ golf 𝌆 hotel
```
## API
## `parseEntities(value[, options])`
##### `options`
###### `options.additional`
Additional character to accept (`string?`, default: `''`).
This allows other characters, without error, when following an ampersand.
###### `options.attribute`
Whether to parse `value` as an attribute value (`boolean?`, default:
`false`).
###### `options.nonTerminated`
Whether to allow non-terminated entities (`boolean`, default: `true`).
For example, `&copycat` for `©cat`. This behaviour is spec-compliant but
can lead to unexpected results.
###### `options.warning`
Error handler ([`Function?`][warning]).
###### `options.text`
Text handler ([`Function?`][text]).
###### `options.reference`
Reference handler ([`Function?`][reference]).
###### `options.warningContext`
Context used when invoking `warning` (`'*'`, optional).
###### `options.textContext`
Context used when invoking `text` (`'*'`, optional).
###### `options.referenceContext`
Context used when invoking `reference` (`'*'`, optional)
###### `options.position`
Starting `position` of `value` (`Location` or `Position`, optional). Useful
when dealing with values nested in some sort of syntax tree. The default is:
```js
{
start: {line: 1, column: 1, offset: 0},
indent: []
}
```
##### Returns
`string` — Decoded `value`.
### `function warning(reason, position, code)`
Error handler.
##### Context
`this` refers to `warningContext` when given to `parseEntities`.
##### Parameters
###### `reason`
Human-readable reason for triggering a parse error (`string`).
###### `position`
Place at which the parse error occurred (`Position`).
###### `code`
Identifier of reason for triggering a parse error (`number`).
The following codes are used:
| Code | Example | Note |
| ---- | ------------------ | --------------------------------------------- |
| `1` | `foo &amp bar` | Missing semicolon (named) |
| `2` | `foo &#123 bar` | Missing semicolon (numeric) |
| `3` | `Foo &bar baz` | Ampersand did not start a reference |
| `4` | `Foo &#` | Empty reference |
| `5` | `Foo &bar; baz` | Unknown entity |
| `6` | `Foo &#128; baz` | [Disallowed reference][invalid] |
| `7` | `Foo &#xD800; baz` | Prohibited: outside permissible unicode range |
### `function text(value, location)`
Text handler.
##### Context
`this` refers to `textContext` when given to `parseEntities`.
##### Parameters
###### `value`
String of content (`string`).
###### `location`
Location at which `value` starts and ends (`Location`).
### `function reference(value, location, source)`
Character reference handler.
##### Context
`this` refers to `referenceContext` when given to `parseEntities`.
##### Parameters
###### `value`
Encoded character reference (`string`).
###### `location`
Location at which `value` starts and ends (`Location`).
###### `source`
Source of character reference (`Location`).
## Related
* [`stringify-entities`](https://github.com/wooorm/stringify-entities)
— Encode HTML character references
* [`character-entities`](https://github.com/wooorm/character-entities)
— Info on character entities
* [`character-entities-html4`](https://github.com/wooorm/character-entities-html4)
— Info on HTML4 character entities
* [`character-entities-legacy`](https://github.com/wooorm/character-entities-legacy)
— Info on legacy character entities
* [`character-reference-invalid`](https://github.com/wooorm/character-reference-invalid)
— Info on invalid numeric character references
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definitions -->
[build-badge]: https://img.shields.io/travis/wooorm/parse-entities.svg
[build]: https://travis-ci.org/wooorm/parse-entities
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/parse-entities.svg
[coverage]: https://codecov.io/github/wooorm/parse-entities
[downloads-badge]: https://img.shields.io/npm/dm/parse-entities.svg
[downloads]: https://www.npmjs.com/package/parse-entities
[size-badge]: https://img.shields.io/bundlephobia/minzip/parse-entities.svg
[size]: https://bundlephobia.com/result?p=parse-entities
[npm]: https://docs.npmjs.com/cli/install
[license]: license
[author]: https://wooorm.com
[warning]: #function-warningreason-position-code
[text]: #function-textvalue-location
[reference]: #function-referencevalue-location-source
[invalid]: https://github.com/wooorm/character-reference-invalid

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Titus Wormer <mailto:tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,10 @@
[
"cent",
"copy",
"divide",
"gt",
"lt",
"not",
"para",
"times"
]

View File

@@ -0,0 +1,134 @@
'use strict'
var entities = require('character-entities-html4')
var legacy = require('character-entities-legacy')
var hexadecimal = require('is-hexadecimal')
var alphanumerical = require('is-alphanumerical')
var dangerous = require('./dangerous.json')
/* Expose. */
module.exports = encode
encode.escape = escape
var own = {}.hasOwnProperty
/* List of enforced escapes. */
var escapes = ['"', "'", '<', '>', '&', '`']
/* Map of characters to names. */
var characters = construct()
/* Default escapes. */
var defaultEscapes = toExpression(escapes)
/* Surrogate pairs. */
var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g
/* Non-ASCII characters. */
// eslint-disable-next-line no-control-regex, unicorn/no-hex-escape
var bmp = /[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g
/* Encode special characters in `value`. */
function encode(value, options) {
var settings = options || {}
var subset = settings.subset
var set = subset ? toExpression(subset) : defaultEscapes
var escapeOnly = settings.escapeOnly
var omit = settings.omitOptionalSemicolons
value = value.replace(set, function(char, pos, val) {
return one(char, val.charAt(pos + 1), settings)
})
if (subset || escapeOnly) {
return value
}
return value
.replace(surrogatePair, replaceSurrogatePair)
.replace(bmp, replaceBmp)
function replaceSurrogatePair(pair, pos, val) {
return toHexReference(
(pair.charCodeAt(0) - 0xd800) * 0x400 +
pair.charCodeAt(1) -
0xdc00 +
0x10000,
val.charAt(pos + 2),
omit
)
}
function replaceBmp(char, pos, val) {
return one(char, val.charAt(pos + 1), settings)
}
}
/* Shortcut to escape special characters in HTML. */
function escape(value) {
return encode(value, {
escapeOnly: true,
useNamedReferences: true
})
}
/* Encode `char` according to `options`. */
function one(char, next, options) {
var shortest = options.useShortestReferences
var omit = options.omitOptionalSemicolons
var named
var numeric
if ((shortest || options.useNamedReferences) && own.call(characters, char)) {
named = toNamed(characters[char], next, omit, options.attribute)
}
if (shortest || !named) {
numeric = toHexReference(char.charCodeAt(0), next, omit)
}
if (named && (!shortest || named.length < numeric.length)) {
return named
}
return numeric
}
/* Transform `code` into an entity. */
function toNamed(name, next, omit, attribute) {
var value = '&' + name
if (
omit &&
own.call(legacy, name) &&
dangerous.indexOf(name) === -1 &&
(!attribute || (next && next !== '=' && !alphanumerical(next)))
) {
return value
}
return value + ';'
}
/* Transform `code` into a hexadecimal character reference. */
function toHexReference(code, next, omit) {
var value = '&#x' + code.toString(16).toUpperCase()
return omit && next && !hexadecimal(next) ? value : value + ';'
}
/* Create an expression for `characters`. */
function toExpression(characters) {
return new RegExp('[' + characters.join('') + ']', 'g')
}
/* Construct the map. */
function construct() {
var chars = {}
var name
for (name in entities) {
chars[entities[name]] = name
}
return chars
}

View File

@@ -0,0 +1,84 @@
{
"name": "stringify-entities",
"version": "1.3.2",
"description": "Encode HTML character references and character entities",
"license": "MIT",
"keywords": [
"stringify",
"encode",
"escape",
"html",
"character",
"reference",
"entity",
"entities"
],
"repository": "wooorm/stringify-entities",
"bugs": "https://github.com/wooorm/stringify-entities/issues",
"author": "Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)"
],
"files": [
"dangerous.json",
"index.js"
],
"dependencies": {
"character-entities-html4": "^1.0.0",
"character-entities-legacy": "^1.0.0",
"is-alphanumerical": "^1.0.0",
"is-hexadecimal": "^1.0.0"
},
"devDependencies": {
"browserify": "^16.0.0",
"character-entities": "^1.0.0",
"esmangle": "^1.0.0",
"nyc": "^11.0.0",
"remark-cli": "^5.0.0",
"remark-preset-wooorm": "^4.0.0",
"tape": "^4.0.0",
"xo": "^0.20.0"
},
"scripts": {
"generate": "node build",
"format": "remark . -qfo && prettier --write '**/*.js' && xo --fix",
"build-bundle": "browserify index.js --bare -s stringifyEntities > stringify-entities.js",
"build-mangle": "esmangle stringify-entities.js > stringify-entities.min.js",
"build": "npm run build-bundle && npm run build-mangle",
"test-api": "node test",
"test-coverage": "nyc --reporter lcov tape test.js",
"test": "npm run generate && npm run format && npm run build && npm run test-coverage"
},
"nyc": {
"check-coverage": true,
"lines": 100,
"functions": 100,
"branches": 100
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"esnext": false,
"rules": {
"no-var": "off",
"unicorn/number-literal-case": "off",
"prefer-arrow-callback": "off",
"guard-for-in": "off"
},
"ignores": [
"stringify-entities.js"
]
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
}
}

View File

@@ -0,0 +1,131 @@
# stringify-entities [![Build Status][build-badge]][build-status] [![Coverage Status][coverage-badge]][coverage-status]
Encode HTML character references and character entities.
* [x] Very fast
* [x] Just the encoding part
* [x] Reliable: ``'`'`` characters are escaped to ensure no scripts
run in IE6-8. Additionally, only named entities recognised by HTML4
are encoded, meaning the infamous `&apos;` (which people think is a
[virus][]) wont show up
## Algorithm
By default, all dangerous, non-ASCII, or non-printable ASCII characters
are encoded. A [subset][] of characters can be given to encode just
those characters. Alternatively, pass [`escapeOnly`][escapeonly] to
escape just the dangerous characters (`"`, `'`, `<`, `>`, `&`, `` ` ``).
By default, numeric entities are used. Pass [`useNamedReferences`][named]
to use named entities when possible, or [`useShortestReferences`][short]
to use them if that results in less bytes.
## Installation
[npm][]:
```bash
npm install stringify-entities
```
## Usage
```js
var stringify = require('stringify-entities')
stringify('alpha © bravo ≠ charlie 𝌆 delta')
// => 'alpha &#xA9; bravo &#x2260; charlie &#x1D306; delta'
stringify('alpha © bravo ≠ charlie 𝌆 delta', {useNamedReferences: true})
// => 'alpha &copy; bravo &ne; charlie &#x1D306; delta'
```
## API
### `stringifyEntities(value[, options])`
Encode special characters in `value`.
##### `options`
###### `options.escapeOnly`
Whether to only escape possibly dangerous characters (`boolean`,
default: `false`). Those characters are `"`, `'`, `<`, `>` `&`, and
`` ` ``.
###### `options.subset`
Whether to only escape the given subset of characters (`Array.<string>`).
###### `options.useNamedReferences`
Whether to use named entities where possible (`boolean?`, default:
`false`).
###### `options.useShortestReferences`
Whether to use named entities, where possible, if that results in less
bytes (`boolean?`, default: `false`). **Note**: `useNamedReferences`
can be omitted when using `useShortestReferences`.
###### `options.omitOptionalSemicolons`
Whether to omit semi-colons when possible (`boolean?`, default: `false`).
**Note**: This creates parse errors: dont use this except when building
a minifier.
Omitting semi-colons is possible for [certain][dangerous] [legacy][]
named references, and numeric entities, in some cases.
###### `options.attribute`
Only needed when operating dangerously with `omitOptionalSemicolons: true`.
Create entities which dont fail in attributes (`boolean?`, default:
`false`).
## Related
* [`parse-entities`](https://github.com/wooorm/parse-entities)
— Parse HTML character references
* [`character-entities`](https://github.com/wooorm/character-entities)
— Info on character entities
* [`character-entities-html4`](https://github.com/wooorm/character-entities-html4)
— Info on HTML4 character entities
* [`character-entities-legacy`](https://github.com/wooorm/character-entities-legacy)
— Info on legacy character entities
* [`character-reference-invalid`](https://github.com/wooorm/character-reference-invalid)
— Info on invalid numeric character references
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definitions -->
[build-badge]: https://img.shields.io/travis/wooorm/stringify-entities.svg
[build-status]: https://travis-ci.org/wooorm/stringify-entities
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/stringify-entities.svg
[coverage-status]: https://codecov.io/github/wooorm/stringify-entities
[license]: LICENSE
[author]: http://wooorm.com
[npm]: https://docs.npmjs.com/cli/install
[virus]: http://www.telegraph.co.uk/technology/advice/10516839/Why-do-some-apostrophes-get-replaced-with-andapos.html
[dangerous]: dangerous.json
[legacy]: https://github.com/wooorm/character-entities-legacy
[subset]: #optionssubset
[escapeonly]: #optionsescapeonly
[named]: #optionsusenamedreferences
[short]: #optionsuseshortestreferences

53
node_modules/remark-stringify/package.json generated vendored Normal file
View File

@@ -0,0 +1,53 @@
{
"name": "remark-stringify",
"version": "6.0.4",
"description": "Markdown compiler for remark",
"license": "MIT",
"keywords": [
"markdown",
"abstract",
"syntax",
"tree",
"ast",
"stringify"
],
"homepage": "https://remark.js.org",
"repository": "https://github.com/remarkjs/remark/tree/master/packages/remark-stringify",
"bugs": "https://github.com/remarkjs/remark/issues",
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"Eugene Sharygin <eush77@gmail.com>"
],
"files": [
"index.js",
"lib"
],
"dependencies": {
"ccount": "^1.0.0",
"is-alphanumeric": "^1.0.0",
"is-decimal": "^1.0.0",
"is-whitespace-character": "^1.0.0",
"longest-streak": "^2.0.1",
"markdown-escapes": "^1.0.0",
"markdown-table": "^1.1.0",
"mdast-util-compact": "^1.0.0",
"parse-entities": "^1.0.2",
"repeat-string": "^1.5.4",
"state-toggle": "^1.0.0",
"stringify-entities": "^1.0.1",
"unherit": "^1.0.4",
"xtend": "^4.0.1"
},
"devDependencies": {
"tape": "^4.9.1",
"unified": "^7.0.0",
"unist-builder": "^1.0.3",
"unist-util-visit": "^1.4.0",
"wcwidth": "^1.0.1"
},
"scripts": {
"test": "tape test.js"
},
"xo": false
}

311
node_modules/remark-stringify/readme.md generated vendored Normal file
View File

@@ -0,0 +1,311 @@
# remark-stringify [![Travis][build-badge]][build-status] [![Coverage][coverage-badge]][coverage-status] [![Downloads][dl-badge]][dl] [![Size][size-badge]][size] [![Chat][chat-badge]][chat]
[Compiler][] for [**unified**][unified].
Stringifies [**mdast**][mdast] syntax trees to markdown.
Used in the [**remark** processor][processor] but can be used on its own as
well.
Can be [extended][extend] to change how markdown is parsed.
* * *
**Announcing the unified collective! 🎉
[Read more about it on Medium »][announcement]**
## Sponsors
<!--lint ignore no-html maximum-line-length-->
<table>
<tr valign="top">
<td width="20%" align="center">
<a href="https://zeit.co"><img src="https://avatars1.githubusercontent.com/u/14985020?s=400&v=4"></a>
<br><br>🥇
<a href="https://zeit.co">ZEIT</a>
</td>
<td width="20%" align="center">
<a href="https://www.gatsbyjs.org"><img src="https://avatars1.githubusercontent.com/u/12551863?s=400&v=4"></a>
<br><br>🥇
<a href="https://www.gatsbyjs.org">Gatsby</a></td>
<td width="20%" align="center">
<a href="https://compositor.io"><img src="https://avatars1.githubusercontent.com/u/19245838?s=400&v=4"></a>
<br><br>🥉
<a href="https://compositor.io">Compositor</a>
</td>
<td width="20%" align="center">
<a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=400&v=4"></a>
<br><br>
<a href="https://www.holloway.com">Holloway</a>
</td>
<td width="20%" align="center">
<br><br><br><br>
<a href="https://opencollective.com/unified"><strong>You?</strong>
</td>
</tr>
</table>
## Installation
[npm][]:
```sh
npm install remark-stringify
```
## Usage
```js
var unified = require('unified')
var createStream = require('unified-stream')
var parse = require('remark-parse')
var toc = require('remark-toc')
var stringify = require('remark-stringify')
var processor = unified()
.use(parse)
.use(toc)
.use(stringify, {
bullet: '*',
fence: '~',
fences: true,
incrementListMarker: false
})
process.stdin.pipe(createStream(processor)).pipe(process.stdout)
```
## Table of Contents
* [API](#api)
* [processor.use(stringify\[, options\])](#processorusestringify-options)
* [stringify.Compiler](#stringifycompiler)
* [Extending the Compiler](#extending-the-compiler)
* [Compiler#visitors](#compilervisitors)
* [function visitor(node\[, parent\])](#function-visitornode-parent)
* [License](#license)
## API
### `processor.use(stringify[, options])`
Configure the `processor` to stringify [**mdast**][mdast] syntax trees
to markdown.
##### `options`
Options are passed directly, or passed later through [`processor.data()`][data].
###### `options.gfm`
Stringify with the required escapes for GFM compatible markdown (`boolean`,
default: `true`).
* Escape pipes (`|`, for tables)
* Escape colons (`:`, for literal URLs)
* Escape tildes (`~`, for strike-through)
###### `options.commonmark`
Stringify for CommonMark compatible markdown (`boolean`, default: `false`).
* Compile adjacent blockquotes separately
* Escape more characters using slashes, instead of as entities
###### `options.pedantic`
Stringify for pedantic compatible markdown (`boolean`, default: `false`).
* Escape underscores in words
###### `options.entities`
How to stringify entities (`string` or `boolean`, default: `false`):
* `true` — Entities are generated for special HTML characters
(`&` > `&amp;`) and non-ASCII characters (`©` > `&copy;`).
If named entities are not (widely) supported, numbered character
references are used (`` > `&#x2019;`)
* `'numbers'` — Numbered entities are generated (`&` > `&#x26;`)
for special HTML characters and non-ASCII characters
* `'escape'` — Special HTML characters are encoded (`&` >
`&amp;`, `` > `&#x2019;`), non-ASCII characters not (ö persists)
###### `options.setext`
Compile headings, when possible, in Setext-style (`boolean`, default: `false`).
Uses `=` for level one headings and `-` for level two headings. Other heading
levels are compiled as ATX (respecting `closeAtx`).
###### `options.closeAtx`
Compile ATX headings with the same amount of closing hashes as opening hashes
(`boolean`, default: `false`).
###### `options.looseTable`
Create tables without fences: initial and final pipes (`boolean`, default:
`false`).
###### `options.spacedTable`
Create tables without spacing between pipes and content (`boolean`, default:
`true`).
###### `options.paddedTable`
Create tables with padding in each cell so that they are the same size
(`boolean`, default: `true`).
###### `options.stringLength`
Function passed to [`markdown-table`][markdown-table] to detect the length of a
table cell (`Function`, default: [`s => s.length`][string-length]).
###### `options.fence`
Fence marker to use for code blocks (`'~'` or ``'`'``, default: ``'`'``).
###### `options.fences`
Stringify code blocks without language with fences (`boolean`, default:
`false`).
###### `options.bullet`
Bullet marker to use for unordered list items (`'-'`, `'*'`, or `'+'`,
default: `'-'`).
###### `options.listItemIndent`
How to indent the content from list items (`'tab'`, `'mixed'` or `'1'`,
default: `'tab'`).
* `'tab'`: use tab stops (4 spaces)
* `'1'`: use one space
* `'mixed'`: use `1` for tight and `tab` for loose list items
###### `options.incrementListMarker`
Whether to increment ordered list item bullets (`boolean`, default: `true`).
###### `options.rule`
Marker to use for thematic breaks / horizontal rules (`'-'`, `'*'`, or `'_'`,
default: `'*'`).
###### `options.ruleRepetition`
Number of markers to use for thematic breaks / horizontal rules (`number`,
default: `3`). Should be `3` or more.
###### `options.ruleSpaces`
Whether to pad thematic break (horizontal rule) markers with spaces (`boolean`,
default `true`).
###### `options.strong`
Marker to use for importance (`'_'` or `'*'`, default `'*'`).
###### `options.emphasis`
Marker to use for emphasis (`'_'` or `'*'`, default `'_'`).
### `stringify.Compiler`
Access to the raw [compiler][], if you need it.
## Extending the Compiler
If this plugin is used, it adds a [`Compiler`][compiler] constructor
to the `processor`. Other plugins can change and add visitors on
the compilers prototype to change how markdown is stringified.
The below plugin modifies a [visitor][] to add an extra blank line
before level two headings.
```js
module.exports = gap
function gap() {
var Compiler = this.Compiler
var visitors = Compiler.prototype.visitors
var original = visitors.heading
visitors.heading = heading
function heading(node) {
return (node.depth === 2 ? '\n' : '') + original.apply(this, arguments)
}
}
```
### `Compiler#visitors`
An object mapping [node][] types to [`visitor`][visitor]s.
### `function visitor(node[, parent])`
Stringify `node`.
###### Parameters
* `node` ([`Node`][node]) — Node to compile
* `parent` ([`Node`][node], optional) — Parent of `node`
###### Returns
`string`, the compiled given `node`.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definitions -->
[build-badge]: https://img.shields.io/travis/remarkjs/remark/master.svg
[build-status]: https://travis-ci.org/remarkjs/remark
[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark.svg
[coverage-status]: https://codecov.io/github/remarkjs/remark
[dl-badge]: https://img.shields.io/npm/dm/remark-stringify.svg
[dl]: https://www.npmjs.com/package/remark-stringify
[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-stringify.svg
[size]: https://bundlephobia.com/result?p=remark-stringify
[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg
[chat]: https://spectrum.chat/unified/remark
[license]: https://github.com/remarkjs/remark/blob/master/license
[author]: https://wooorm.com
[npm]: https://docs.npmjs.com/cli/install
[unified]: https://github.com/unifiedjs/unified
[processor]: https://github.com/remarkjs/remark
[data]: https://github.com/unifiedjs/unified#processordatakey-value
[compiler]: https://github.com/unifiedjs/unified#processorcompiler
[mdast]: https://github.com/syntax-tree/mdast
[node]: https://github.com/syntax-tree/unist#node
[extend]: #extending-the-compiler
[visitor]: #function-visitornode-parent
[markdown-table]: https://github.com/wooorm/markdown-table
[string-length]: https://github.com/wooorm/markdown-table#stringlengthcell
[announcement]: https://medium.com/unifiedjs/collectively-evolving-through-crowdsourcing-22c359ea95cc