mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-13 05:50:27 +00:00
Redo render
This commit is contained in:
parent
981f4ae513
commit
9c2846232c
58
fs/html.go
58
fs/html.go
@ -1,24 +1,16 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/gomarkdown/markdown"
|
||||
"github.com/gomarkdown/markdown/html"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
"gopkg.in/russross/blackfriday.v2"
|
||||
)
|
||||
|
||||
func markdownToHtml(md string) string {
|
||||
extensions := parser.CommonExtensions | parser.AutoHeadingIDs
|
||||
p := parser.NewWithExtensions(extensions)
|
||||
|
||||
htmlFlags := html.CommonFlags | html.HrefTargetBlank
|
||||
opts := html.RendererOptions{Flags: htmlFlags}
|
||||
renderer := html.NewRenderer(opts)
|
||||
|
||||
return string(markdown.ToHTML([]byte(md), p, renderer))
|
||||
func markdownToHtml(md []byte) string {
|
||||
return string(blackfriday.Run(NormalizeEOL(md)))
|
||||
}
|
||||
|
||||
func (h *Hypha) asHtml() (string, error) {
|
||||
@ -41,7 +33,7 @@ func (h *Hypha) asHtml() (string, error) {
|
||||
// TODO: support mycorrhiza extensions like transclusion.
|
||||
switch rev.TextMime {
|
||||
case "text/markdown":
|
||||
html := markdown.ToHTML(contents, nil, nil)
|
||||
html := markdownToHtml(contents)
|
||||
ret += string(html)
|
||||
default:
|
||||
ret += fmt.Sprintf(`<pre>%s</pre>`, contents)
|
||||
@ -52,3 +44,43 @@ func (h *Hypha) asHtml() (string, error) {
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// NormalizeEOL will convert Windows (CRLF) and Mac (CR) EOLs to UNIX (LF)
|
||||
// Code taken from here: https://github.com/go-gitea/gitea/blob/dc8036dcc680abab52b342d18181a5ee42f40318/modules/util/util.go#L68-L102
|
||||
// Gitea has MIT License
|
||||
//
|
||||
// We use it because md parser does not handle CRLF correctly. I don't know why, but CRLF appears sometimes.
|
||||
func NormalizeEOL(input []byte) []byte {
|
||||
var right, left, pos int
|
||||
if right = bytes.IndexByte(input, '\r'); right == -1 {
|
||||
return input
|
||||
}
|
||||
length := len(input)
|
||||
tmp := make([]byte, length)
|
||||
|
||||
// We know that left < length because otherwise right would be -1 from IndexByte.
|
||||
copy(tmp[pos:pos+right], input[left:left+right])
|
||||
pos += right
|
||||
tmp[pos] = '\n'
|
||||
left += right + 1
|
||||
pos++
|
||||
|
||||
for left < length {
|
||||
if input[left] == '\n' {
|
||||
left++
|
||||
}
|
||||
|
||||
right = bytes.IndexByte(input[left:], '\r')
|
||||
if right == -1 {
|
||||
copy(tmp[pos:], input[left:])
|
||||
pos += length - left
|
||||
break
|
||||
}
|
||||
copy(tmp[pos:pos+right], input[left:left+right])
|
||||
pos += right
|
||||
tmp[pos] = '\n'
|
||||
left += right + 1
|
||||
pos++
|
||||
}
|
||||
return tmp[:pos]
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ func (h *Hypha) ActionZen(w http.ResponseWriter) *Hypha {
|
||||
|
||||
// ActionView is used with `?action=view` or no action at all.
|
||||
// It renders the page, the layout and everything else.
|
||||
func (h *Hypha) ActionView(w http.ResponseWriter, renderExists, renderNotExists func(string, string) string) *Hypha {
|
||||
func (h *Hypha) ActionView(w http.ResponseWriter, renderExists, renderNotExists func(string, string) []byte) *Hypha {
|
||||
var html string
|
||||
var err error
|
||||
if h.Exists {
|
||||
@ -167,9 +167,9 @@ func (h *Hypha) ActionView(w http.ResponseWriter, renderExists, renderNotExists
|
||||
w.Header().Set("Content-Type", "text/html;charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if h.Exists {
|
||||
w.Write([]byte(renderExists(h.FullName, html)))
|
||||
w.Write(renderExists(h.FullName, html))
|
||||
} else {
|
||||
w.Write([]byte(renderNotExists(h.FullName, "")))
|
||||
w.Write(renderNotExists(h.FullName, ""))
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
8
go.mod
8
go.mod
@ -3,7 +3,13 @@ module github.com/bouncepaw/mycorrhiza
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725
|
||||
github.com/gorilla/mux v1.7.4
|
||||
mvdan.cc/gogrep v0.0.0-20200420132841-24e8804e5b3c // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
gopkg.in/russross/blackfriday.v2 v2.0.1
|
||||
)
|
||||
|
||||
replace gopkg.in/russross/blackfriday.v2 => github.com/russross/blackfriday/v2 v2.0.1
|
||||
|
4
go.sum
4
go.sum
@ -5,6 +5,10 @@ github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
|
@ -44,7 +44,7 @@ func HandlerEdit(w http.ResponseWriter, rq *http.Request) {
|
||||
h := fs.Hs.Open(vars["hypha"]).OnRevision("0")
|
||||
w.Header().Set("Content-Type", "text/html;charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(render.HyphaEdit(h)))
|
||||
w.Write(render.HyphaEdit(h))
|
||||
}
|
||||
|
||||
func HandlerUpdate(w http.ResponseWriter, rq *http.Request) {
|
||||
@ -63,6 +63,6 @@ func HandlerUpdate(w http.ResponseWriter, rq *http.Request) {
|
||||
if !h.Invalid {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.Write([]byte(render.HyphaUpdateOk(h)))
|
||||
w.Write(render.HyphaUpdateOk(h))
|
||||
}
|
||||
}
|
||||
|
161
render/render.go
161
render/render.go
@ -10,74 +10,52 @@ import (
|
||||
"github.com/bouncepaw/mycorrhiza/fs"
|
||||
)
|
||||
|
||||
// EditHyphaPage returns HTML page of hypha editor.
|
||||
func EditHyphaPage(name, textMime, content, tags string) string {
|
||||
page := map[string]string{
|
||||
"Text": content,
|
||||
"TextMime": textMime,
|
||||
"Name": name,
|
||||
"Tags": tags,
|
||||
}
|
||||
keys := map[string]string{
|
||||
"Title": fmt.Sprintf(cfg.TitleEditTemplate, name),
|
||||
"Header": renderFromString(name, "Hypha/edit/header.html"),
|
||||
"Sidebar": renderFromMap(page, "Hypha/edit/sidebar.html"),
|
||||
}
|
||||
return renderBase(renderFromMap(page, "Hypha/edit/index.html"), keys)
|
||||
}
|
||||
|
||||
func HyphaEdit(h *fs.Hypha) string {
|
||||
page := map[string]string{
|
||||
// HyphaEdit renders hypha editor.
|
||||
func HyphaEdit(h *fs.Hypha) []byte { //
|
||||
hyphaData := map[string]string{
|
||||
"Name": h.FullName,
|
||||
"Tags": h.TagsJoined(),
|
||||
"TextMime": h.TextMime(),
|
||||
"Text": h.TextContent(),
|
||||
}
|
||||
keys := map[string]string{
|
||||
return layout("edit/index").
|
||||
withMap(hyphaData).
|
||||
wrapInBase(map[string]string{
|
||||
"Title": fmt.Sprintf(cfg.TitleEditTemplate, h.FullName),
|
||||
"Header": renderFromString(h.FullName, "Hypha/edit/header.html"),
|
||||
"Sidebar": renderFromMap(page, "Hypha/edit/sidebar.html"),
|
||||
}
|
||||
return renderBase(renderFromMap(page, "Hypha/edit/index.html"), keys)
|
||||
"Header": layout("edit/header").withString(h.FullName).String(),
|
||||
"Sidebar": layout("edit/sidebar").withMap(hyphaData).String(),
|
||||
})
|
||||
}
|
||||
|
||||
// Hypha404 returns 404 page for nonexistent page.
|
||||
func Hypha404(name, _ string) string {
|
||||
return HyphaGeneric(name, name, "Hypha/view/404.html")
|
||||
// HyphaUpdateOk is used to inform that update was successful.
|
||||
func HyphaUpdateOk(h *fs.Hypha) []byte { //
|
||||
return layout("updateOk").
|
||||
withMap(map[string]string{"Name": h.FullName}).
|
||||
Bytes()
|
||||
}
|
||||
|
||||
// HyphaPage returns HTML page of hypha viewer.
|
||||
func HyphaPage(name, content string) string {
|
||||
return HyphaGeneric(name, content, "Hypha/view/index.html")
|
||||
// Hypha404 renders 404 page for nonexistent page.
|
||||
func Hypha404(name, _ string) []byte {
|
||||
return hyphaGeneric(name, name, "view/404")
|
||||
}
|
||||
|
||||
// HyphaGeneric is used when building renderers for all types of hypha pages
|
||||
func HyphaGeneric(name string, content, templatePath string) string {
|
||||
var sidebar string
|
||||
if aside := renderFromMap(map[string]string{
|
||||
"Tree": fs.Hs.GetTree(name, true).AsHtml(),
|
||||
}, "Hypha/view/sidebar.html"); aside != "" {
|
||||
sidebar = aside
|
||||
// HyphaPage renders hypha viewer.
|
||||
func HyphaPage(name, content string) []byte {
|
||||
return hyphaGeneric(name, content, "view/index")
|
||||
}
|
||||
keys := map[string]string{
|
||||
|
||||
// hyphaGeneric is used when building renderers for all types of hypha pages
|
||||
func hyphaGeneric(name, content, templateName string) []byte {
|
||||
return layout(templateName).
|
||||
withString(content).
|
||||
wrapInBase(map[string]string{
|
||||
"Title": fmt.Sprintf(cfg.TitleTemplate, name),
|
||||
"Sidebar": sidebar,
|
||||
}
|
||||
return renderBase(renderFromString(content, templatePath), keys)
|
||||
"Sidebar": hyphaTree(name),
|
||||
})
|
||||
}
|
||||
|
||||
func HyphaUpdateOk(h *fs.Hypha) string {
|
||||
data := map[string]string{
|
||||
"Name": h.FullName,
|
||||
}
|
||||
return renderFromMap(data, "updateOk.html")
|
||||
}
|
||||
|
||||
// renderBase collects and renders page from base template
|
||||
// Args:
|
||||
// content: string or pre-rendered template
|
||||
// keys: map with replaced standart fields
|
||||
func renderBase(content string, keys map[string]string) string {
|
||||
// wrapInBase is used to wrap layouts in things that are present on all pages.
|
||||
func (lyt *Layout) wrapInBase(keys map[string]string) []byte {
|
||||
page := map[string]string{
|
||||
"Title": cfg.SiteTitle,
|
||||
"Main": "",
|
||||
@ -86,36 +64,67 @@ func renderBase(content string, keys map[string]string) string {
|
||||
for key, val := range keys {
|
||||
page[key] = val
|
||||
}
|
||||
page["Main"] = content
|
||||
return renderFromMap(page, "base.html")
|
||||
page["Main"] = lyt.String()
|
||||
return layout("base").withMap(page).Bytes()
|
||||
}
|
||||
|
||||
// renderFromMap applies `data` map to template in `templatePath` and returns the result.
|
||||
func renderFromMap(data map[string]string, templatePath string) string {
|
||||
hyphPath := path.Join(cfg.TemplatesDir, cfg.Theme, templatePath)
|
||||
h := fs.Hs.Open(hyphPath).OnRevision("0")
|
||||
tmpl, err := template.ParseFiles(h.TextPath())
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tmpl.Execute(buf, data); err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return buf.String()
|
||||
func hyphaTree(name string) string {
|
||||
return layout("view/sidebar").
|
||||
withMap(map[string]string{"Tree": fs.Hs.GetTree(name, true).AsHtml()}).
|
||||
String()
|
||||
}
|
||||
|
||||
// renderFromMap applies `data` string to template in `templatePath` and returns the result.
|
||||
func renderFromString(data string, templatePath string) string {
|
||||
hyphPath := path.Join(cfg.TemplatesDir, cfg.Theme, templatePath)
|
||||
h := fs.Hs.Open(hyphPath).OnRevision("0")
|
||||
type Layout struct {
|
||||
tmpl *template.Template
|
||||
buf *bytes.Buffer
|
||||
invalid bool
|
||||
err error
|
||||
}
|
||||
|
||||
func layout(name string) *Layout {
|
||||
h := fs.Hs.Open(path.Join(cfg.TemplatesDir, cfg.Theme, name+".html")).OnRevision("0")
|
||||
if h.Invalid {
|
||||
return &Layout{nil, nil, true, h.Err}
|
||||
}
|
||||
tmpl, err := template.ParseFiles(h.TextPath())
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
return &Layout{nil, nil, true, err}
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tmpl.Execute(buf, data); err != nil {
|
||||
return err.Error()
|
||||
return &Layout{tmpl, new(bytes.Buffer), false, nil}
|
||||
}
|
||||
return buf.String()
|
||||
|
||||
func (lyt *Layout) withString(data string) *Layout {
|
||||
if lyt.invalid {
|
||||
return lyt
|
||||
}
|
||||
if err := lyt.tmpl.Execute(lyt.buf, data); err != nil {
|
||||
lyt.invalid = true
|
||||
lyt.err = err
|
||||
}
|
||||
return lyt
|
||||
}
|
||||
|
||||
func (lyt *Layout) withMap(data map[string]string) *Layout {
|
||||
if lyt.invalid {
|
||||
return lyt
|
||||
}
|
||||
if err := lyt.tmpl.Execute(lyt.buf, data); err != nil {
|
||||
lyt.invalid = true
|
||||
lyt.err = err
|
||||
}
|
||||
return lyt
|
||||
}
|
||||
|
||||
func (lyt *Layout) Bytes() []byte {
|
||||
if lyt.invalid {
|
||||
return []byte(lyt.err.Error())
|
||||
}
|
||||
return lyt.buf.Bytes()
|
||||
}
|
||||
|
||||
func (lyt *Layout) String() string {
|
||||
if lyt.invalid {
|
||||
return lyt.err.Error()
|
||||
}
|
||||
return lyt.buf.String()
|
||||
}
|
||||
|
5
w/m/Fruit/4.markdown
Normal file
5
w/m/Fruit/4.markdown
Normal file
@ -0,0 +1,5 @@
|
||||
According to real *scientists*, fruit is a type of fetus. Most of them are tasty and cool, though some of them are really sour and depressing. Be careful when choosing fruit. Best ones are:
|
||||
|
||||
* [Apple](./Apple)
|
||||
* [Pear](/Pear)
|
||||
|
10
w/m/Fruit/5.markdown
Normal file
10
w/m/Fruit/5.markdown
Normal file
@ -0,0 +1,10 @@
|
||||
According to real *scientists*, fruit is a type of fetus. Most of them are tasty and cool, though some of them are really sour and depressing. Be careful when choosing fruit. Best ones are:
|
||||
|
||||
- [Apple](Fruit/Apple)
|
||||
- [Pear](Fruit/Pear)
|
||||
|
||||
```
|
||||
фрукты полезны для здоровья!!
|
||||
```
|
||||
|
||||
|
@ -40,6 +40,32 @@
|
||||
"binary_mime": "",
|
||||
"text_name": "3.markdown",
|
||||
"binary_name": ""
|
||||
},
|
||||
"4": {
|
||||
"tags": [
|
||||
""
|
||||
],
|
||||
"name": "Fruit",
|
||||
"comment": "Update Fruit",
|
||||
"author": "",
|
||||
"time": 1593338963,
|
||||
"text_mime": "text/markdown",
|
||||
"binary_mime": "",
|
||||
"text_name": "4.markdown",
|
||||
"binary_name": ""
|
||||
},
|
||||
"5": {
|
||||
"tags": [
|
||||
""
|
||||
],
|
||||
"name": "Fruit",
|
||||
"comment": "Update Fruit",
|
||||
"author": "",
|
||||
"time": 1593339050,
|
||||
"text_mime": "text/markdown",
|
||||
"binary_mime": "",
|
||||
"text_name": "5.markdown",
|
||||
"binary_name": ""
|
||||
}
|
||||
},
|
||||
"Invalid": false,
|
||||
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "header.html",
|
||||
"comment": "Create Templates/default-dark/Hypha/edit/header.html",
|
||||
"author": "",
|
||||
"time": 1592996801,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<div class="naviwrapper">
|
||||
<form class="naviwrapper__edit edit-box"
|
||||
method="POST"
|
||||
id="editform"
|
||||
enctype="multipart/form-data"
|
||||
action="?action=update">
|
||||
|
||||
<div class="edit-box__left">
|
||||
<h4 class="">Edit box</h4>
|
||||
<!-- It is important that there is no indent ↓ -->
|
||||
<textarea class="edit-box__text" name="text" cols="80" rows="25">
|
||||
{{ .Text }}</textarea>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "index.html",
|
||||
"comment": "Create Templates/default-dark/Hypha/edit/index.html",
|
||||
"author": "",
|
||||
"time": 1592996876,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<div style=""><h4>Text MIME-type</h4>
|
||||
<p>Good types are <code>text/markdown</code> and <code>text/plain</code></p>
|
||||
<input type="text" name="text_mime" value="{{ .TextMime }}"/>
|
||||
|
||||
<h4>Revision comment</h4>
|
||||
<p>Please make your comment helpful</p>
|
||||
<input type="text" name="comment" value="Update {{ .Name }}"/>
|
||||
|
||||
<h4>Edit tags</h4>
|
||||
<p>Tags are separated by commas, whitespace is ignored</p>
|
||||
<input type="text" name="tags" value="{{ .Tags }}"/>
|
||||
|
||||
<h4>Upload file</h4>
|
||||
<p>If this hypha has a file like that, the text above is meant to be a description of it</p>
|
||||
<input type="file" name="binary"/>
|
||||
|
||||
|
||||
<p><input type="submit" value="update"/></p>
|
||||
</div>
|
@ -1,4 +0,0 @@
|
||||
<h1 class="page__title">{{ . }}</h1>
|
||||
<p class="msg_hypha-does-not-exist msg">
|
||||
The hypha you are trying to access does not exist yet. Why not <a href="?action=edit">create</a> it?
|
||||
</p>
|
@ -1,30 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ .Title }}</title>
|
||||
<link rel="stylesheet" href="/Templates/default-dark/main.css?action=raw">
|
||||
</head>
|
||||
<body>
|
||||
<div class="shroom">
|
||||
<button class="shroom__button" id="shroomBtn"><span>🍄</span> Open</button>
|
||||
</div>
|
||||
<main class="main">{{ .Main }}</main>
|
||||
<div class="left-panel" id="shroomburgerMenu">
|
||||
<div class="left-panel__in">
|
||||
<div class="shroom mushroom">
|
||||
<button class="shroom__button" id="mushroomBtn"><span>🍄</span> Close</button>
|
||||
</div>
|
||||
<div class="left-panel__contents">
|
||||
<!-- Site title is fetched from your config.json. Set your title in "site-title" field. You can add more things to the header here. -->
|
||||
<header class="header">
|
||||
<h1 class="header__site-title">{{ .SiteTitle }}</h1>
|
||||
</header>
|
||||
<aside class="sidebar">{{ .Sidebar }}</aside>
|
||||
<footer class="footer">
|
||||
<p>This website runs <a href='https://github.com/bouncepaw/mycorrhiza'>MycorrhizaWiki</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/Templates/default-dark/main.js?action=raw"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "base.html",
|
||||
"comment": "Create Templates/default-dark/base.html",
|
||||
"author": "",
|
||||
"time": 1592996503,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,221 +0,0 @@
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font: 15px/1.5 system-ui, -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Helvetica', 'PT Sans', 'Roboto', 'Arial', sans-serif;
|
||||
max-width: 500px;
|
||||
min-height: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 12px 24px;
|
||||
background-color: #272b30;
|
||||
color: #c8c8c8;
|
||||
}
|
||||
|
||||
.msg {
|
||||
background-color: #f4f4f4;
|
||||
padding: 1rem;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.shroom {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.shroom__button {
|
||||
border-radius: 1rem;
|
||||
padding: 8px 16px 8px 0;
|
||||
border: none;
|
||||
background: #f0f2f4;
|
||||
color: #444;
|
||||
font: inherit;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.shroom span {
|
||||
margin-left: 16px;
|
||||
margin-right: 8px;
|
||||
font-size: 20px;
|
||||
vertical-align: -0.04em;
|
||||
}
|
||||
|
||||
.mushroom .shroom__button {
|
||||
background: #44484a;
|
||||
color: #dddfe4;
|
||||
}
|
||||
|
||||
|
||||
.header {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
color: #20ce92;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: #019fe3;
|
||||
}
|
||||
|
||||
/*a:visited {
|
||||
color: #44a;
|
||||
}*/
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0.5em 0 0.25em;
|
||||
}
|
||||
|
||||
.page {
|
||||
font-size: 16px;
|
||||
line-height: 1.666;
|
||||
max-width: 40em;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.page pre {
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.page__amnt {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.page__title {
|
||||
font-family: 'PT Serif', 'Georgia', serif;
|
||||
font-size: 36px;
|
||||
font-weight: normal;
|
||||
color: #20ce92;
|
||||
}
|
||||
|
||||
.edit-box {
|
||||
display: grid;
|
||||
grid-template-columns: 7fr 5fr;
|
||||
}
|
||||
.edit-box .naviwrapper__buttons {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
}
|
||||
.edit-box__left { grid-column: 1; grid-row: 2 }
|
||||
.edit-box__right { grid-column: 2; grid-row: 1 / span 2; padding-right: 16px }
|
||||
.edit-box__text {
|
||||
border-radius: 1rem;
|
||||
color: #c8c8c8;
|
||||
padding: 16px;
|
||||
background-color: rgba(255,255,255,.05);
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 1em 0;
|
||||
font-size: 12px;
|
||||
color: #7a8288;
|
||||
}
|
||||
|
||||
footer a, footer a:visited {
|
||||
color: #7a8288;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.left-panel.active {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.left-panel.active .sidebar {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.left-panel__in {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
padding: 12px 24px;
|
||||
|
||||
}
|
||||
|
||||
.left-panel__contents {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
}
|
||||
|
||||
.left-panel .shroom {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@media (min-width: 700px) {
|
||||
body {
|
||||
max-width: 1200px;
|
||||
padding: 8px 16px;
|
||||
padding-right: 274px;
|
||||
}
|
||||
|
||||
.shroom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
min-width: 274px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.left-panel__contents {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding: 16px;
|
||||
border-radius: 1rem;
|
||||
background-color: rgba(255,255,255,.05);
|
||||
}
|
||||
|
||||
.hypha-actions ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.hypha-actions li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.hypha-actions a {
|
||||
display: block;
|
||||
padding: 6px 16px;
|
||||
font: inherit;
|
||||
text-decoration: none;
|
||||
color: #7a8288;
|
||||
transition: 0.1s background;
|
||||
}
|
||||
|
||||
aside .hypha-actions a:hover {
|
||||
background-color: #272b30;
|
||||
color: #73ca73;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": [
|
||||
""
|
||||
],
|
||||
"name": "main.css",
|
||||
"comment": "Update sys/main.css",
|
||||
"author": "",
|
||||
"time": 1592666188,
|
||||
"text_mime": "text/css",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.css",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
var menu = document.getElementById('shroomburgerMenu');
|
||||
document.getElementById('shroomBtn').addEventListener('click', function() {
|
||||
menu.classList.add('active');
|
||||
});
|
||||
document.getElementById('mushroomBtn').addEventListener('click', function() {
|
||||
menu.classList.remove('active');
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "main.js",
|
||||
"comment": "Update sys/main.js",
|
||||
"author": "",
|
||||
"time": 1592937088,
|
||||
"text_mime": "text/javascript",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.mjs",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Saved {{ .Name }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Saved successfully. <a href="/{{ .Name }}">Go back</a></p>
|
||||
</body>
|
||||
</html>
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "updateOk.html",
|
||||
"comment": "Create Templates/default-dark/updateOk.html",
|
||||
"author": "",
|
||||
"time": 1592996644,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
<h1 class="header__edit-title">Edit {{ . }}</h1>
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": [
|
||||
""
|
||||
],
|
||||
"name": "sidebar.html",
|
||||
"comment": "Create Templates/default-dark/Hypha/edit/sidebar.html",
|
||||
"author": "",
|
||||
"time": 1593003792,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "404.html",
|
||||
"comment": "Create Templates/default-light/Hypha/view/404.html",
|
||||
"author": "",
|
||||
"time": 1592996917,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
{{ . }}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "index.html",
|
||||
"comment": "Create Templates/default-light/Hypha/view/index.html",
|
||||
"author": "",
|
||||
"time": 1592996954,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
<div class="hypha-actions">
|
||||
<ul>
|
||||
<li><a href="?action=edit">Edit</a></li>
|
||||
<li><a href="?action=getBinary">Download</a></li>
|
||||
<li><a href="?action=zen">Zen mode</a></li>
|
||||
<li><a href="?action=raw">View raw</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ .Tree }}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "sidebar.html",
|
||||
"comment": "Create Templates/default-light/Hypha/view/sidebar.html",
|
||||
"author": "",
|
||||
"time": 1592996977,
|
||||
"text_mime": "text/html",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.html",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
232
w/m/TestMd/1.markdown
Normal file
232
w/m/TestMd/1.markdown
Normal file
@ -0,0 +1,232 @@
|
||||
|
||||
|
||||
# h1 Heading 8-)
|
||||
## h2 Heading
|
||||
### h3 Heading
|
||||
#### h4 Heading
|
||||
##### h5 Heading
|
||||
###### h6 Heading
|
||||
|
||||
|
||||
## Horizontal Rules
|
||||
|
||||
___
|
||||
|
||||
---
|
||||
|
||||
***
|
||||
|
||||
|
||||
## Typographic replacements
|
||||
|
||||
Enable typographer option to see result.
|
||||
|
||||
(c) (C) (r) (R) (tm) (TM) (p) (P) +-
|
||||
|
||||
test.. test... test..... test?..... test!....
|
||||
|
||||
!!!!!! ???? ,, -- ---
|
||||
|
||||
"Smartypants, double quotes" and 'single quotes'
|
||||
|
||||
|
||||
## Emphasis
|
||||
|
||||
**This is bold text**
|
||||
|
||||
__This is bold text__
|
||||
|
||||
*This is italic text*
|
||||
|
||||
_This is italic text_
|
||||
|
||||
~~Strikethrough~~
|
||||
|
||||
|
||||
## Blockquotes
|
||||
|
||||
|
||||
> Blockquotes can also be nested...
|
||||
>> ...by using additional greater-than signs right next to each other...
|
||||
> > > ...or with spaces between arrows.
|
||||
|
||||
|
||||
## Lists
|
||||
|
||||
Unordered
|
||||
|
||||
+ Create a list by starting a line with `+`, `-`, or `*`
|
||||
+ Sub-lists are made by indenting 2 spaces:
|
||||
- Marker character change forces new list start:
|
||||
* Ac tristique libero volutpat at
|
||||
+ Facilisis in pretium nisl aliquet
|
||||
- Nulla volutpat aliquam velit
|
||||
+ Very easy!
|
||||
|
||||
Ordered
|
||||
|
||||
1. Lorem ipsum dolor sit amet
|
||||
2. Consectetur adipiscing elit
|
||||
3. Integer molestie lorem at massa
|
||||
|
||||
|
||||
1. You can use sequential numbers...
|
||||
1. ...or keep all the numbers as `1.`
|
||||
|
||||
Start numbering with offset:
|
||||
|
||||
57. foo
|
||||
1. bar
|
||||
|
||||
|
||||
## Code
|
||||
|
||||
Inline `code`
|
||||
|
||||
Indented code
|
||||
|
||||
// Some comments
|
||||
line 1 of code
|
||||
line 2 of code
|
||||
line 3 of code
|
||||
|
||||
|
||||
Block code "fences"
|
||||
|
||||
```
|
||||
Sample text here...
|
||||
```
|
||||
|
||||
Syntax highlighting
|
||||
|
||||
``` js
|
||||
var foo = function (bar) {
|
||||
return bar++;
|
||||
};
|
||||
|
||||
console.log(foo(5));
|
||||
```
|
||||
|
||||
## Tables
|
||||
|
||||
| Option | Description |
|
||||
| ------ | ----------- |
|
||||
| data | path to data files to supply the data that will be passed into templates. |
|
||||
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||
| ext | extension to be used for dest files. |
|
||||
|
||||
Right aligned columns
|
||||
|
||||
| Option | Description |
|
||||
| ------:| -----------:|
|
||||
| data | path to data files to supply the data that will be passed into templates. |
|
||||
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||
| ext | extension to be used for dest files. |
|
||||
|
||||
|
||||
## Links
|
||||
|
||||
[link text](http://dev.nodeca.com)
|
||||
|
||||
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
|
||||
|
||||
Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
|
||||
|
||||
|
||||
## Images
|
||||
|
||||
![Minion](https://octodex.github.com/images/minion.png)
|
||||
![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat")
|
||||
|
||||
Like links, Images also have a footnote style syntax
|
||||
|
||||
![Alt text][id]
|
||||
|
||||
With a reference later in the document defining the URL location:
|
||||
|
||||
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
||||
|
||||
|
||||
## Plugins
|
||||
|
||||
The killer feature of `markdown-it` is very effective support of
|
||||
[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
|
||||
|
||||
|
||||
### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
|
||||
|
||||
> Classic markup: :wink: :crush: :cry: :tear: :laughing: :yum:
|
||||
>
|
||||
> Shortcuts (emoticons): :-) :-( 8-) ;)
|
||||
|
||||
see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
|
||||
|
||||
|
||||
### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
|
||||
|
||||
- 19^th^
|
||||
- H~2~O
|
||||
|
||||
|
||||
### [\<ins>](https://github.com/markdown-it/markdown-it-ins)
|
||||
|
||||
++Inserted text++
|
||||
|
||||
|
||||
### [\<mark>](https://github.com/markdown-it/markdown-it-mark)
|
||||
|
||||
==Marked text==
|
||||
|
||||
|
||||
### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
|
||||
|
||||
Footnote 1 link[^first].
|
||||
|
||||
Footnote 2 link[^second].
|
||||
|
||||
Inline footnote^[Text of inline footnote] definition.
|
||||
|
||||
Duplicated footnote reference[^second].
|
||||
|
||||
[^first]: Footnote **can have markup**
|
||||
|
||||
and multiple paragraphs.
|
||||
|
||||
[^second]: Footnote text.
|
||||
|
||||
|
||||
### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
|
||||
|
||||
Term 1
|
||||
|
||||
: Definition 1
|
||||
with lazy continuation.
|
||||
|
||||
Term 2 with *inline markup*
|
||||
|
||||
: Definition 2
|
||||
|
||||
{ some code, part of Definition 2 }
|
||||
|
||||
Third paragraph of definition 2.
|
||||
|
||||
_Compact style:_
|
||||
|
||||
Term 1
|
||||
~ Definition 1
|
||||
|
||||
Term 2
|
||||
~ Definition 2a
|
||||
~ Definition 2b
|
||||
|
||||
|
||||
### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
|
||||
|
||||
This is HTML abbreviation example.
|
||||
|
||||
It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
|
||||
|
||||
*[HTML]: Hyper Text Markup Language
|
||||
|
||||
### [Custom containers](https://github.com/markdown-it/markdown-it-container)
|
||||
|
21
w/m/TestMd/meta.json
Normal file
21
w/m/TestMd/meta.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": [
|
||||
""
|
||||
],
|
||||
"name": "TestMd",
|
||||
"comment": "Update TestMd",
|
||||
"author": "",
|
||||
"time": 1593340713,
|
||||
"text_mime": "text/markdown",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.markdown",
|
||||
"binary_name": ""
|
||||
}
|
||||
},
|
||||
"Invalid": false,
|
||||
"Err": null
|
||||
}
|
Loading…
Reference in New Issue
Block a user