mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
add markdown viewer
This commit is contained in:
parent
fc5c815824
commit
1c49b71606
|
@ -34,8 +34,10 @@ turn your phone or raspi into a portable file server with resumable uploads/down
|
||||||
* [ ] download as zip
|
* [ ] download as zip
|
||||||
* [x] volumes
|
* [x] volumes
|
||||||
* [x] accounts
|
* [x] accounts
|
||||||
|
* [x] markdown viewer
|
||||||
|
* [ ] markdown editor? w
|
||||||
|
|
||||||
summary: close to beta
|
summary: it works! you can use it! (but technically not even close to beta)
|
||||||
|
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
|
@ -82,6 +84,7 @@ in the `scripts` folder:
|
||||||
|
|
||||||
roughly sorted by priority
|
roughly sorted by priority
|
||||||
|
|
||||||
|
* sortable browser columns
|
||||||
* up2k handle filename too long
|
* up2k handle filename too long
|
||||||
* up2k fails on empty files? alert then stuck
|
* up2k fails on empty files? alert then stuck
|
||||||
* unexpected filepath on dupe up2k
|
* unexpected filepath on dupe up2k
|
||||||
|
|
|
@ -706,6 +706,48 @@ class HttpCli(object):
|
||||||
self.log(logmsg)
|
self.log(logmsg)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def tx_md(self, fs_path):
|
||||||
|
logmsg = "{:4} {} ".format("", self.req)
|
||||||
|
html_path = os.path.join(E.mod, "web/md.html")
|
||||||
|
|
||||||
|
st = os.stat(fsenc(fs_path))
|
||||||
|
sz_md = st.st_size
|
||||||
|
ts_md = st.st_mtime
|
||||||
|
|
||||||
|
st = os.stat(fsenc(html_path))
|
||||||
|
ts_html = st.st_mtime
|
||||||
|
|
||||||
|
file_ts = max(ts_md, ts_html)
|
||||||
|
file_lastmod, do_send = self._chk_lastmod(file_ts)
|
||||||
|
self.out_headers["Last-Modified"] = file_lastmod
|
||||||
|
status = 200 if do_send else 304
|
||||||
|
|
||||||
|
targs = {
|
||||||
|
"title": html_escape(self.vpath, quote=False),
|
||||||
|
"md": "",
|
||||||
|
}
|
||||||
|
sz_html = len(self.conn.tpl_md.render(**targs).encode("utf-8"))
|
||||||
|
self.send_headers(sz_html + sz_md, status)
|
||||||
|
|
||||||
|
logmsg += str(status)
|
||||||
|
if self.mode == "HEAD" or not do_send:
|
||||||
|
self.log(logmsg)
|
||||||
|
return True
|
||||||
|
|
||||||
|
with open(fsenc(fs_path), "rb") as f:
|
||||||
|
md = f.read()
|
||||||
|
|
||||||
|
targs["md"] = md.decode("utf-8", "replace")
|
||||||
|
html = self.conn.tpl_md.render(**targs).encode("utf-8")
|
||||||
|
try:
|
||||||
|
self.s.sendall(html)
|
||||||
|
except:
|
||||||
|
self.log(logmsg + " \033[31md/c\033[0m")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.log(logmsg + " " + str(len(html)))
|
||||||
|
return True
|
||||||
|
|
||||||
def tx_mounts(self):
|
def tx_mounts(self):
|
||||||
rvol = [x + "/" if x else x for x in self.rvol]
|
rvol = [x + "/" if x else x for x in self.rvol]
|
||||||
wvol = [x + "/" if x else x for x in self.wvol]
|
wvol = [x + "/" if x else x for x in self.wvol]
|
||||||
|
@ -735,6 +777,9 @@ class HttpCli(object):
|
||||||
raise Pebkac(404)
|
raise Pebkac(404)
|
||||||
|
|
||||||
if not os.path.isdir(fsenc(abspath)):
|
if not os.path.isdir(fsenc(abspath)):
|
||||||
|
if abspath.endswith(".md") and "raw" not in self.uparam:
|
||||||
|
return self.tx_md(abspath)
|
||||||
|
|
||||||
return self.tx_file(abspath)
|
return self.tx_file(abspath)
|
||||||
|
|
||||||
fsroot, vfs_ls, vfs_virt = vn.ls(rem, self.uname)
|
fsroot, vfs_ls, vfs_virt = vn.ls(rem, self.uname)
|
||||||
|
|
|
@ -35,6 +35,7 @@ class HttpConn(object):
|
||||||
self.tpl_mounts = env.get_template("splash.html")
|
self.tpl_mounts = env.get_template("splash.html")
|
||||||
self.tpl_browser = env.get_template("browser.html")
|
self.tpl_browser = env.get_template("browser.html")
|
||||||
self.tpl_msg = env.get_template("msg.html")
|
self.tpl_msg = env.get_template("msg.html")
|
||||||
|
self.tpl_md = env.get_template("md.html")
|
||||||
|
|
||||||
def respath(self, res_name):
|
def respath(self, res_name):
|
||||||
return os.path.join(E.mod, "web", res_name)
|
return os.path.join(E.mod, "web", res_name)
|
||||||
|
|
375
copyparty/web/md.css
Normal file
375
copyparty/web/md.css
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
html, body {
|
||||||
|
color: #333;
|
||||||
|
background: #eee;
|
||||||
|
font-family: sans-serif;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
#mw {
|
||||||
|
width: 48.5em;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 6em;
|
||||||
|
}
|
||||||
|
pre, code, a {
|
||||||
|
color: #480;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border: .07em solid #ddd;
|
||||||
|
border-radius: .2em;
|
||||||
|
padding: .1em .3em;
|
||||||
|
margin: 0 .1em;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
font-size: .96em;
|
||||||
|
}
|
||||||
|
pre, code {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
counter-reset: precode;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
counter-increment: precode;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 -.3em;
|
||||||
|
padding: .4em .5em;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #cdc;
|
||||||
|
min-width: calc(100% - .6em);
|
||||||
|
line-height: 1.1em;
|
||||||
|
}
|
||||||
|
pre code:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
pre code:before {
|
||||||
|
content: counter(precode);
|
||||||
|
-webkit-user-select: none;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: right;
|
||||||
|
font-size: .75em;
|
||||||
|
color: #48a;
|
||||||
|
width: 4em;
|
||||||
|
padding-right: 1.5em;
|
||||||
|
margin-left: -5.5em;
|
||||||
|
}
|
||||||
|
pre code:hover {
|
||||||
|
background: #fec;
|
||||||
|
color: #360;
|
||||||
|
}
|
||||||
|
h1, h2 {
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 1.7em;
|
||||||
|
text-align: center;
|
||||||
|
border: 1em solid #777;
|
||||||
|
border-width: .05em 0;
|
||||||
|
margin: 3em 0;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: normal;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border-top: .07em solid #fff;
|
||||||
|
border-bottom: .07em solid #bbb;
|
||||||
|
border-radius: .5em .5em 0 0;
|
||||||
|
padding-left: .4em;
|
||||||
|
margin-top: 3em;
|
||||||
|
}
|
||||||
|
h1 a, h3 a, h5 a,
|
||||||
|
h2 a, h4 a, h6 a {
|
||||||
|
color: inherit;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#m ul,
|
||||||
|
#m ol {
|
||||||
|
border-left: .3em solid #ddd;
|
||||||
|
}
|
||||||
|
#m>ul,
|
||||||
|
#m>ol {
|
||||||
|
border-color: #bbb;
|
||||||
|
}
|
||||||
|
#m ul>li {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
#m ul>li,
|
||||||
|
#m ol>li {
|
||||||
|
margin: .7em 0;
|
||||||
|
}
|
||||||
|
p>em,
|
||||||
|
li>em {
|
||||||
|
color: #c50;
|
||||||
|
padding: .1em;
|
||||||
|
border-bottom: .1em solid #bbb;
|
||||||
|
}
|
||||||
|
blockquote {
|
||||||
|
font-family: serif;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border: .07em dashed #ccc;
|
||||||
|
padding: 0 2em;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
small {
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
#toc {
|
||||||
|
width: 48.5em;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
#toc ul {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
#toc>ul {
|
||||||
|
text-align: left;
|
||||||
|
padding-left: .5em;
|
||||||
|
}
|
||||||
|
#toc li {
|
||||||
|
list-style-type: none;
|
||||||
|
line-height: 1.2em;
|
||||||
|
margin: .5em 0;
|
||||||
|
}
|
||||||
|
#toc a {
|
||||||
|
color: #057;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
display: block;
|
||||||
|
margin-left: -.3em;
|
||||||
|
padding: .2em .3em;
|
||||||
|
}
|
||||||
|
#toc a.act {
|
||||||
|
color: #fff;
|
||||||
|
background: #07a;
|
||||||
|
}
|
||||||
|
.todo_pend,
|
||||||
|
.todo_done {
|
||||||
|
z-index: 99;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.3em;
|
||||||
|
line-height: .1em;
|
||||||
|
margin: -.5em 0 -.5em -.85em;
|
||||||
|
top: .1em;
|
||||||
|
color: #b29;
|
||||||
|
}
|
||||||
|
.todo_done {
|
||||||
|
color: #6b3;
|
||||||
|
text-shadow: .02em 0 0 #6b3;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
padding: .2em .5em;
|
||||||
|
border: .12em solid #aaa;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
border: .12em solid #aaa;
|
||||||
|
}
|
||||||
|
blink {
|
||||||
|
animation: blinker .7s cubic-bezier(.9, 0, .1, 1) infinite;
|
||||||
|
}
|
||||||
|
@keyframes blinker {
|
||||||
|
10% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen {
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
background: #39b;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0 .3em;
|
||||||
|
border: none;
|
||||||
|
border-bottom: .07em solid #079;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #fff;
|
||||||
|
background: #555;
|
||||||
|
margin-top: 2em;
|
||||||
|
border-bottom: .22em solid #999;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #fff;
|
||||||
|
background: #444;
|
||||||
|
font-weight: normal;
|
||||||
|
border-top: .4em solid #fb0;
|
||||||
|
border-bottom: .4em solid #777;
|
||||||
|
border-radius: 0 1em 0 1em;
|
||||||
|
margin: 3em 0 1em 0;
|
||||||
|
padding: .5em 0;
|
||||||
|
}
|
||||||
|
#mn {
|
||||||
|
text-shadow: 1px 1px 0 #000;
|
||||||
|
xfont-variant: small-caps;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 1.3em 0 0 0;
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
#mn a {
|
||||||
|
background: #2c2c2c;
|
||||||
|
margin: 0 0 0 -.2em;
|
||||||
|
padding: 0 0 0 .4em;
|
||||||
|
/* ie: */
|
||||||
|
border-bottom: .1em solid #777\9;
|
||||||
|
margin-right: 1em\9;
|
||||||
|
}
|
||||||
|
#mn a:first-child {
|
||||||
|
padding-left: .5em;
|
||||||
|
}
|
||||||
|
#mn a:last-child {
|
||||||
|
padding-right: .5em;
|
||||||
|
}
|
||||||
|
#mn a:not(:last-child):after {
|
||||||
|
content: '';
|
||||||
|
width: 1.05em;
|
||||||
|
height: 1.05em;
|
||||||
|
margin: -.2em .3em -.2em -.4em;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid rgba(255,224,192,0.3);
|
||||||
|
border-width: .05em .05em 0 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
background: linear-gradient(45deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.25) 75%, rgba(0,0,0,0.35));
|
||||||
|
}
|
||||||
|
#mn a:hover {
|
||||||
|
color: #fff;
|
||||||
|
background: linear-gradient(90deg, rgba(0,0,0,0), rgba(0,0,0,0.2), rgba(0,0,0,0));
|
||||||
|
}
|
||||||
|
#mh {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
html.dark,
|
||||||
|
html.dark body {
|
||||||
|
background: #222;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
html.dark #toc a {
|
||||||
|
color: #ccc;
|
||||||
|
border-left: .4em solid #444;
|
||||||
|
border-bottom: .1em solid #333;
|
||||||
|
}
|
||||||
|
html.dark #toc a.act {
|
||||||
|
color: #fff;
|
||||||
|
border-left: .4em solid #3ad;
|
||||||
|
}
|
||||||
|
html.dark #toc li {
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
html.dark #m a,
|
||||||
|
html.dark #mh a {
|
||||||
|
background: #057;
|
||||||
|
}
|
||||||
|
html.dark #m h1 a, html.dark #m h4 a,
|
||||||
|
html.dark #m h2 a, html.dark #m h5 a,
|
||||||
|
html.dark #m h3 a, html.dark #m h6 a {
|
||||||
|
color: inherit;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
html.dark pre,
|
||||||
|
html.dark code {
|
||||||
|
color: #8c0;
|
||||||
|
background: #1a1a1a;
|
||||||
|
border: .07em solid #333;
|
||||||
|
}
|
||||||
|
html.dark #m ul,
|
||||||
|
html.dark #m ol {
|
||||||
|
border-color: #444;
|
||||||
|
}
|
||||||
|
html.dark #m>ul,
|
||||||
|
html.dark #m>ol {
|
||||||
|
border-color: #555;
|
||||||
|
}
|
||||||
|
html.dark p>em,
|
||||||
|
html.dark li>em {
|
||||||
|
color: #f94;
|
||||||
|
border-color: #666;
|
||||||
|
}
|
||||||
|
html.dark h1 {
|
||||||
|
background: #383838;
|
||||||
|
border-top: .4em solid #b80;
|
||||||
|
border-bottom: .4em solid #4c4c4c;
|
||||||
|
}
|
||||||
|
html.dark h2 {
|
||||||
|
background: #444;
|
||||||
|
border-bottom: .22em solid #555;
|
||||||
|
}
|
||||||
|
html.dark td,
|
||||||
|
html.dark th {
|
||||||
|
border-color: #444;
|
||||||
|
}
|
||||||
|
html.dark blockquote {
|
||||||
|
background: #282828;
|
||||||
|
border: .07em dashed #444;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 64em) {
|
||||||
|
#mw {
|
||||||
|
margin-left: 14em;
|
||||||
|
margin-left: calc(100% - 50em);
|
||||||
|
}
|
||||||
|
#toc {
|
||||||
|
width: 13em;
|
||||||
|
width: calc(100% - 52.3em);
|
||||||
|
background: #eee;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: 0 0 1em #ccc;
|
||||||
|
scrollbar-color: #eb0 #f7f7f7;
|
||||||
|
xscrollbar-width: thin;
|
||||||
|
}
|
||||||
|
#toc li {
|
||||||
|
border-left: .3em solid #ccc;
|
||||||
|
}
|
||||||
|
#toc::-webkit-scrollbar-track {
|
||||||
|
background: #f7f7f7;
|
||||||
|
}
|
||||||
|
#toc::-webkit-scrollbar {
|
||||||
|
background: #f7f7f7;
|
||||||
|
width: .8em;
|
||||||
|
}
|
||||||
|
#toc::-webkit-scrollbar-thumb {
|
||||||
|
background: #eb0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
html.dark #toc {
|
||||||
|
background: #282828;
|
||||||
|
box-shadow: 0 0 1em #181818;
|
||||||
|
scrollbar-color: #b80 #282828;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 84em) {
|
||||||
|
#toc { width: 30em }
|
||||||
|
#mw { margin-left: 32em }
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
a {
|
||||||
|
color: #079;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: .07em solid #4ac;
|
||||||
|
padding: 0 .3em;
|
||||||
|
}
|
||||||
|
#toc>ul {
|
||||||
|
border-left: .1em solid #84c4dd;
|
||||||
|
}
|
||||||
|
#mn, #mh {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
47
copyparty/web/md.html
Normal file
47
copyparty/web/md.html
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<!DOCTYPE html><html><head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>📝🎉 {{ title }}</title> <!-- 📜 -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.7">
|
||||||
|
<link href="/.cpr/md.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="toc"></div>
|
||||||
|
<div id="mw">
|
||||||
|
<div id="mn"></div>
|
||||||
|
<div id="mh">
|
||||||
|
<a id="lightswitch" href="#">dark</a>
|
||||||
|
there will soon be more buttons on this row so it looks less dumb
|
||||||
|
</div>
|
||||||
|
<div id="ml">
|
||||||
|
<div style="text-align:center;margin:5em 0">
|
||||||
|
<div style="font-size:2em;margin:1em 0">Loading</div>
|
||||||
|
if you're still reading this, check that javascript is allowed
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="m">
|
||||||
|
<textarea id="mt" style="display:none">{{ md }}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var link_md_as_html = false; // TODO (does nothing)
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var btn = document.getElementById("lightswitch");
|
||||||
|
var toggle = function () {
|
||||||
|
var dark = !document.documentElement.getAttribute("class");
|
||||||
|
document.documentElement.setAttribute("class", dark ? "dark" : "");
|
||||||
|
btn.innerHTML = dark ? "light" : "dark";
|
||||||
|
if (window.localStorage)
|
||||||
|
localStorage.setItem('md-dark', dark ? 1 : 0);
|
||||||
|
};
|
||||||
|
btn.onclick = toggle;
|
||||||
|
if (window.localStorage && localStorage.getItem('md-dark') == 1)
|
||||||
|
toggle();
|
||||||
|
})();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script src="/.cpr/deps/marked.full.js"></script>
|
||||||
|
<script src="/.cpr/md.js"></script>
|
||||||
|
</body></html>
|
232
copyparty/web/md.js
Normal file
232
copyparty/web/md.js
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
/*var conv = new showdown.Converter();
|
||||||
|
conv.setFlavor('github');
|
||||||
|
conv.setOption('tasklists', 0);
|
||||||
|
var mhtml = conv.makeHtml(dom_md.value);
|
||||||
|
*/
|
||||||
|
|
||||||
|
var dom_toc = document.getElementById('toc');
|
||||||
|
var dom_wrap = document.getElementById('mw');
|
||||||
|
var dom_head = document.getElementById('mh');
|
||||||
|
var dom_nav = document.getElementById('mn');
|
||||||
|
var dom_doc = document.getElementById('m');
|
||||||
|
var dom_md = document.getElementById('mt');
|
||||||
|
|
||||||
|
// add toolbar buttons
|
||||||
|
(function () {
|
||||||
|
var n = document.location + '';
|
||||||
|
n = n.substr(n.indexOf('//') + 2).split('/');
|
||||||
|
n[0] = 'top';
|
||||||
|
var nav = [];
|
||||||
|
var url = '/';
|
||||||
|
for (var a = 0; a < n.length; a++) {
|
||||||
|
if (a > 0)
|
||||||
|
url += n[a] + '/';
|
||||||
|
|
||||||
|
nav.push('<a href="' + url + '">' + n[a] + '</a>');
|
||||||
|
}
|
||||||
|
dom_nav.innerHTML = nav.join('');
|
||||||
|
})();
|
||||||
|
|
||||||
|
function convert_markdown(md_text) {
|
||||||
|
marked.setOptions({
|
||||||
|
//headerPrefix: 'h-',
|
||||||
|
breaks: true,
|
||||||
|
gfm: true
|
||||||
|
});
|
||||||
|
var html = marked(md_text);
|
||||||
|
dom_doc.innerHTML = html;
|
||||||
|
|
||||||
|
var loader = document.getElementById('ml');
|
||||||
|
loader.parentNode.removeChild(loader);
|
||||||
|
|
||||||
|
// todo-lists (should probably be a marked extension)
|
||||||
|
var nodes = dom_doc.getElementsByTagName('input');
|
||||||
|
for (var a = nodes.length - 1; a >= 0; a--) {
|
||||||
|
var dom_box = nodes[a];
|
||||||
|
if (dom_box.getAttribute('type') !== 'checkbox')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var dom_li = dom_box.parentNode;
|
||||||
|
var done = dom_box.getAttribute('checked');
|
||||||
|
done = done !== null;
|
||||||
|
var clas = done ? 'done' : 'pend';
|
||||||
|
var char = done ? 'Y' : 'N';
|
||||||
|
|
||||||
|
dom_li.setAttribute('class', 'task-list-item');
|
||||||
|
dom_li.style.listStyleType = 'none';
|
||||||
|
var html = dom_li.innerHTML;
|
||||||
|
dom_li.innerHTML =
|
||||||
|
'<span class="todo_' + clas + '">' + char + '</span>' +
|
||||||
|
html.substr(html.indexOf('>') + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init_toc() {
|
||||||
|
var anchors = []; // list of toc entries, complex objects
|
||||||
|
var anchor = null; // current toc node
|
||||||
|
var id_seen = {}; // taken IDs
|
||||||
|
var html = []; // generated toc html
|
||||||
|
var lv = 0; // current indentation level in the toc html
|
||||||
|
var re = new RegExp('^[Hh]([1-3])');
|
||||||
|
|
||||||
|
var manip_nodes_dyn = dom_doc.getElementsByTagName('*');
|
||||||
|
var manip_nodes = [];
|
||||||
|
for (var a = 0, aa = manip_nodes_dyn.length; a < aa; a++)
|
||||||
|
manip_nodes.push(manip_nodes_dyn[a]);
|
||||||
|
|
||||||
|
for (var a = 0, aa = manip_nodes.length; a < aa; a++) {
|
||||||
|
var elm = manip_nodes[a];
|
||||||
|
var m = re.exec(elm.tagName);
|
||||||
|
|
||||||
|
var is_header =
|
||||||
|
m !== null;
|
||||||
|
|
||||||
|
var is_precode =
|
||||||
|
!is_header &&
|
||||||
|
elm.tagName == 'PRE' &&
|
||||||
|
elm.childNodes.length === 1 &&
|
||||||
|
elm.childNodes[0].tagName == 'CODE';
|
||||||
|
|
||||||
|
if (is_header) {
|
||||||
|
var nlv = m[1];
|
||||||
|
while (lv < nlv) {
|
||||||
|
html.push('<ul>');
|
||||||
|
lv++;
|
||||||
|
}
|
||||||
|
while (lv > nlv) {
|
||||||
|
html.push('</ul>');
|
||||||
|
lv--;
|
||||||
|
}
|
||||||
|
|
||||||
|
var orig_id = elm.getAttribute('id');
|
||||||
|
var id = orig_id;
|
||||||
|
if (id_seen[id]) {
|
||||||
|
for (var n = 1; n < 4096; n++) {
|
||||||
|
id = orig_id + '-' + n;
|
||||||
|
if (!id_seen[id])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elm.setAttribute('id', id);
|
||||||
|
}
|
||||||
|
id_seen[id] = 1;
|
||||||
|
|
||||||
|
var ahref = '<a href="#' + id + '">' +
|
||||||
|
elm.innerHTML + '</a>';
|
||||||
|
|
||||||
|
html.push('<li>' + ahref + '</li>');
|
||||||
|
elm.innerHTML = ahref;
|
||||||
|
|
||||||
|
if (anchor != null)
|
||||||
|
anchors.push(anchor);
|
||||||
|
|
||||||
|
anchor = {
|
||||||
|
elm: elm,
|
||||||
|
kids: [],
|
||||||
|
y: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (is_precode) {
|
||||||
|
elm.innerHTML = elm.innerHTML.replace(
|
||||||
|
/\r?\n<\/code>$/i, '</code>').split(/\r?\n/g).join('</code>\n<code>');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_header && anchor)
|
||||||
|
anchor.kids.push(elm);
|
||||||
|
}
|
||||||
|
dom_toc.innerHTML = html.join('\n');
|
||||||
|
if (anchor != null)
|
||||||
|
anchors.push(anchor);
|
||||||
|
|
||||||
|
// copy toc links into the toc list
|
||||||
|
var atoc = dom_toc.getElementsByTagName('a');
|
||||||
|
for (var a = 0, aa = anchors.length; a < aa; a++)
|
||||||
|
anchors[a].lnk = atoc[a];
|
||||||
|
|
||||||
|
// collect vertical position of all toc items (headers in document)
|
||||||
|
function freshen_offsets() {
|
||||||
|
var top = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
for (var a = anchors.length - 1; a >= 0; a--) {
|
||||||
|
var y = top + anchors[a].elm.getBoundingClientRect().top;
|
||||||
|
y = Math.round(y * 10.0) / 10;
|
||||||
|
if (anchors[a].y === y)
|
||||||
|
break;
|
||||||
|
|
||||||
|
anchors[a].y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hilight the correct toc items + scroll into view
|
||||||
|
function freshen_toclist() {
|
||||||
|
if (anchors.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ptop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
var hit = -1;
|
||||||
|
for (var a = 0; a < anchors.length; a++) {
|
||||||
|
if (anchors[a].y >= ptop - 8) { //???
|
||||||
|
hit = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var links = dom_toc.getElementsByTagName('a');
|
||||||
|
if (!anchors[hit].active) {
|
||||||
|
for (var a = 0; a < anchors.length; a++) {
|
||||||
|
if (anchors[a].active) {
|
||||||
|
anchors[a].active = false;
|
||||||
|
links[a].setAttribute('class', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anchors[hit].active = true;
|
||||||
|
links[hit].setAttribute('class', 'act');
|
||||||
|
}
|
||||||
|
|
||||||
|
var pane_height = parseInt(getComputedStyle(dom_toc).height);
|
||||||
|
var link_bounds = links[hit].getBoundingClientRect();
|
||||||
|
var top = link_bounds.top - (pane_height / 6);
|
||||||
|
var btm = link_bounds.bottom + (pane_height / 6);
|
||||||
|
if (top < 0)
|
||||||
|
dom_toc.scrollTop -= -top;
|
||||||
|
else if (btm > pane_height)
|
||||||
|
dom_toc.scrollTop += btm - pane_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
freshen_offsets();
|
||||||
|
freshen_toclist();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { "refresh": refresh }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// "main" :p
|
||||||
|
convert_markdown(dom_md.value);
|
||||||
|
var toc = init_toc();
|
||||||
|
|
||||||
|
|
||||||
|
// scroll handler
|
||||||
|
(function () {
|
||||||
|
var timer_active = false;
|
||||||
|
var final = null;
|
||||||
|
|
||||||
|
function onscroll() {
|
||||||
|
clearTimeout(final);
|
||||||
|
timer_active = false;
|
||||||
|
toc.refresh();
|
||||||
|
}
|
||||||
|
onscroll();
|
||||||
|
|
||||||
|
window.onscroll = function () {
|
||||||
|
// long timeout: scroll ended
|
||||||
|
clearTimeout(final);
|
||||||
|
final = setTimeout(onscroll, 100);
|
||||||
|
|
||||||
|
// short timeout: continuous updates
|
||||||
|
if (timer_active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timer_active = true;
|
||||||
|
setTimeout(onscroll, 10);
|
||||||
|
};
|
||||||
|
})();
|
|
@ -1,25 +1,50 @@
|
||||||
FROM alpine:3.11
|
FROM alpine:3.11
|
||||||
WORKDIR /z
|
WORKDIR /z
|
||||||
ENV ver_asmcrypto=2821dd1dedd1196c378f5854037dda5c869313f3 \
|
ENV ver_asmcrypto=2821dd1dedd1196c378f5854037dda5c869313f3 \
|
||||||
|
ver_markdownit=10.0.0 \
|
||||||
|
ver_showdown=1.9.1 \
|
||||||
|
ver_marked=1.0.0 \
|
||||||
ver_ogvjs=1.6.1
|
ver_ogvjs=1.6.1
|
||||||
|
|
||||||
|
|
||||||
# download
|
# download
|
||||||
RUN apk add make g++ git bash npm patch wget tar pigz brotli gzip unzip \
|
RUN apk add make g++ git bash npm patch wget tar pigz brotli gzip unzip \
|
||||||
&& wget https://github.com/brion/ogv.js/releases/download/$ver_ogvjs/ogvjs-$ver_ogvjs.zip \
|
&& wget https://github.com/brion/ogv.js/releases/download/$ver_ogvjs/ogvjs-$ver_ogvjs.zip -O ogvjs.zip \
|
||||||
&& wget https://github.com/asmcrypto/asmcrypto.js/archive/$ver_asmcrypto.tar.gz \
|
&& wget https://github.com/asmcrypto/asmcrypto.js/archive/$ver_asmcrypto.tar.gz -O asmcrypto.tgz \
|
||||||
&& unzip ogvjs-$ver_ogvjs.zip \
|
&& wget https://github.com/markedjs/marked/archive/v$ver_marked.tar.gz -O marked.tgz \
|
||||||
&& tar -xf $ver_asmcrypto.tar.gz \
|
&& unzip ogvjs.zip \
|
||||||
&& cd asmcrypto.js-$ver_asmcrypto \
|
&& (tar -xf asmcrypto.tgz \
|
||||||
&& npm install \
|
&& cd asmcrypto.js-$ver_asmcrypto \
|
||||||
|
&& npm install ) \
|
||||||
|
&& (tar -xf marked.tgz \
|
||||||
|
&& cd marked-$ver_marked \
|
||||||
|
&& npm install \
|
||||||
|
&& npm i grunt uglify-js -g ) \
|
||||||
&& mkdir /z/dist
|
&& mkdir /z/dist
|
||||||
|
|
||||||
|
|
||||||
|
# uncomment if you wanna test the abandoned markdown converters
|
||||||
|
#ENV build_abandoned=1
|
||||||
|
|
||||||
|
|
||||||
|
RUN [ $build_abandoned ] || exit 0; \
|
||||||
|
git clone --depth 1 --branch $ver_showdown https://github.com/showdownjs/showdown/ \
|
||||||
|
&& wget https://github.com/markdown-it/markdown-it/archive/$ver_markdownit.tar.gz -O markdownit.tgz \
|
||||||
|
&& (cd showdown \
|
||||||
|
&& npm install \
|
||||||
|
&& npm i grunt -g ) \
|
||||||
|
&& (tar -xf markdownit.tgz \
|
||||||
|
&& cd markdown-it-$ver_markdownit \
|
||||||
|
&& npm install )
|
||||||
|
|
||||||
|
|
||||||
# build asmcrypto
|
# build asmcrypto
|
||||||
RUN cd asmcrypto.js-$ver_asmcrypto \
|
RUN cd asmcrypto.js-$ver_asmcrypto \
|
||||||
&& echo "export { Sha512 } from './hash/sha512/sha512';" > src/entry-export_all.ts \
|
&& echo "export { Sha512 } from './hash/sha512/sha512';" > src/entry-export_all.ts \
|
||||||
&& node -r esm build.js \
|
&& node -r esm build.js \
|
||||||
&& mv asmcrypto.all.es5.js /z/dist/sha512.js
|
&& mv asmcrypto.all.es5.js /z/dist/sha512.js
|
||||||
|
|
||||||
|
|
||||||
# build ogvjs
|
# build ogvjs
|
||||||
RUN cd ogvjs-$ver_ogvjs \
|
RUN cd ogvjs-$ver_ogvjs \
|
||||||
&& cp -pv \
|
&& cp -pv \
|
||||||
|
@ -40,8 +65,90 @@ RUN cd ogvjs-$ver_ogvjs \
|
||||||
dynamicaudio.swf \
|
dynamicaudio.swf \
|
||||||
/z/dist
|
/z/dist
|
||||||
|
|
||||||
|
|
||||||
|
# build marked
|
||||||
|
COPY marked.patch /z/
|
||||||
|
RUN cd marked-$ver_marked \
|
||||||
|
&& patch -p1 < /z/marked.patch \
|
||||||
|
&& npm run build \
|
||||||
|
&& cp -pv marked.min.js /z/dist/marked.js \
|
||||||
|
&& cp -pv lib/marked.js /z/dist/marked.full.js
|
||||||
|
# && npm run test \
|
||||||
|
|
||||||
|
|
||||||
|
# build showdown (abandoned; disabled by default)
|
||||||
|
COPY showdown.patch /z/
|
||||||
|
RUN [ $build_abandoned ] || exit 0; \
|
||||||
|
cd showdown \
|
||||||
|
&& rm -rf bin dist \
|
||||||
|
# # remove ellipsis plugin \
|
||||||
|
&& rm \
|
||||||
|
src/subParsers/ellipsis.js \
|
||||||
|
test/cases/ellipsis* \
|
||||||
|
# # remove html-to-md converter \
|
||||||
|
&& rm \
|
||||||
|
test/node/testsuite.makemd.js \
|
||||||
|
test/node/showdown.Converter.makeMarkdown.js \
|
||||||
|
# # remove emojis \
|
||||||
|
&& rm src/subParsers/emoji.js \
|
||||||
|
&& awk '/^showdown.helper.emojis/ {o=1} !o; /^\}/ {o=0}' \
|
||||||
|
>f <src/helpers.js \
|
||||||
|
&& mv f src/helpers.js \
|
||||||
|
&& rm -rf test/features/emojis \
|
||||||
|
# # remove ghmentions \
|
||||||
|
&& rm test/features/ghMentions.* \
|
||||||
|
# # remove option descriptions \
|
||||||
|
&& sed -ri '/descri(ption|be): /d' src/options.js \
|
||||||
|
&& patch -p1 < /z/showdown.patch
|
||||||
|
|
||||||
|
RUN [ $build_abandoned ] || exit 0; \
|
||||||
|
cd showdown \
|
||||||
|
&& grunt build \
|
||||||
|
&& sed -ri '/sourceMappingURL=showdown.min.js.map/d' dist/showdown.min.js \
|
||||||
|
&& mv dist/showdown.min.js /z/dist/showdown.js \
|
||||||
|
&& ls -al /z/dist/showdown.js
|
||||||
|
|
||||||
|
|
||||||
|
# build markdownit (abandoned; disabled by default)
|
||||||
|
COPY markdown-it.patch /z/
|
||||||
|
RUN [ $build_abandoned ] || exit 0; \
|
||||||
|
cd markdown-it-$ver_markdownit \
|
||||||
|
&& patch -p1 < /z/markdown-it.patch \
|
||||||
|
&& make browserify \
|
||||||
|
&& cp -pv dist/markdown-it.min.js /z/dist/markdown-it.js \
|
||||||
|
&& cp -pv dist/markdown-it.js /z/dist/markdown-it-full.js
|
||||||
|
|
||||||
|
|
||||||
# compress
|
# compress
|
||||||
COPY zopfli.makefile /z/dist/Makefile
|
COPY zopfli.makefile /z/dist/Makefile
|
||||||
RUN cd /z/dist \
|
RUN cd /z/dist \
|
||||||
&& make -j$(nproc) \
|
&& make -j$(nproc) \
|
||||||
&& rm Makefile
|
&& rm Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# showdown: abandoned due to code-blocks in lists failing
|
||||||
|
# 22770 orig
|
||||||
|
# 12154 no-emojis
|
||||||
|
# 12134 no-srcmap
|
||||||
|
# 11189 no-descriptions
|
||||||
|
# 11152 no-ellipsis
|
||||||
|
# 10617 no-this.makeMd
|
||||||
|
# 9569 no-extensions
|
||||||
|
# 9537 no-extensions
|
||||||
|
# 9410 no-mentions
|
||||||
|
|
||||||
|
|
||||||
|
# markdown-it: abandoned because no header anchors (and too big)
|
||||||
|
# 32322 107754 orig (wowee)
|
||||||
|
# 19619 21392 71540 less entities
|
||||||
|
|
||||||
|
|
||||||
|
# marked:
|
||||||
|
# 9253 29773 orig
|
||||||
|
# 9159 29633 no copyright (reverted)
|
||||||
|
# 9040 29057 no sanitize
|
||||||
|
# 8870 28631 no email-mangle
|
||||||
|
# so really not worth it, just drop the patch when that stops working
|
||||||
|
|
||||||
|
|
||||||
|
# f=../../copyparty/web/deps/marked.js.gz; (cd ~ed/src/ && diff -NarU1 marked-1.0.0-orig/ marked-1.0.0-edit/) >marked.patch; make && printf '%d ' $(wc -c <$f) $(gzip -d <$f | wc -c); echo
|
||||||
|
|
10
scripts/deps-docker/markdown-it.patch
Normal file
10
scripts/deps-docker/markdown-it.patch
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
diff -NarU1 markdown-it-10.0.0-orig/lib/common/entities.js markdown-it-10.0.0-edit/lib/common/entities.js
|
||||||
|
--- markdown-it-10.0.0-orig/lib/common/entities.js 2019-09-10 21:39:58.000000000 +0000
|
||||||
|
+++ markdown-it-10.0.0-edit/lib/common/entities.js 2020-04-26 10:24:33.043023331 +0000
|
||||||
|
@@ -5,2 +5,5 @@
|
||||||
|
/*eslint quotes:0*/
|
||||||
|
-module.exports = require('entities/lib/maps/entities.json');
|
||||||
|
+//module.exports = require('entities/lib/maps/entities.json');
|
||||||
|
+module.exports = {
|
||||||
|
+ "amp": "&", "quot": "\"", "gt": ">", "lt": "<"
|
||||||
|
+}
|
269
scripts/deps-docker/marked.patch
Normal file
269
scripts/deps-docker/marked.patch
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
diff -NarU1 marked-1.0.0-orig/src/defaults.js marked-1.0.0-edit/src/defaults.js
|
||||||
|
--- marked-1.0.0-orig/src/defaults.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/src/defaults.js 2020-04-25 19:16:56.124621393 +0000
|
||||||
|
@@ -9,10 +9,6 @@
|
||||||
|
langPrefix: 'language-',
|
||||||
|
- mangle: true,
|
||||||
|
pedantic: false,
|
||||||
|
renderer: null,
|
||||||
|
- sanitize: false,
|
||||||
|
- sanitizer: null,
|
||||||
|
silent: false,
|
||||||
|
smartLists: false,
|
||||||
|
- smartypants: false,
|
||||||
|
tokenizer: null,
|
||||||
|
diff -NarU1 marked-1.0.0-orig/src/helpers.js marked-1.0.0-edit/src/helpers.js
|
||||||
|
--- marked-1.0.0-orig/src/helpers.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/src/helpers.js 2020-04-25 18:58:43.001320210 +0000
|
||||||
|
@@ -65,16 +65,3 @@
|
||||||
|
const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
|
||||||
|
-function cleanUrl(sanitize, base, href) {
|
||||||
|
- if (sanitize) {
|
||||||
|
- let prot;
|
||||||
|
- try {
|
||||||
|
- prot = decodeURIComponent(unescape(href))
|
||||||
|
- .replace(nonWordAndColonTest, '')
|
||||||
|
- .toLowerCase();
|
||||||
|
- } catch (e) {
|
||||||
|
- return null;
|
||||||
|
- }
|
||||||
|
- if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
|
||||||
|
- return null;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+function cleanUrl(base, href) {
|
||||||
|
if (base && !originIndependentUrl.test(href)) {
|
||||||
|
@@ -224,8 +211,2 @@
|
||||||
|
|
||||||
|
-function checkSanitizeDeprecation(opt) {
|
||||||
|
- if (opt && opt.sanitize && !opt.silent) {
|
||||||
|
- console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
module.exports = {
|
||||||
|
@@ -240,4 +221,3 @@
|
||||||
|
rtrim,
|
||||||
|
- findClosingBracket,
|
||||||
|
- checkSanitizeDeprecation
|
||||||
|
+ findClosingBracket
|
||||||
|
};
|
||||||
|
diff -NarU1 marked-1.0.0-orig/src/Lexer.js marked-1.0.0-edit/src/Lexer.js
|
||||||
|
--- marked-1.0.0-orig/src/Lexer.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/src/Lexer.js 2020-04-25 22:46:54.107584066 +0000
|
||||||
|
@@ -6,3 +6,3 @@
|
||||||
|
* smartypants text replacement
|
||||||
|
- */
|
||||||
|
+ *
|
||||||
|
function smartypants(text) {
|
||||||
|
@@ -27,3 +27,3 @@
|
||||||
|
* mangle email addresses
|
||||||
|
- */
|
||||||
|
+ *
|
||||||
|
function mangle(text) {
|
||||||
|
@@ -388,3 +388,3 @@
|
||||||
|
// autolink
|
||||||
|
- if (token = this.tokenizer.autolink(src, mangle)) {
|
||||||
|
+ if (token = this.tokenizer.autolink(src)) {
|
||||||
|
src = src.substring(token.raw.length);
|
||||||
|
@@ -395,3 +395,3 @@
|
||||||
|
// url (gfm)
|
||||||
|
- if (!inLink && (token = this.tokenizer.url(src, mangle))) {
|
||||||
|
+ if (!inLink && (token = this.tokenizer.url(src))) {
|
||||||
|
src = src.substring(token.raw.length);
|
||||||
|
@@ -402,3 +402,3 @@
|
||||||
|
// text
|
||||||
|
- if (token = this.tokenizer.inlineText(src, inRawBlock, smartypants)) {
|
||||||
|
+ if (token = this.tokenizer.inlineText(src, inRawBlock)) {
|
||||||
|
src = src.substring(token.raw.length);
|
||||||
|
diff -NarU1 marked-1.0.0-orig/src/marked.js marked-1.0.0-edit/src/marked.js
|
||||||
|
--- marked-1.0.0-orig/src/marked.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/src/marked.js 2020-04-25 22:42:55.140924439 +0000
|
||||||
|
@@ -8,3 +8,2 @@
|
||||||
|
merge,
|
||||||
|
- checkSanitizeDeprecation,
|
||||||
|
escape
|
||||||
|
@@ -37,3 +36,2 @@
|
||||||
|
opt = merge({}, marked.defaults, opt || {});
|
||||||
|
- checkSanitizeDeprecation(opt);
|
||||||
|
const highlight = opt.highlight;
|
||||||
|
@@ -101,6 +99,5 @@
|
||||||
|
opt = merge({}, marked.defaults, opt || {});
|
||||||
|
- checkSanitizeDeprecation(opt);
|
||||||
|
return Parser.parse(Lexer.lex(src, opt), opt);
|
||||||
|
} catch (e) {
|
||||||
|
- e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
||||||
|
+ e.message += '\nmake issue @ https://github.com/9001/copyparty';
|
||||||
|
if ((opt || marked.defaults).silent) {
|
||||||
|
diff -NarU1 marked-1.0.0-orig/src/Renderer.js marked-1.0.0-edit/src/Renderer.js
|
||||||
|
--- marked-1.0.0-orig/src/Renderer.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/src/Renderer.js 2020-04-25 18:59:15.091319265 +0000
|
||||||
|
@@ -134,3 +134,3 @@
|
||||||
|
link(href, title, text) {
|
||||||
|
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
||||||
|
+ href = cleanUrl(this.options.baseUrl, href);
|
||||||
|
if (href === null) {
|
||||||
|
@@ -147,3 +147,3 @@
|
||||||
|
image(href, title, text) {
|
||||||
|
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
||||||
|
+ href = cleanUrl(this.options.baseUrl, href);
|
||||||
|
if (href === null) {
|
||||||
|
diff -NarU1 marked-1.0.0-orig/src/Tokenizer.js marked-1.0.0-edit/src/Tokenizer.js
|
||||||
|
--- marked-1.0.0-orig/src/Tokenizer.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/src/Tokenizer.js 2020-04-25 22:47:07.610917004 +0000
|
||||||
|
@@ -256,9 +256,6 @@
|
||||||
|
return {
|
||||||
|
- type: this.options.sanitize
|
||||||
|
- ? 'paragraph'
|
||||||
|
- : 'html',
|
||||||
|
- raw: cap[0],
|
||||||
|
- pre: !this.options.sanitizer
|
||||||
|
- && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
|
||||||
|
- text: this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0]
|
||||||
|
+ type: 'html',
|
||||||
|
+ raw: cap[0],
|
||||||
|
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
|
||||||
|
+ text: cap[0]
|
||||||
|
};
|
||||||
|
@@ -382,5 +379,3 @@
|
||||||
|
return {
|
||||||
|
- type: this.options.sanitize
|
||||||
|
- ? 'text'
|
||||||
|
- : 'html',
|
||||||
|
+ type: 'html',
|
||||||
|
raw: cap[0],
|
||||||
|
@@ -388,7 +383,3 @@
|
||||||
|
inRawBlock,
|
||||||
|
- text: this.options.sanitize
|
||||||
|
- ? (this.options.sanitizer
|
||||||
|
- ? this.options.sanitizer(cap[0])
|
||||||
|
- : escape(cap[0]))
|
||||||
|
- : cap[0]
|
||||||
|
+ text: cap[0]
|
||||||
|
};
|
||||||
|
@@ -504,3 +495,3 @@
|
||||||
|
|
||||||
|
- autolink(src, mangle) {
|
||||||
|
+ autolink(src) {
|
||||||
|
const cap = this.rules.inline.autolink.exec(src);
|
||||||
|
@@ -509,3 +500,3 @@
|
||||||
|
if (cap[2] === '@') {
|
||||||
|
- text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
|
||||||
|
+ text = escape(cap[1]);
|
||||||
|
href = 'mailto:' + text;
|
||||||
|
@@ -532,3 +523,3 @@
|
||||||
|
|
||||||
|
- url(src, mangle) {
|
||||||
|
+ url(src) {
|
||||||
|
let cap;
|
||||||
|
@@ -537,3 +528,3 @@
|
||||||
|
if (cap[2] === '@') {
|
||||||
|
- text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
|
||||||
|
+ text = escape(cap[0]);
|
||||||
|
href = 'mailto:' + text;
|
||||||
|
@@ -569,3 +560,3 @@
|
||||||
|
|
||||||
|
- inlineText(src, inRawBlock, smartypants) {
|
||||||
|
+ inlineText(src, inRawBlock) {
|
||||||
|
const cap = this.rules.inline.text.exec(src);
|
||||||
|
@@ -574,5 +565,5 @@
|
||||||
|
if (inRawBlock) {
|
||||||
|
- text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];
|
||||||
|
+ text = cap[0];
|
||||||
|
} else {
|
||||||
|
- text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
|
||||||
|
+ text = escape(cap[0]);
|
||||||
|
}
|
||||||
|
diff -NarU1 marked-1.0.0-orig/test/bench.js marked-1.0.0-edit/test/bench.js
|
||||||
|
--- marked-1.0.0-orig/test/bench.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/test/bench.js 2020-04-25 19:02:27.227980287 +0000
|
||||||
|
@@ -34,3 +34,2 @@
|
||||||
|
pedantic: false,
|
||||||
|
- sanitize: false,
|
||||||
|
smartLists: false
|
||||||
|
@@ -46,3 +45,2 @@
|
||||||
|
pedantic: false,
|
||||||
|
- sanitize: false,
|
||||||
|
smartLists: false
|
||||||
|
@@ -59,3 +57,2 @@
|
||||||
|
pedantic: false,
|
||||||
|
- sanitize: false,
|
||||||
|
smartLists: false
|
||||||
|
@@ -71,3 +68,2 @@
|
||||||
|
pedantic: false,
|
||||||
|
- sanitize: false,
|
||||||
|
smartLists: false
|
||||||
|
@@ -84,3 +80,2 @@
|
||||||
|
pedantic: true,
|
||||||
|
- sanitize: false,
|
||||||
|
smartLists: false
|
||||||
|
@@ -96,3 +91,2 @@
|
||||||
|
pedantic: true,
|
||||||
|
- sanitize: false,
|
||||||
|
smartLists: false
|
||||||
|
diff -NarU1 marked-1.0.0-orig/test/specs/run-spec.js marked-1.0.0-edit/test/specs/run-spec.js
|
||||||
|
--- marked-1.0.0-orig/test/specs/run-spec.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/test/specs/run-spec.js 2020-04-25 19:05:24.321308408 +0000
|
||||||
|
@@ -21,6 +21,2 @@
|
||||||
|
}
|
||||||
|
- if (spec.options.sanitizer) {
|
||||||
|
- // eslint-disable-next-line no-eval
|
||||||
|
- spec.options.sanitizer = eval(spec.options.sanitizer);
|
||||||
|
- }
|
||||||
|
(spec.only ? fit : (spec.skip ? xit : it))('should ' + passFail + example, async() => {
|
||||||
|
@@ -49,2 +45 @@
|
||||||
|
runSpecs('ReDOS', './redos');
|
||||||
|
-runSpecs('Security', './security', false, { silent: true }); // silent - do not show deprecation warning
|
||||||
|
diff -NarU1 marked-1.0.0-orig/test/unit/Lexer-spec.js marked-1.0.0-edit/test/unit/Lexer-spec.js
|
||||||
|
--- marked-1.0.0-orig/test/unit/Lexer-spec.js 2020-04-21 01:03:48.000000000 +0000
|
||||||
|
+++ marked-1.0.0-edit/test/unit/Lexer-spec.js 2020-04-25 22:47:27.170916427 +0000
|
||||||
|
@@ -464,3 +464,3 @@
|
||||||
|
|
||||||
|
- it('sanitize', () => {
|
||||||
|
+ /*it('sanitize', () => {
|
||||||
|
expectTokens({
|
||||||
|
@@ -482,3 +482,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
});
|
||||||
|
@@ -586,3 +586,3 @@
|
||||||
|
|
||||||
|
- it('html sanitize', () => {
|
||||||
|
+ /*it('html sanitize', () => {
|
||||||
|
expectInlineTokens({
|
||||||
|
@@ -596,3 +596,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
|
||||||
|
@@ -825,3 +825,3 @@
|
||||||
|
|
||||||
|
- it('autolink mangle email', () => {
|
||||||
|
+ /*it('autolink mangle email', () => {
|
||||||
|
expectInlineTokens({
|
||||||
|
@@ -845,3 +845,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
|
||||||
|
@@ -882,3 +882,3 @@
|
||||||
|
|
||||||
|
- it('url mangle email', () => {
|
||||||
|
+ /*it('url mangle email', () => {
|
||||||
|
expectInlineTokens({
|
||||||
|
@@ -902,3 +902,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
});
|
||||||
|
@@ -918,3 +918,3 @@
|
||||||
|
|
||||||
|
- describe('smartypants', () => {
|
||||||
|
+ /*describe('smartypants', () => {
|
||||||
|
it('single quotes', () => {
|
||||||
|
@@ -988,3 +988,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
});
|
214
scripts/deps-docker/showdown.patch
Normal file
214
scripts/deps-docker/showdown.patch
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
diff -NarU1 showdown-orig/Gruntfile.js showdown-mod/Gruntfile.js
|
||||||
|
--- showdown-orig/Gruntfile.js 2020-04-23 06:22:01.486676149 +0000
|
||||||
|
+++ showdown-mod/Gruntfile.js 2020-04-23 08:03:56.700219788 +0000
|
||||||
|
@@ -27,3 +27,2 @@
|
||||||
|
'src/subParsers/*.js',
|
||||||
|
- 'src/subParsers/makeMarkdown/*.js',
|
||||||
|
'src/loader.js'
|
||||||
|
diff -NarU1 showdown-orig/src/converter.js showdown-mod/src/converter.js
|
||||||
|
--- showdown-orig/src/converter.js 2020-04-23 06:22:01.496676150 +0000
|
||||||
|
+++ showdown-mod/src/converter.js 2020-04-23 08:20:11.056920123 +0000
|
||||||
|
@@ -84,5 +84,5 @@
|
||||||
|
|
||||||
|
- if (options.extensions) {
|
||||||
|
+ /*if (options.extensions) {
|
||||||
|
showdown.helper.forEach(options.extensions, _parseExtension);
|
||||||
|
- }
|
||||||
|
+ }*/
|
||||||
|
}
|
||||||
|
@@ -95,3 +95,3 @@
|
||||||
|
*/
|
||||||
|
- function _parseExtension (ext, name) {
|
||||||
|
+ /*function _parseExtension (ext, name) {
|
||||||
|
|
||||||
|
@@ -159,3 +159,3 @@
|
||||||
|
*/
|
||||||
|
- function legacyExtensionLoading (ext, name) {
|
||||||
|
+ /*function legacyExtensionLoading (ext, name) {
|
||||||
|
if (typeof ext === 'function') {
|
||||||
|
@@ -351,3 +351,3 @@
|
||||||
|
*/
|
||||||
|
- this.makeMarkdown = this.makeMd = function (src, HTMLParser) {
|
||||||
|
+ /*this.makeMarkdown = this.makeMd = function (src, HTMLParser) {
|
||||||
|
|
||||||
|
@@ -482,3 +482,3 @@
|
||||||
|
*/
|
||||||
|
- this.addExtension = function (extension, name) {
|
||||||
|
+ /*this.addExtension = function (extension, name) {
|
||||||
|
name = name || null;
|
||||||
|
@@ -491,3 +491,3 @@
|
||||||
|
*/
|
||||||
|
- this.useExtension = function (extensionName) {
|
||||||
|
+ /*this.useExtension = function (extensionName) {
|
||||||
|
_parseExtension(extensionName);
|
||||||
|
@@ -526,3 +526,3 @@
|
||||||
|
*/
|
||||||
|
- this.removeExtension = function (extension) {
|
||||||
|
+ /*this.removeExtension = function (extension) {
|
||||||
|
if (!showdown.helper.isArray(extension)) {
|
||||||
|
@@ -549,3 +549,3 @@
|
||||||
|
*/
|
||||||
|
- this.getAllExtensions = function () {
|
||||||
|
+ /*this.getAllExtensions = function () {
|
||||||
|
return {
|
||||||
|
diff -NarU1 showdown-orig/src/options.js showdown-mod/src/options.js
|
||||||
|
--- showdown-orig/src/options.js 2020-04-23 06:22:01.496676150 +0000
|
||||||
|
+++ showdown-mod/src/options.js 2020-04-23 08:24:29.176929018 +0000
|
||||||
|
@@ -118,3 +118,3 @@
|
||||||
|
},
|
||||||
|
- ghMentions: {
|
||||||
|
+ /*ghMentions: {
|
||||||
|
defaultValue: false,
|
||||||
|
@@ -127,3 +127,3 @@
|
||||||
|
type: 'string'
|
||||||
|
- },
|
||||||
|
+ },*/
|
||||||
|
encodeEmails: {
|
||||||
|
diff -NarU1 showdown-orig/src/showdown.js showdown-mod/src/showdown.js
|
||||||
|
--- showdown-orig/src/showdown.js 2020-04-23 06:22:01.496676150 +0000
|
||||||
|
+++ showdown-mod/src/showdown.js 2020-04-23 08:25:01.976930148 +0000
|
||||||
|
@@ -7,3 +7,2 @@
|
||||||
|
parsers = {},
|
||||||
|
- extensions = {},
|
||||||
|
globalOptions = getDefaultOpts(true),
|
||||||
|
@@ -25,5 +24,4 @@
|
||||||
|
ghCompatibleHeaderId: true,
|
||||||
|
- ghMentions: true,
|
||||||
|
+ //ghMentions: true,
|
||||||
|
backslashEscapesHTMLTags: true,
|
||||||
|
- emoji: true,
|
||||||
|
splitAdjacentBlockquotes: true
|
||||||
|
@@ -48,3 +46,3 @@
|
||||||
|
requireSpaceBeforeHeadingText: true,
|
||||||
|
- ghMentions: false,
|
||||||
|
+ //ghMentions: false,
|
||||||
|
encodeEmails: true
|
||||||
|
@@ -65,3 +63,2 @@
|
||||||
|
*/
|
||||||
|
-showdown.extensions = {};
|
||||||
|
|
||||||
|
@@ -193,3 +190,3 @@
|
||||||
|
*/
|
||||||
|
-showdown.extension = function (name, ext) {
|
||||||
|
+/*showdown.extension = function (name, ext) {
|
||||||
|
'use strict';
|
||||||
|
@@ -235,3 +232,3 @@
|
||||||
|
*/
|
||||||
|
-showdown.getAllExtensions = function () {
|
||||||
|
+/*showdown.getAllExtensions = function () {
|
||||||
|
'use strict';
|
||||||
|
@@ -244,3 +241,3 @@
|
||||||
|
*/
|
||||||
|
-showdown.removeExtension = function (name) {
|
||||||
|
+/*showdown.removeExtension = function (name) {
|
||||||
|
'use strict';
|
||||||
|
@@ -252,3 +249,3 @@
|
||||||
|
*/
|
||||||
|
-showdown.resetExtensions = function () {
|
||||||
|
+/*showdown.resetExtensions = function () {
|
||||||
|
'use strict';
|
||||||
|
@@ -263,3 +260,3 @@
|
||||||
|
*/
|
||||||
|
-function validate (extension, name) {
|
||||||
|
+/*function validate (extension, name) {
|
||||||
|
'use strict';
|
||||||
|
@@ -370,3 +367,3 @@
|
||||||
|
*/
|
||||||
|
-showdown.validateExtension = function (ext) {
|
||||||
|
+/*showdown.validateExtension = function (ext) {
|
||||||
|
'use strict';
|
||||||
|
@@ -380 +377,2 @@
|
||||||
|
};
|
||||||
|
+*/
|
||||||
|
diff -NarU1 showdown-orig/src/subParsers/anchors.js showdown-mod/src/subParsers/anchors.js
|
||||||
|
--- showdown-orig/src/subParsers/anchors.js 2020-04-23 06:22:01.496676150 +0000
|
||||||
|
+++ showdown-mod/src/subParsers/anchors.js 2020-04-23 08:25:26.880264347 +0000
|
||||||
|
@@ -76,3 +76,3 @@
|
||||||
|
// Lastly handle GithubMentions if option is enabled
|
||||||
|
- if (options.ghMentions) {
|
||||||
|
+ /*if (options.ghMentions) {
|
||||||
|
text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) {
|
||||||
|
@@ -93,3 +93,3 @@
|
||||||
|
});
|
||||||
|
- }
|
||||||
|
+ }*/
|
||||||
|
|
||||||
|
diff -NarU1 showdown-orig/src/subParsers/spanGamut.js showdown-mod/src/subParsers/spanGamut.js
|
||||||
|
--- showdown-orig/src/subParsers/spanGamut.js 2020-04-23 06:22:01.496676150 +0000
|
||||||
|
+++ showdown-mod/src/subParsers/spanGamut.js 2020-04-23 08:07:50.460227880 +0000
|
||||||
|
@@ -22,3 +22,2 @@
|
||||||
|
text = showdown.subParser('simplifiedAutoLinks')(text, options, globals);
|
||||||
|
- text = showdown.subParser('emoji')(text, options, globals);
|
||||||
|
text = showdown.subParser('underline')(text, options, globals);
|
||||||
|
@@ -26,3 +25,2 @@
|
||||||
|
text = showdown.subParser('strikethrough')(text, options, globals);
|
||||||
|
- text = showdown.subParser('ellipsis')(text, options, globals);
|
||||||
|
|
||||||
|
diff -NarU1 showdown-orig/test/node/showdown.Converter.js showdown-mod/test/node/showdown.Converter.js
|
||||||
|
--- showdown-orig/test/node/showdown.Converter.js 2020-04-23 06:22:01.520009484 +0000
|
||||||
|
+++ showdown-mod/test/node/showdown.Converter.js 2020-04-23 08:14:58.086909318 +0000
|
||||||
|
@@ -29,3 +29,3 @@
|
||||||
|
|
||||||
|
- describe('Converter.options extensions', function () {
|
||||||
|
+ /*describe('Converter.options extensions', function () {
|
||||||
|
var runCount;
|
||||||
|
@@ -48,3 +48,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
|
||||||
|
@@ -115,3 +115,3 @@
|
||||||
|
|
||||||
|
- describe('extension methods', function () {
|
||||||
|
+ /*describe('extension methods', function () {
|
||||||
|
var extObjMock = {
|
||||||
|
@@ -145,3 +145,3 @@
|
||||||
|
});
|
||||||
|
- });
|
||||||
|
+ });*/
|
||||||
|
|
||||||
|
diff -NarU1 showdown-orig/test/node/showdown.js showdown-mod/test/node/showdown.js
|
||||||
|
--- showdown-orig/test/node/showdown.js 2020-04-23 06:22:01.523342816 +0000
|
||||||
|
+++ showdown-mod/test/node/showdown.js 2020-04-23 08:14:31.733575073 +0000
|
||||||
|
@@ -25,3 +25,3 @@
|
||||||
|
|
||||||
|
-describe('showdown.extension()', function () {
|
||||||
|
+/*describe('showdown.extension()', function () {
|
||||||
|
'use strict';
|
||||||
|
@@ -110,3 +110,3 @@
|
||||||
|
});
|
||||||
|
-});
|
||||||
|
+});*/
|
||||||
|
|
||||||
|
diff -NarU1 showdown-orig/test/node/testsuite.features.js showdown-mod/test/node/testsuite.features.js
|
||||||
|
--- showdown-orig/test/node/testsuite.features.js 2020-04-23 06:22:01.523342816 +0000
|
||||||
|
+++ showdown-mod/test/node/testsuite.features.js 2020-04-23 08:25:48.880265106 +0000
|
||||||
|
@@ -13,3 +13,2 @@
|
||||||
|
rawPrefixHeaderIdSuite = bootstrap.getTestSuite('test/features/rawPrefixHeaderId/'),
|
||||||
|
- emojisSuite = bootstrap.getTestSuite('test/features/emojis/'),
|
||||||
|
underlineSuite = bootstrap.getTestSuite('test/features/underline/'),
|
||||||
|
@@ -69,4 +68,4 @@
|
||||||
|
converter = new showdown.Converter({ghCompatibleHeaderId: true});
|
||||||
|
- } else if (testsuite[i].name === 'ghMentions') {
|
||||||
|
- converter = new showdown.Converter({ghMentions: true});
|
||||||
|
+ //} else if (testsuite[i].name === 'ghMentions') {
|
||||||
|
+ // converter = new showdown.Converter({ghMentions: true});
|
||||||
|
} else if (testsuite[i].name === 'disable-email-encoding') {
|
||||||
|
@@ -185,17 +184,2 @@
|
||||||
|
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||||
|
- }
|
||||||
|
- });
|
||||||
|
-
|
||||||
|
- /** test emojis support **/
|
||||||
|
- describe('emojis support', function () {
|
||||||
|
- var converter,
|
||||||
|
- suite = emojisSuite;
|
||||||
|
- for (var i = 0; i < suite.length; ++i) {
|
||||||
|
- if (suite[i].name === 'simplifiedautolinks') {
|
||||||
|
- converter = new showdown.Converter({emoji: true, simplifiedAutoLink: true});
|
||||||
|
- } else {
|
||||||
|
- converter = new showdown.Converter({emoji: true});
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||||
|
}
|
155
srv/test.md
Normal file
155
srv/test.md
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
*fails marked/showdown/tui/simplemde (just italics), **OK: markdown-it/simplemde:***
|
||||||
|
testing just google.com and underscored _google.com_ also with _google.com,_ trailing comma and _google.com_, comma after
|
||||||
|
|
||||||
|
*fails tui (just italics), **OK: marked/showdown/markdown-it/simplemde:***
|
||||||
|
testing just https://google.com and underscored _https://google.com_ links like that
|
||||||
|
|
||||||
|
*fails marked (no markup) and showdown/tui/simplemde (no links at all), **OK: markdown-it:***
|
||||||
|
let's try <google.com> bracketed and _<google.com>_ underscored bracketed
|
||||||
|
|
||||||
|
*fails marked (literal underscore), **OK: showdown/markdown-it/simplemde:***
|
||||||
|
let's try <https://google.com> bracketed and _<https://google.com>_ underscored bracketed
|
||||||
|
|
||||||
|
*fails none:*
|
||||||
|
and then [google](google.com) verbose and _[google](google.com)_ underscored
|
||||||
|
|
||||||
|
*fails none:*
|
||||||
|
and then [google](https://google.com/) verbose and _[google](https://google.com/)_ underscored
|
||||||
|
|
||||||
|
*all behave similarly (only verbose ones):*
|
||||||
|
and then <local> or maybe <./local> fsgfds </absolute> fsgfds
|
||||||
|
and then [local] or maybe [./local] fsgfds [/absolute] fsgfds
|
||||||
|
and then (local) or maybe (./local) fsgfds (/absolute) fsgfds
|
||||||
|
and then [](local) or maybe [](./local) fsgfds [](/absolute) fsgfds
|
||||||
|
and then [.](local) or maybe [.](./local) fsgfds [.](/absolute) fsgfds
|
||||||
|
and then [asdf](local) or maybe [asdf](./local) fsgfds [asdf](/absolute) fsgfds
|
||||||
|
|
||||||
|
*`ng/OK/OK/OK markdown-it`
|
||||||
|
`ng/OK/ng/OK marked`
|
||||||
|
`ng/OK/OK/OK showdown`
|
||||||
|
`OK/OK/OK/OK simplemde`*
|
||||||
|
[with spaces](/with spaces) plain, [with spaces](/with%20spaces) %20, [with spaces](</with spaces>) brackets, [with spaces](/with%20spaces) %20
|
||||||
|
|
||||||
|
*this fails marked, **OK: markdown-it, simplemde:***
|
||||||
|
|
||||||
|
* testing a list with:
|
||||||
|
`some code after a newline`
|
||||||
|
|
||||||
|
* testing a list with:
|
||||||
|
just a newline
|
||||||
|
|
||||||
|
and here is really just
|
||||||
|
a newline toplevel
|
||||||
|
|
||||||
|
*this fails showdown/hypermd, **OK: marked/markdown-it/simplemde:***
|
||||||
|
|
||||||
|
* testing a list with
|
||||||
|
|
||||||
|
code here
|
||||||
|
and a newline
|
||||||
|
this should have two leading spaces
|
||||||
|
|
||||||
|
* second list level
|
||||||
|
|
||||||
|
more code here
|
||||||
|
and a newline
|
||||||
|
this should have two leading spaces
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
* testing a list with
|
||||||
|
|
||||||
|
code here
|
||||||
|
and a newline
|
||||||
|
this should have two leading spaces
|
||||||
|
|
||||||
|
* second list level
|
||||||
|
|
||||||
|
more code here
|
||||||
|
and a newline
|
||||||
|
this should have two leading spaces
|
||||||
|
|
||||||
|
*this fails stackedit, **OK: showdown/marked/markdown-it/simplemde:***
|
||||||
|
|
||||||
|
|||
|
||||||
|
|--|--|
|
||||||
|
| a table | with no header |
|
||||||
|
| second row | foo bar |
|
||||||
|
|
||||||
|
*this fails showdown/stackedit, **OK: marked/markdown-it/simplemde:***
|
||||||
|
|
||||||
|
|||
|
||||||
|
|--|--:|
|
||||||
|
| a table | on the right |
|
||||||
|
| second row | foo bar |
|
||||||
|
|
||||||
|
* list entry
|
||||||
|
* [x] yes
|
||||||
|
* [ ] no
|
||||||
|
* another entry
|
||||||
|
|
||||||
|
# s1
|
||||||
|
## ep1
|
||||||
|
## ep2
|
||||||
|
# s2
|
||||||
|
## ep1
|
||||||
|
## ep2
|
||||||
|
# s3
|
||||||
|
## ep1
|
||||||
|
## ep2
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
marked:
|
||||||
|
works in last ff/chrome for xp
|
||||||
|
bug: config{breaks:true} does nothing in 1.0
|
||||||
|
use whitespace, no tabs
|
||||||
|
|
||||||
|
showdown:
|
||||||
|
ie6 and ie8 broken, works in last ff/chrome for xp
|
||||||
|
|
||||||
|
markdown-it:
|
||||||
|
works in last ff/chrome for xp
|
||||||
|
use whitespace, no tabs
|
||||||
|
no header anchors
|
||||||
|
|
||||||
|
tui wysiwyg:
|
||||||
|
requires links to be <http://> or [title](location)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
links:
|
||||||
|
http://demo.showdownjs.com/
|
||||||
|
https://marked.js.org/demo/
|
||||||
|
https://markdown-it.github.io/
|
||||||
|
https://simplemde.com/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all-pass:
|
||||||
|
|
||||||
|
https://github.com/joemccann/dillinger
|
||||||
|
https://dillinger.io/
|
||||||
|
uses markdown-it
|
||||||
|
|
||||||
|
https://github.com/markdown-it/markdown-it
|
||||||
|
https://markdown-it.github.io/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
almost-all-pass:
|
||||||
|
|
||||||
|
https://simplemde.com/
|
||||||
|
|
||||||
|
https://github.com/nhn/tui.editor
|
||||||
|
https://nhn.github.io/tui.editor/latest/tutorial-example01-editor-basic
|
||||||
|
ie10 and up
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unrelated neat stuff:
|
||||||
|
https://github.com/gnab/remark
|
||||||
|
|
Loading…
Reference in a new issue