Skip to content

Commit

Permalink
Add _ to identifier names
Browse files Browse the repository at this point in the history
*   Add support for underscore in names to prevent interference w/ gemoji
*   Disallow underscore at end of name to prevent interference w/ emphasis

Related to GH-651.
  • Loading branch information
wooorm authored May 5, 2021
1 parent fb00d9b commit e3486e5
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 6 deletions.
11 changes: 9 additions & 2 deletions lib/factory-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ var asciiAlpha = require('micromark/dist/character/ascii-alpha')
var asciiAlphanumeric = require('micromark/dist/character/ascii-alphanumeric')

function createName(effects, ok, nok, nameType) {
var self = this

return start

function start(code) {
Expand All @@ -19,12 +21,17 @@ function createName(effects, ok, nok, nameType) {
}

function name(code) {
if (code === 45 /* `-` */ || asciiAlphanumeric(code)) {
if (
code === 45 /* `-` */ ||
code === 95 /* `_` */ ||
asciiAlphanumeric(code)
) {
effects.consume(code)
return name
}

effects.exit(nameType)
return ok(code)
// To do next major: disallow `-` at end of name too, for consistency.
return self.previous === 95 /* `_` */ ? nok(code) : ok(code)
}
}
8 changes: 7 additions & 1 deletion lib/tokenize-directive-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
}

effects.exit('directiveContainerSequence')
return createName(effects, afterName, nok, 'directiveContainerName')(code)
return createName.call(
self,
effects,
afterName,
nok,
'directiveContainerName'
)(code)
}

function afterName(code) {
Expand Down
4 changes: 3 additions & 1 deletion lib/tokenize-directive-leaf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true}

function tokenizeDirectiveLeaf(effects, ok, nok) {
var self = this

return start

function start(code) {
Expand All @@ -28,7 +30,7 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
if (code === 58 /* `:` */) {
effects.consume(code)
effects.exit('directiveLeafSequence')
return createName(effects, afterName, nok, 'directiveLeafName')
return createName.call(self, effects, afterName, nok, 'directiveLeafName')
}

return nok(code)
Expand Down
2 changes: 1 addition & 1 deletion lib/tokenize-directive-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function tokenizeDirectiveText(effects, ok, nok) {
effects.enter('directiveTextMarker')
effects.consume(code)
effects.exit('directiveTextMarker')
return createName(effects, afterName, nok, 'directiveTextName')
return createName.call(self, effects, afterName, nok, 'directiveTextName')
}

function afterName(code) {
Expand Down
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ He dies.
:::

The `name` part is required. The first character must be a letter, other
characters can be alphanumerical and `-`.
characters can be alphanumerical, `-`, and `_`.
`_` cannot end a name.

The `[label]` part is optional (`:x` and `:x[]` are equivalent)†.
When used, it can include text constructs such as emphasis and so on: `x[a *b*
Expand Down
42 changes: 42 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ test('micromark-extension-directive (syntax)', function (t) {
'should not support a colon followed by a dash'
)

t.equal(
micromark(':_', options()),
'<p>:_</p>',
'should not support a colon followed by an underscore'
)

t.equal(
micromark(':a9', options()),
'<p></p>',
Expand All @@ -60,12 +66,48 @@ test('micromark-extension-directive (syntax)', function (t) {
'should support a dash in a name'
)

t.equal(
micromark(':a_b', options()),
'<p></p>',
'should support an underscore in a name'
)

t.equal(
micromark(':a_', options()),
'<p>:a_</p>',
'should *not* support an underscore at the end of a name'
)

t.equal(
micromark(':a:', options()),
'<p>:a:</p>',
'should *not* support a colon right after a name'
)

t.equal(
micromark(':+1:', options()),
'<p>:+1:</p>',
'should not interfere w/ gemoji (1)'
)

t.equal(
micromark(':heart:', options()),
'<p>:heart:</p>',
'should not interfere w/ gemoji (2)'
)

t.equal(
micromark(':call_me_hand:', options()),
'<p>:call_me_hand:</p>',
'should not interfere w/ gemoji (3)'
)

t.equal(
micromark('_:directive_', options()),
'<p><em>:directive</em></p>',
'should not interfere w/ emphasis (`_`)'
)

t.equal(
micromark(':a[', options()),
'<p>[</p>',
Expand Down

0 comments on commit e3486e5

Please sign in to comment.