1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-13 05:50:27 +00:00

Redo render

This commit is contained in:
Timur Ismagilov 2020-06-28 20:02:07 +05:00
parent 981f4ae513
commit 9c2846232c
43 changed files with 476 additions and 620 deletions

View File

@ -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]
}

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -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))
}
}

View File

@ -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{
"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)
return layout("edit/index").
withMap(hyphaData).
wrapInBase(map[string]string{
"Title": fmt.Sprintf(cfg.TitleEditTemplate, h.FullName),
"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
}
keys := map[string]string{
"Title": fmt.Sprintf(cfg.TitleTemplate, name),
"Sidebar": sidebar,
}
return renderBase(renderFromString(content, templatePath), keys)
// HyphaPage renders hypha viewer.
func HyphaPage(name, content string) []byte {
return hyphaGeneric(name, content, "view/index")
}
func HyphaUpdateOk(h *fs.Hypha) string {
data := map[string]string{
"Name": h.FullName,
}
return renderFromMap(data, "updateOk.html")
// 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": hyphaTree(name),
})
}
// 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 buf.String()
return &Layout{tmpl, new(bytes.Buffer), false, nil}
}
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
View 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
View 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)
```
фрукты полезны для здоровья!!
```

View File

@ -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,

View File

@ -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": ""
}
}
}

View File

@ -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>

View File

@ -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": ""
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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": ""
}
}
}

View File

@ -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;
}

View File

@ -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": ""
}
}
}

View File

@ -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');
});

View File

@ -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": ""
}
}
}

View File

@ -1,8 +0,0 @@
<html>
<head>
<title>Saved {{ .Name }}</title>
</head>
<body>
<p>Saved successfully. <a href="/{{ .Name }}">Go back</a></p>
</body>
</html>

View File

@ -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": ""
}
}
}

View File

@ -1 +0,0 @@
<h1 class="header__edit-title">Edit {{ . }}</h1>

View File

@ -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": ""
}
}
}

View File

@ -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": ""
}
}
}

View File

@ -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": ""
}
}
}

View File

@ -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 }}

View File

@ -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": ""
}
}
}

View File

@ -1 +1 @@
<h1 class="header__edit-title">Edit {{ . }}</h1>
<h1 class="header__edit-title">Edit {{ . }}</h1>

View File

@ -1,19 +1,19 @@
<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 }}" form="edit-form"/>
<h4>Revision comment</h4>
<p>Please make your comment helpful</p>
<input type="text" name="comment" value="Update {{ .Name }}" form="edit-form"/>
<h4>Edit tags</h4>
<p>Tags are separated by commas, whitespace is ignored</p>
<input type="text" name="tags" value="{{ .Tags }}" form="edit-form"/>
<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" form="edit-form"/>
<p><input type="submit" value="update" form="edit-form"/></p>
</div>
<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 }}" form="edit-form"/>
<h4>Revision comment</h4>
<p>Please make your comment helpful</p>
<input type="text" name="comment" value="Update {{ .Name }}" form="edit-form"/>
<h4>Edit tags</h4>
<p>Tags are separated by commas, whitespace is ignored</p>
<input type="text" name="tags" value="{{ .Tags }}" form="edit-form"/>
<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" form="edit-form"/>
<p><input type="submit" value="update" form="edit-form"/></p>
</div>

View File

@ -1,4 +1,4 @@
<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>
<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>

View File

@ -1,9 +1,9 @@
<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 }}
<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 }}

232
w/m/TestMd/1.markdown Normal file
View 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
View 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
}