aboutsummaryrefslogtreecommitdiff
path: root/lexers/markdown.lua
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-10-16 12:36:47 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-11-08 13:35:36 +0100
commit039042f2e323c1f982f1de61b702c88fb33d6ccb (patch)
tree67dea69de9462e0c27ea2a743b4c5d1798eaa057 /lexers/markdown.lua
parentb1ec60061623601ca6185a16d77c6c6c62135e95 (diff)
downloadvis-039042f2e323c1f982f1de61b702c88fb33d6ccb.tar.gz
vis-039042f2e323c1f982f1de61b702c88fb33d6ccb.tar.xz
Import LPeg based lexers from Scintillua 3.6.1-1
These are Copyright (c) 2007-2015 Mitchell and released under the MIT license.
Diffstat (limited to 'lexers/markdown.lua')
-rw-r--r--lexers/markdown.lua109
1 files changed, 109 insertions, 0 deletions
diff --git a/lexers/markdown.lua b/lexers/markdown.lua
new file mode 100644
index 0000000..9ab1568
--- /dev/null
+++ b/lexers/markdown.lua
@@ -0,0 +1,109 @@
+-- Copyright 2006-2015 Mitchell mitchell.att.foicica.com. See LICENSE.
+-- Markdown LPeg lexer.
+
+local l = require('lexer')
+local token, word_match = l.token, l.word_match
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+
+local M = {_NAME = 'markdown'}
+
+-- Whitespace.
+local ws = token(l.WHITESPACE, l.space^1)
+
+-- Block elements.
+local header = token('h6', l.starts_line('######') * l.nonnewline^0) +
+ token('h5', l.starts_line('#####') * l.nonnewline^0) +
+ token('h4', l.starts_line('####') * l.nonnewline^0) +
+ token('h3', l.starts_line('###') * l.nonnewline^0) +
+ token('h2', l.starts_line('##') * l.nonnewline^0) +
+ token('h1', l.starts_line('#') * l.nonnewline^0)
+
+local blockquote = token(l.STRING,
+ lpeg.Cmt(l.starts_line(S(' \t')^0 * '>'),
+ function(input, index)
+ local _, e = input:find('\n[ \t]*\r?\n',
+ index)
+ return (e or #input) + 1
+ end))
+
+local blockcode = token('code', l.starts_line(P(' ')^4 + P('\t')) * -P('<') *
+ l.nonnewline^0)
+
+local hr = token('hr', lpeg.Cmt(l.starts_line(S(' \t')^0 * lpeg.C(S('*-_'))),
+ function(input, index, c)
+ local line = input:match('[^\n]*', index)
+ line = line:gsub('[ \t]', '')
+ if line:find('[^'..c..']') or #line < 2 then
+ return nil
+ end
+ return (input:find('\n', index) or #input) + 1
+ end))
+
+-- Span elements.
+local dq_str = token(l.STRING, l.delimited_range('"', false, true))
+local sq_str = token(l.STRING, l.delimited_range("'", false, true))
+local paren_str = token(l.STRING, l.delimited_range('()'))
+local link = token('link', P('!')^-1 * l.delimited_range('[]') *
+ (P('(') * (l.any - S(') \t'))^0 *
+ (S(' \t')^1 *
+ l.delimited_range('"', false, true))^-1 * ')' +
+ S(' \t')^0 * l.delimited_range('[]')) +
+ P('http://') * (l.any - l.space)^1)
+local link_label = token('link_label', l.delimited_range('[]') * ':') * ws *
+ token('link_url', (l.any - l.space)^1) *
+ (ws * (dq_str + sq_str + paren_str))^-1
+
+local strong = token('strong', (P('**') * (l.any - '**')^0 * P('**')^-1) +
+ (P('__') * (l.any - '__')^0 * P('__')^-1))
+local em = token('em',
+ l.delimited_range('*', true) + l.delimited_range('_', true))
+local code = token('code', (P('``') * (l.any - '``')^0 * P('``')^-1) +
+ l.delimited_range('`', true, true))
+
+local escape = token(l.DEFAULT, P('\\') * 1)
+
+local list = token('list',
+ l.starts_line(S(' \t')^0 * (S('*+-') + R('09')^1 * '.')) *
+ S(' \t'))
+
+M._rules = {
+ {'header', header},
+ {'blockquote', blockquote},
+ {'blockcode', blockcode},
+ {'hr', hr},
+ {'list', list},
+ {'whitespace', ws},
+ {'link_label', link_label},
+ {'escape', escape},
+ {'link', link},
+ {'strong', strong},
+ {'em', em},
+ {'code', code},
+}
+
+local font_size = 10
+local hstyle = 'fore:$(color.red)'
+M._tokenstyles = {
+ h6 = hstyle,
+ h5 = hstyle..',size:'..(font_size + 1),
+ h4 = hstyle..',size:'..(font_size + 2),
+ h3 = hstyle..',size:'..(font_size + 3),
+ h2 = hstyle..',size:'..(font_size + 4),
+ h1 = hstyle..',size:'..(font_size + 5),
+ code = l.STYLE_EMBEDDED..',eolfilled',
+ hr = 'back:$(color.black),eolfilled',
+ link = 'underlined',
+ link_url = 'underlined',
+ link_label = l.STYLE_LABEL,
+ strong = 'bold',
+ em = 'italics',
+ list = l.STYLE_CONSTANT,
+}
+
+-- Embedded HTML.
+local html = l.load('html')
+local start_rule = token('tag', l.starts_line(S(' \t')^0 * '<'))
+local end_rule = token(l.DEFAULT, P('\n')) -- TODO: l.WHITESPACE causes errors
+l.embed_lexer(M, html, start_rule, end_rule)
+
+return M