Skip to content

Instantly share code, notes, and snippets.

@hanxi
Created December 16, 2014 08:14
Show Gist options
  • Save hanxi/e5a9b3545b3b16617c0a to your computer and use it in GitHub Desktop.
Save hanxi/e5a9b3545b3b16617c0a to your computer and use it in GitHub Desktop.
使用LPeg将markdown转成html
local lpeg = require 'lpeg'
local P,S,C,Cs,Cg = lpeg.P,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cg
local test = [[
A title
---
BTitle
--
CTitle
===
## A title
here _we go_ and `a:bonzo()`:
<
one line
two line
three line
<and `more_or_less_something`
[A reference](http://bonzo.dog)
> quoted
> lines
]]
function subst(openp,repl,endp)
openp = P(openp) -- make sure it's a pattern
endp = endp and P(endp) or openp
-- pattern is 'bracket followed by any number of non-bracket followed by bracket'
local contents = C((1 - endp)^1)
local patt = openp * contents * endp
if repl then patt = patt/repl end
return patt
end
function empty(p)
return C(p)/''
end
local lf = P'\n'
local rest_of_line = C((1 - lf)^1)
local rest_of_line_nl = C((1 - lf)^0*lf)
-- indented code block
local indent = P'\t' + P' '
local indented = empty(indent)*rest_of_line_nl
-- which we'll assume are Lua code
local block = Cs(indented^1)/'<pre>%1</pre>\n'
-- use > to get simple quoted block
-- quoted_line = empty('> ')*rest_of_line_nl
local quoted_line = subst('> ','<p>%1</p>\n','\n')
local quote = Cs (quoted_line^1)/"<blockquote>\n%1</blockquote>"
local code = subst('`','<code>%1</code>')
local italic = subst('*',"<em>%1</em>") + subst('_',"<em>%1</em>")
local bold = subst('**',"<strong>%1</strong>") + subst('__',"<strong>%1</strong>")
local special = C('<')/'&lt;' + C('&')/'&amp;'
local title1 = P'#' * rest_of_line/'<h1>%1</h1>' + C((1 - lf)^0)*lf*P'='^1/'<h1>%1</h1>'
local title2 = P'##' * rest_of_line/'<h2>%1</h2>' + C((1 - lf)^0)*lf*P'-'^1/'<h2>%1</h2>'
local title3 = P'###' * rest_of_line/'<h3>%1</h3>'
local title4 = P'####' * rest_of_line/'<h4>%1</h4>'
local title5 = P'#####' * rest_of_line/'<h5>%1</h5>'
local title6 = P'######' * rest_of_line/'<h6>%1</h6>'
local url = (subst('[',nil,']')*subst('(',nil,')'))/'<a href="%2">%1</a>'
local item = block + title6 + title5 + title4 + title3 + title2 + title1 + code + italic + bold + quote + url + special + 1
local text = Cs(item^1)
if arg[1] then
local f = io.open(arg[1])
test = f:read '*a'
f:close()
end
print("<pre>"..test.."</pre><hr>")
print(text:match(test))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment