mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

176 lines
5.5 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This file is a part of Julia. License is MIT: https://julialang.org/license
#
# Emphasis
#
mutable struct Italic
text
end
@trigger '*' ->
function asterisk_italic(stream::IO, md::MD)
result = parse_inline_wrapper(stream, "*")
return result === nothing ? nothing : Italic(parseinline(result, md))
end
mutable struct Bold
text
end
@trigger '*' ->
function asterisk_bold(stream::IO, md::MD)
result = parse_inline_wrapper(stream, "**")
return result === nothing ? nothing : Bold(parseinline(result, md))
end
#
# Code
#
@trigger '`' ->
function inline_code(stream::IO, md::MD)
withstream(stream) do
ticks = startswith(stream, r"^(`+)")
result = readuntil(stream, ticks)
if result === nothing
nothing
else
result = strip(result)
# An odd number of backticks wrapping the text will produce a `Code` node, while
# an even number will result in a `LaTeX` node. This allows for arbitary
# backtick combinations to be embedded inside the resulting node, i.e.
#
# `a`, ``a``, `` `a` ``, ``` ``a`` ```, ``` `a` ```, etc.
# ^ ^ ^ ^ ^
# C L L C C with C=Code and L=LaTeX.
#
isodd(length(ticks)) ? Code(result) : LaTeX(result)
end
end
end
#
# Images & Links
#
mutable struct Image
url::String
alt::String
end
@trigger '!' ->
function image(stream::IO, md::MD)
withstream(stream) do
startswith(stream, "![") || return
alt = readuntil(stream, ']', match = '[')
alt nothing && return
skipwhitespace(stream)
startswith(stream, '(') || return
url = readuntil(stream, ')', match = '(')
url nothing && return
return Image(url, alt)
end
end
mutable struct Link
text
url::String
end
@trigger '[' ->
function link(stream::IO, md::MD)
withstream(stream) do
startswith(stream, '[') || return
text = readuntil(stream, ']', match = '[')
text nothing && return
skipwhitespace(stream)
startswith(stream, '(') || return
url = readuntil(stream, ')', match = '(')
url nothing && return
return Link(parseinline(text, md), url)
end
end
@trigger '[' ->
function footnote_link(stream::IO, md::MD)
withstream(stream) do
regex = r"^\[\^(\w+)\]"
str = startswith(stream, regex)
if isempty(str)
return
else
ref = match(regex, str).captures[1]
return Footnote(ref, nothing)
end
end
end
@trigger '<' ->
function autolink(stream::IO, md::MD)
withstream(stream) do
startswith(stream, '<') || return
url = readuntil(stream, '>')
url nothing && return
_is_link(url) && return Link(url, url)
_is_mailto(url) && return Link(url, url)
return
end
end
# This list is taken from the commonmark spec
# http://spec.commonmark.org/0.19/#absolute-uri
const _allowable_schemes = Set(split("coap doi javascript aaa aaas about acap cap cid crid data dav dict dns file ftp geo go gopher h323 http https iax icap im imap info ipp iris iris.beep iris.xpc iris.xpcs iris.lwz ldap mailto mid msrp msrps mtqp mupdate news nfs ni nih nntp opaquelocktoken pop pres rtsp service session shttp sieve sip sips sms snmp,soap.beep soap.beeps tag tel telnet tftp thismessage tn3270 tip tv urn vemmi ws wss xcon xcon-userid xmlrpc.beep xmlrpc.beeps xmpp z39.50r z39.50s
adiumxtra afp afs aim apt,attachment aw beshare bitcoin bolo callto chrome,chrome-extension com-eventbrite-attendee content cvs,dlna-playsingle dlna-playcontainer dtn dvb ed2k facetime feed finger fish gg git gizmoproject gtalk hcp icon ipn irc irc6 ircs itms jar jms keyparc lastfm ldaps magnet maps market,message mms ms-help msnim mumble mvn notes oid palm paparazzi platform proxy psyc query res resource rmi rsync rtmp secondlife sftp sgn skype smb soldat spotify ssh steam svn teamspeak
things udp unreal ut2004 ventrilo view-source webcal wtai wyciwyg xfire xri ymsgr"))
function _is_link(s::AbstractString)
'<' in s && return false
m = match(r"^(.*)://(\S+?)(:\S*)?$", s)
m nothing && return false
scheme = lowercase(m.captures[1])
return scheme in _allowable_schemes
end
# non-normative regex from the HTML5 spec
const _email_regex = r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
function _is_mailto(s::AbstractString)
length(s) < 6 && return false
# slicing strings is a bit risky, but this equality check is safe
lowercase(s[1:6]) == "mailto:" || return false
return ismatch(_email_regex, s[6:end])
end
#
# Punctuation
#
mutable struct LineBreak end
@trigger '\\' ->
function linebreak(stream::IO, md::MD)
if startswith(stream, "\\\n")
return LineBreak()
end
end
@trigger '-' ->
function en_dash(stream::IO, md::MD)
if startswith(stream, "--")
return ""
end
end
const escape_chars = "\\`*_#+-.!{}[]()\$"
@trigger '\\' ->
function escapes(stream::IO, md::MD)
withstream(stream) do
if startswith(stream, "\\") && !eof(stream) && (c = read(stream, Char)) in escape_chars
return string(c)
end
end
end