Skip to content

Commit

Permalink
Add support for Twitter, custom handles
Browse files Browse the repository at this point in the history
Closes GH-6.
  • Loading branch information
wooorm committed Apr 24, 2020
1 parent 543c411 commit 641f66f
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 32 deletions.
86 changes: 55 additions & 31 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,69 @@ var toString = require('nlcst-to-string')

module.exports = mentions

var name = /^(?:[a-z\d]{1,2}|[a-z\d][a-z\d-]{1,37}[a-z\d])([']s)?$/i
var genitive = /[']s?$/i

function mentions() {
return transform
}
var gh = /^@(?:[a-z\d]{1,2}|[a-z\d][a-z\d-]{1,37}[a-z\d])(\/(?:[a-z\d]{1,2}|[a-z\d][a-z\d-]{1,37}[a-z\d]))?$/i
var tw = /^@\w{1,15}$/i

function transform(tree) {
visit(tree, 'SymbolNode', visitor)
}
function mentions(options) {
var style = (options || {}).style || 'github'

function visitor(node, index, parent) {
var siblings = parent.children
var offset = index

if (toString(node) !== '@') {
return
if (style === 'github') {
style = gh
} else if (style === 'twitter') {
style = tw
}

if (!name.test(valueOf(siblings[++offset]))) {
return
}
return transform

if (
valueOf(siblings[offset + 1]) === '/' &&
name.test(valueOf(siblings[offset + 2]))
) {
offset += 2
function transform(tree) {
visit(tree, 'SymbolNode', visitor)
}

siblings.splice(index, offset - index + 1, {
type: 'SourceNode',
value: toString(siblings.slice(index, offset + 1)),
position: {
start: position.start(node),
end: position.end(siblings[offset])
function visitor(node, index, parent) {
var siblings = parent.children
var length = siblings.length
var offset = index
var slice

if (toString(node) !== '@') {
return
}
})
}

function valueOf(node) {
return node ? toString(node) : ''
offset++

while (offset <= length) {
if (offset === length) break
if (siblings[offset].type === 'WhiteSpaceNode') break

if (
toString(siblings[offset]) !== '/' &&
!check(siblings.slice(index, offset + 1))
) {
break
}

offset++
}

slice = siblings.slice(index, offset)

if (!check(slice)) {
return
}

siblings.splice(index, offset - index, {
type: 'SourceNode',
value: toString(slice),
position: {
start: position.start(node),
end: position.end(slice[slice.length - 1])
}
})
}

function check(nodes) {
return style.test(toString(nodes).replace(genitive, ''))
}
}
8 changes: 7 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,19 @@ no issues found

## API

### `retext().use(mentions)`
### `retext().use(mentions[, options])`

Classify [**@mentions**](https://github.com/blog/821) as [**source**][source],
which represent “external (ungrammatical) values” instead of natural language.
This hides mentions from [`retext-spell`][spell],
[`retext-readability`][readability], [`retext-equality`][equality], and more.

###### `options.style`

Style can be either `'github'` (for GitHub user and team mentions), `'twitter'`
(for Twitter handles), or a regular expression (such as `/^@\w{1,15}$/i`, which
is the Twitter regex).

## Related

* [`retext-syntax-urls`][syntax-urls]
Expand Down
58 changes: 58 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,64 @@ test('mentions()', function (t) {
'should work as only item in sentence'
)

t.deepEqual(
retext()
.use(mentions, {style: 'twitter'})
.use(strip)
.runSync(
noPosition.parse(
'@_philippkuehn (my twitter handle) is not recognized.'
)
),
u('RootNode', [
u('ParagraphNode', [
u('SentenceNode', [
u('SourceNode', '@_philippkuehn'),
u('WhiteSpaceNode', ' '),
u('PunctuationNode', '('),
u('WordNode', [u('TextNode', 'my')]),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'twitter')]),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'handle')]),
u('PunctuationNode', ')'),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'is')]),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'not')]),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'recognized')]),
u('PunctuationNode', '.')
])
])
]),
'should support twitter handles'
)

t.deepEqual(
retext()
.use(mentions, {style: /^@[a-z]{1,15}$/i})
.use(strip)
.runSync(noPosition.parse('@lettersOnly, no @123123 digits.')),
u('RootNode', [
u('ParagraphNode', [
u('SentenceNode', [
u('SourceNode', '@lettersOnly'),
u('PunctuationNode', ','),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'no')]),
u('WhiteSpaceNode', ' '),
u('SymbolNode', '@'),
u('WordNode', [u('TextNode', '123123')]),
u('WhiteSpaceNode', ' '),
u('WordNode', [u('TextNode', 'digits')]),
u('PunctuationNode', '.')
])
])
]),
'should support custom handles'
)

t.end()
})

Expand Down

0 comments on commit 641f66f

Please sign in to comment.