'use strict' var asciiAlpha = require('../character/ascii-alpha.js') var asciiAlphanumeric = require('../character/ascii-alphanumeric.js') var asciiAtext = require('../character/ascii-atext.js') var asciiControl = require('../character/ascii-control.js') var autolink = { name: 'autolink', tokenize: tokenizeAutolink } function tokenizeAutolink(effects, ok, nok) { var size = 1 return start function start(code) { effects.enter('autolink') effects.enter('autolinkMarker') effects.consume(code) effects.exit('autolinkMarker') effects.enter('autolinkProtocol') return open } function open(code) { if (asciiAlpha(code)) { effects.consume(code) return schemeOrEmailAtext } return asciiAtext(code) ? emailAtext(code) : nok(code) } function schemeOrEmailAtext(code) { return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code) ? schemeInsideOrEmailAtext(code) : emailAtext(code) } function schemeInsideOrEmailAtext(code) { if (code === 58) { effects.consume(code) return urlInside } if ( (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && size++ < 32 ) { effects.consume(code) return schemeInsideOrEmailAtext } return emailAtext(code) } function urlInside(code) { if (code === 62) { effects.exit('autolinkProtocol') return end(code) } if (code === 32 || code === 60 || asciiControl(code)) { return nok(code) } effects.consume(code) return urlInside } function emailAtext(code) { if (code === 64) { effects.consume(code) size = 0 return emailAtSignOrDot } if (asciiAtext(code)) { effects.consume(code) return emailAtext } return nok(code) } function emailAtSignOrDot(code) { return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) } function emailLabel(code) { if (code === 46) { effects.consume(code) size = 0 return emailAtSignOrDot } if (code === 62) { // Exit, then change the type. effects.exit('autolinkProtocol').type = 'autolinkEmail' return end(code) } return emailValue(code) } function emailValue(code) { if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { effects.consume(code) return code === 45 ? emailValue : emailLabel } return nok(code) } function end(code) { effects.enter('autolinkMarker') effects.consume(code) effects.exit('autolinkMarker') effects.exit('autolink') return ok } } module.exports = autolink