mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-10-30 03:36:16 +00:00
Implement some features of mycomarkup
This commit is contained in:
parent
657fb5d357
commit
d6c6ad4ae3
@ -4,8 +4,13 @@ A wiki engine.
|
||||
This is the development branch for version 0.10. Features planned for this version:
|
||||
* [x] New file structure
|
||||
* [ ] Mycomarkup
|
||||
* [x] 6 headings
|
||||
* [x] Paragraph styling
|
||||
* [ ] Inline links
|
||||
* [ ] Better lists
|
||||
* [ ] Better quotes
|
||||
* [x] CLI options
|
||||
* [ ] CSS improvements
|
||||
* [x] CSS improvements
|
||||
|
||||
## Building
|
||||
```sh
|
||||
|
@ -77,7 +77,7 @@ func (hop *HistoryOp) WithFilesRenamed(pairs map[string]string) *HistoryOp {
|
||||
for from, to := range pairs {
|
||||
if from != "" {
|
||||
os.MkdirAll(filepath.Dir(to), 0777)
|
||||
hop.gitop(append([]string{"mv"}, from, to)...)
|
||||
Rename(from, to)
|
||||
}
|
||||
}
|
||||
return hop
|
||||
|
@ -118,7 +118,7 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) {
|
||||
} else {
|
||||
warning = `<p>You are creating a new hypha.</p>`
|
||||
}
|
||||
util.HTTP200Page(w, base("Edit"+hyphaName, templates.EditHTML(hyphaName, textAreaFill, warning)))
|
||||
util.HTTP200Page(w, base("Edit "+hyphaName, templates.EditHTML(hyphaName, textAreaFill, warning)))
|
||||
}
|
||||
|
||||
// handlerUploadText uploads a new text part for the hypha.
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/gemtext"
|
||||
"github.com/bouncepaw/mycorrhiza/history"
|
||||
"github.com/bouncepaw/mycorrhiza/markup"
|
||||
"github.com/bouncepaw/mycorrhiza/templates"
|
||||
"github.com/bouncepaw/mycorrhiza/tree"
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
@ -37,7 +37,7 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
|
||||
textContents, err = history.FileAtRevision(textPath, revHash)
|
||||
)
|
||||
if err == nil {
|
||||
contents = gemtext.ToHtml(hyphaName, textContents)
|
||||
contents = markup.ToHtml(hyphaName, textContents)
|
||||
}
|
||||
page := templates.RevisionHTML(
|
||||
hyphaName,
|
||||
@ -104,7 +104,7 @@ func handlerPage(w http.ResponseWriter, rq *http.Request) {
|
||||
fileContentsT, errT := ioutil.ReadFile(data.textPath)
|
||||
_, errB := os.Stat(data.binaryPath)
|
||||
if errT == nil {
|
||||
contents = gemtext.ToHtml(hyphaName, string(fileContentsT))
|
||||
contents = markup.ToHtml(hyphaName, string(fileContentsT))
|
||||
}
|
||||
if !os.IsNotExist(errB) {
|
||||
contents = binaryHtmlBlock(hyphaName, data) + contents
|
||||
|
6
hypha.go
6
hypha.go
@ -10,17 +10,17 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/gemtext"
|
||||
"github.com/bouncepaw/mycorrhiza/history"
|
||||
"github.com/bouncepaw/mycorrhiza/markup"
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gemtext.HyphaExists = func(hyphaName string) bool {
|
||||
markup.HyphaExists = func(hyphaName string) bool {
|
||||
_, hyphaExists := HyphaStorage[hyphaName]
|
||||
return hyphaExists
|
||||
}
|
||||
gemtext.HyphaAccess = func(hyphaName string) (rawText, binaryBlock string, err error) {
|
||||
markup.HyphaAccess = func(hyphaName string) (rawText, binaryBlock string, err error) {
|
||||
if hyphaData, ok := HyphaStorage[hyphaName]; ok {
|
||||
rawText, err = FetchTextPart(hyphaData)
|
||||
if hyphaData.binaryPath != "" {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package gemtext
|
||||
package markup
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -13,7 +13,7 @@ var HyphaExists func(string) bool
|
||||
// HyphaAccess holds function that accesses a hypha by its name.
|
||||
var HyphaAccess func(string) (rawText, binaryHtml string, err error)
|
||||
|
||||
// GemLexerState is used by gemtext parser to remember what is going on.
|
||||
// GemLexerState is used by markup parser to remember what is going on.
|
||||
type GemLexerState struct {
|
||||
// Name of hypha being parsed
|
||||
name string
|
||||
@ -29,7 +29,7 @@ type Line struct {
|
||||
contents interface{}
|
||||
}
|
||||
|
||||
// Parse gemtext line starting with "=>" according to wikilink rules.
|
||||
// Parse markup line starting with "=>" according to wikilink rules.
|
||||
// See http://localhost:1737/page/wikilink
|
||||
func wikilink(src string, state *GemLexerState) (href, text, class string) {
|
||||
src = strings.TrimSpace(remover("=>")(src))
|
||||
@ -79,7 +79,7 @@ func lex(name, content string) (ast []Line) {
|
||||
return ast
|
||||
}
|
||||
|
||||
// Lex `line` in gemtext and save it to `ast` using `state`.
|
||||
// Lex `line` in markup and save it to `ast` using `state`.
|
||||
func geminiLineToAST(line string, state *GemLexerState, ast *[]Line) {
|
||||
addLine := func(text interface{}) {
|
||||
*ast = append(*ast, Line{id: state.id, contents: text})
|
||||
@ -142,20 +142,29 @@ normalState:
|
||||
case startsWith("```"):
|
||||
state.where = "pre"
|
||||
state.buf = fmt.Sprintf("<pre id='%d' alt='%s' class='codeblock'><code>", state.id, strings.TrimPrefix(line, "```"))
|
||||
case startsWith("*"):
|
||||
case startsWith("* "):
|
||||
state.where = "list"
|
||||
state.buf = fmt.Sprintf("<ul id='%d'>\n", state.id)
|
||||
goto listState
|
||||
|
||||
case startsWith("###"):
|
||||
case startsWith("###### "):
|
||||
addLine(fmt.Sprintf(
|
||||
"<h3 id='%d'>%s</h3>", state.id, removeHeadingOctothorps(line)))
|
||||
case startsWith("##"):
|
||||
"<h6 id='%d'>%s</h6>", state.id, line[7:]))
|
||||
case startsWith("##### "):
|
||||
addLine(fmt.Sprintf(
|
||||
"<h2 id='%d'>%s</h2>", state.id, removeHeadingOctothorps(line)))
|
||||
case startsWith("#"):
|
||||
"<h5 id='%d'>%s</h5>", state.id, line[6:]))
|
||||
case startsWith("#### "):
|
||||
addLine(fmt.Sprintf(
|
||||
"<h1 id='%d'>%s</h1>", state.id, removeHeadingOctothorps(line)))
|
||||
"<h4 id='%d'>%s</h4>", state.id, line[5:]))
|
||||
case startsWith("### "):
|
||||
addLine(fmt.Sprintf(
|
||||
"<h3 id='%d'>%s</h3>", state.id, line[4:]))
|
||||
case startsWith("## "):
|
||||
addLine(fmt.Sprintf(
|
||||
"<h2 id='%d'>%s</h2>", state.id, line[3:]))
|
||||
case startsWith("# "):
|
||||
addLine(fmt.Sprintf(
|
||||
"<h1 id='%d'>%s</h1>", state.id, line[2:]))
|
||||
|
||||
case startsWith(">"):
|
||||
addLine(fmt.Sprintf(
|
||||
@ -168,6 +177,6 @@ normalState:
|
||||
case startsWith("<="):
|
||||
addLine(parseTransclusion(line, state.name))
|
||||
default:
|
||||
addLine(fmt.Sprintf("<p id='%d'>%s</p>", state.id, line))
|
||||
addLine(fmt.Sprintf("<p id='%d'>%s</p>", state.id, ParagraphToHtml(line)))
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package gemtext
|
||||
package markup
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TODO: move test gemtext docs to files, perhaps? These strings sure are ugly
|
||||
// TODO: move test markup docs to files, perhaps? These strings sure are ugly
|
||||
func TestLex(t *testing.T) {
|
||||
check := func(name, content string, expectedAst []Line) {
|
||||
if ast := lex(name, content); !reflect.DeepEqual(ast, expectedAst) {
|
||||
@ -25,9 +25,9 @@ func TestLex(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
contentsB, err := ioutil.ReadFile("testdata/test.gmi")
|
||||
contentsB, err := ioutil.ReadFile("testdata/test.myco")
|
||||
if err != nil {
|
||||
t.Error("Could not read test gemtext file!")
|
||||
t.Error("Could not read test markup file!")
|
||||
}
|
||||
contents := string(contentsB)
|
||||
check("Apple", contents, []Line{
|
||||
@ -46,7 +46,7 @@ func TestLex(t *testing.T) {
|
||||
<li>li\n"+</li>
|
||||
</ul>`},
|
||||
{10, `<pre id='10' alt='alt text goes here' class='codeblock'><code>=> preformatted text
|
||||
where gemtext is not lexed</code></pre>`},
|
||||
where markup is not lexed</code></pre>`},
|
||||
{11, `<p><a id='11' class='wikilink_internal' href="/page/linking">linking</a></p>`},
|
||||
{12, "<p id='12'>text</p>"},
|
||||
{13, `<pre id='13' alt='' class='codeblock'><code>()
|
102
markup/mycomarkup.go
Normal file
102
markup/mycomarkup.go
Normal file
@ -0,0 +1,102 @@
|
||||
// This is not done yet
|
||||
package markup
|
||||
|
||||
import (
|
||||
"html"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Mycomarkup-formatted document
|
||||
type MycoDoc struct {
|
||||
// data
|
||||
hyphaName string
|
||||
contents string
|
||||
|
||||
// state
|
||||
recursionDepth int
|
||||
|
||||
// results
|
||||
}
|
||||
|
||||
// Constructor
|
||||
func Doc(hyphaName, contents string) *MycoDoc {
|
||||
return &MycoDoc{
|
||||
hyphaName: hyphaName,
|
||||
contents: contents,
|
||||
}
|
||||
}
|
||||
|
||||
// AsHtml returns an html representation of the document
|
||||
func (md *MycoDoc) AsHtml() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type BlockType int
|
||||
|
||||
const (
|
||||
BlockH1 = iota
|
||||
BlockH2
|
||||
BlockH3
|
||||
BlockH4
|
||||
BlockH5
|
||||
BlockH6
|
||||
BlockRocket
|
||||
BlockPre
|
||||
BlockQuote
|
||||
BlockPara
|
||||
)
|
||||
|
||||
type CrawlWhere int
|
||||
|
||||
const (
|
||||
inSomewhere = iota
|
||||
inPre
|
||||
inEnd
|
||||
)
|
||||
|
||||
func crawl(name, content string) []string {
|
||||
stateStack := []CrawlWhere{inSomewhere}
|
||||
|
||||
startsWith := func(token string) bool {
|
||||
return strings.HasPrefix(content, token)
|
||||
}
|
||||
|
||||
pop := func() {
|
||||
stateStack = stateStack[:len(stateStack)-1]
|
||||
}
|
||||
|
||||
push := func(s CrawlWhere) {
|
||||
stateStack = append(stateStack, s)
|
||||
}
|
||||
|
||||
readln := func(c string) (string, string) {
|
||||
parts := strings.SplitN(c, "\n", 1)
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
|
||||
preAcc := ""
|
||||
line := ""
|
||||
|
||||
for {
|
||||
switch stateStack[0] {
|
||||
case inSomewhere:
|
||||
switch {
|
||||
case startsWith("```"):
|
||||
push(inPre)
|
||||
_, content = readln(content)
|
||||
default:
|
||||
}
|
||||
case inPre:
|
||||
switch {
|
||||
case startsWith("```"):
|
||||
pop()
|
||||
_, content = readln(content)
|
||||
default:
|
||||
line, content = readln(content)
|
||||
preAcc += html.EscapeString(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
108
markup/paragraph.go
Normal file
108
markup/paragraph.go
Normal file
@ -0,0 +1,108 @@
|
||||
package markup
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type spanTokenType int
|
||||
|
||||
const (
|
||||
spanTextNode = iota
|
||||
spanItalic
|
||||
spanBold
|
||||
spanMono
|
||||
spanSuper
|
||||
spanSub
|
||||
spanMark
|
||||
)
|
||||
|
||||
func tagFromState(stt spanTokenType, tagState map[spanTokenType]bool, tagName, originalForm string) string {
|
||||
if tagState[spanMono] && (stt != spanMono) {
|
||||
return originalForm
|
||||
}
|
||||
if tagState[stt] {
|
||||
tagState[stt] = false
|
||||
return fmt.Sprintf("</%s>", tagName)
|
||||
} else {
|
||||
tagState[stt] = true
|
||||
return fmt.Sprintf("<%s>", tagName)
|
||||
}
|
||||
}
|
||||
|
||||
// getTextNode splits the `p` into two parts `textNode` and `rest` by the first encountered rune that resembles a span tag. If there is none, `textNode = p`, `rest = ""`. It handles escaping with backslash.
|
||||
func getTextNode(input *bytes.Buffer) string {
|
||||
var (
|
||||
textNodeBuffer = bytes.Buffer{}
|
||||
escaping = false
|
||||
)
|
||||
// Always read the first byte in advance to avoid endless loops that kill computers (sad experience)
|
||||
if input.Len() != 0 {
|
||||
b, _ := input.ReadByte()
|
||||
textNodeBuffer.WriteByte(b)
|
||||
}
|
||||
for input.Len() != 0 {
|
||||
// Assume no error is possible because we check for length
|
||||
b, _ := input.ReadByte()
|
||||
if escaping {
|
||||
textNodeBuffer.WriteByte(b)
|
||||
escaping = false
|
||||
} else if b == '\\' {
|
||||
escaping = true
|
||||
} else if strings.IndexByte("/*`^,!", b) >= 0 {
|
||||
input.UnreadByte()
|
||||
break
|
||||
} else {
|
||||
textNodeBuffer.WriteByte(b)
|
||||
}
|
||||
}
|
||||
return textNodeBuffer.String()
|
||||
}
|
||||
|
||||
func ParagraphToHtml(input string) string {
|
||||
var (
|
||||
p = bytes.NewBufferString(input)
|
||||
ret strings.Builder
|
||||
// true = tag is opened, false = tag is not opened
|
||||
tagState = map[spanTokenType]bool{
|
||||
spanItalic: false,
|
||||
spanBold: false,
|
||||
spanMono: false,
|
||||
spanSuper: false,
|
||||
spanSub: false,
|
||||
spanMark: false,
|
||||
}
|
||||
startsWith = func(t string) bool {
|
||||
return bytes.HasPrefix(p.Bytes(), []byte(t))
|
||||
}
|
||||
)
|
||||
|
||||
for p.Len() != 0 {
|
||||
switch {
|
||||
case startsWith("//"):
|
||||
ret.WriteString(tagFromState(spanItalic, tagState, "em", "//"))
|
||||
p.Next(2)
|
||||
case startsWith("**"):
|
||||
ret.WriteString(tagFromState(spanBold, tagState, "strong", "**"))
|
||||
p.Next(2)
|
||||
case startsWith("`"):
|
||||
ret.WriteString(tagFromState(spanMono, tagState, "code", "`"))
|
||||
p.Next(1)
|
||||
case startsWith("^"):
|
||||
ret.WriteString(tagFromState(spanSuper, tagState, "sup", "^"))
|
||||
p.Next(1)
|
||||
case startsWith(",,"):
|
||||
ret.WriteString(tagFromState(spanSub, tagState, "sub", ",,"))
|
||||
p.Next(2)
|
||||
case startsWith("!!"):
|
||||
ret.WriteString(tagFromState(spanMark, tagState, "mark", "!!"))
|
||||
p.Next(2)
|
||||
default:
|
||||
ret.WriteString(html.EscapeString(getTextNode(p)))
|
||||
}
|
||||
}
|
||||
|
||||
return ret.String()
|
||||
}
|
44
markup/paragraph_test.go
Normal file
44
markup/paragraph_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package markup
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
/*
|
||||
func TestGetTextNode(t *testing.T) {
|
||||
tests := [][]string{
|
||||
// input textNode rest
|
||||
{"barab", "barab", ""},
|
||||
{"test, ", "test", ", "},
|
||||
{"/test/", "", "/test/"},
|
||||
{"\\/test/", "/test", "/"},
|
||||
{"test \\/ar", "test /ar", ""},
|
||||
{"test //italian// test", "test ", "//italian// test"},
|
||||
}
|
||||
for _, triplet := range tests {
|
||||
a, b := getTextNode([]byte(triplet[0]))
|
||||
if a != triplet[1] || string(b) != triplet[2] {
|
||||
t.Error(fmt.Sprintf("Wanted: %q\nGot: %q %q", triplet, a, b))
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func TestParagraphToHtml(t *testing.T) {
|
||||
tests := [][]string{
|
||||
{"a simple paragraph", "a simple paragraph"},
|
||||
{"//italic//", "<em>italic</em>"},
|
||||
{"Embedded //italic//", "Embedded <em>italic</em>"},
|
||||
{"double //italian// //text//", "double <em>italian</em> <em>text</em>"},
|
||||
{"it has `mono`", "it has <code>mono</code>"},
|
||||
{"this is a left **bold", "this is a left <strong>bold"},
|
||||
{"this line has a ,comma, two of them", "this line has a ,comma, two of them"},
|
||||
{"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if ParagraphToHtml(test[0]) != test[1] {
|
||||
t.Error(fmt.Sprintf("%q: Wanted %q, got %q", test[0], test[1], ParagraphToHtml(test[0])))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package gemtext
|
||||
package markup
|
||||
|
||||
import ()
|
||||
|
@ -12,7 +12,7 @@ more text
|
||||
* li\n"+
|
||||
```alt text goes here
|
||||
=> preformatted text
|
||||
where gemtext is not lexed
|
||||
where markup is not lexed
|
||||
```it ends here"
|
||||
=>linking
|
||||
|
@ -1,4 +1,4 @@
|
||||
package gemtext
|
||||
package markup
|
||||
|
||||
import (
|
||||
"strings"
|
@ -1,4 +1,4 @@
|
||||
package gemtext
|
||||
package markup
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -9,7 +9,7 @@ import (
|
||||
|
||||
const xclError = -9
|
||||
|
||||
// Transclusion is used by gemtext parser to remember what hyphae shall be transcluded.
|
||||
// Transclusion is used by markup parser to remember what hyphae shall be transcluded.
|
||||
type Transclusion struct {
|
||||
name string
|
||||
from int // inclusive
|
@ -1,4 +1,4 @@
|
||||
package gemtext
|
||||
package markup
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
func TestParseTransclusion(t *testing.T) {
|
||||
check := func(line string, expectedXclusion Transclusion) {
|
||||
if xcl := parseTransclusion(line); xcl != expectedXclusion {
|
||||
if xcl := parseTransclusion(line, "t"); xcl != expectedXclusion {
|
||||
t.Error(line, "; got:", xcl, "wanted:", expectedXclusion)
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 46cc59eeca16e873b47fdda84009adabb4e82d2b
|
||||
Subproject commit 58d000edaa4f06586accc6199190ca69bebf2ad4
|
@ -9,17 +9,21 @@
|
||||
html {height:100%; padding:0; background-color:#ddd;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='42' height='44' viewBox='0 0 42 44' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='Page-1' fill='none' fill-rule='evenodd'%3E%3Cg id='brick-wall' fill='%23bbbbbb' fill-opacity='0.4'%3E%3Cpath d='M0 0h42v44H0V0zm1 1h40v20H1V1zM0 23h20v20H0V23zm22 0h20v20H22V23z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");} /* heropatterns.com */
|
||||
body {height:100%; margin:0; font-size:16px; font-family:sans-serif;}
|
||||
main {padding:1rem; background-color: white; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2);}
|
||||
main {padding:1rem; background-color: white; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2); }
|
||||
main > form {margin-bottom:1rem;}
|
||||
textarea {font-size:15px;}
|
||||
.upload-text-form {height:90%;}
|
||||
.upload-text-form textarea {width:100%;height:90%;}
|
||||
.edit {height:100%;}
|
||||
.edit-form {height:90%;}
|
||||
.edit-form textarea {width:100%;height:90%;}
|
||||
|
||||
main h1:not(.navi-title) {font-size:1.7rem;}
|
||||
blockquote {border-left: 4px black solid; margin-left: 0; padding-left: 1rem;}
|
||||
.wikilink_new {color:#a55858;}
|
||||
.wikilink_new:visited {color:#a55858;}
|
||||
.wikilink_external::after {content:"🌐"; margin-left: .5rem; font-size: small; text-decoration: none; align: bottom;}
|
||||
p code {background-color:#eee; padding: .1rem .3rem; border-radius: .25rem; font-size: 90%; }
|
||||
.codeblock {background-color:#eee; padding:.5rem; font-size:16px; white-space: pre-wrap;}
|
||||
.transclusion .codeblock {background-color:#ddd;}
|
||||
.transclusion code, .transclusion .codeblock {background-color:#ddd;}
|
||||
.transclusion {background-color:#eee; padding:0 0 0 1.5rem;}
|
||||
.transclusion__link {display: block; position: absolute; transform-origin: 0 0; transform: rotate(90deg); margin-top: 0.5rem; color: black; text-decoration: none;}
|
||||
|
||||
|
@ -31,17 +31,21 @@ func StreamDefaultCSS(qw422016 *qt422016.Writer) {
|
||||
html {height:100%; padding:0; background-color:#ddd;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='42' height='44' viewBox='0 0 42 44' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='Page-1' fill='none' fill-rule='evenodd'%3E%3Cg id='brick-wall' fill='%23bbbbbb' fill-opacity='0.4'%3E%3Cpath d='M0 0h42v44H0V0zm1 1h40v20H1V1zM0 23h20v20H0V23zm22 0h20v20H22V23z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");} /* heropatterns.com */
|
||||
body {height:100%; margin:0; font-size:16px; font-family:sans-serif;}
|
||||
main {padding:1rem; background-color: white; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2);}
|
||||
main {padding:1rem; background-color: white; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2); }
|
||||
main > form {margin-bottom:1rem;}
|
||||
textarea {font-size:15px;}
|
||||
.upload-text-form {height:90%;}
|
||||
.upload-text-form textarea {width:100%;height:90%;}
|
||||
.edit {height:100%;}
|
||||
.edit-form {height:90%;}
|
||||
.edit-form textarea {width:100%;height:90%;}
|
||||
|
||||
main h1:not(.navi-title) {font-size:1.7rem;}
|
||||
blockquote {border-left: 4px black solid; margin-left: 0; padding-left: 1rem;}
|
||||
.wikilink_new {color:#a55858;}
|
||||
.wikilink_new:visited {color:#a55858;}
|
||||
.wikilink_external::after {content:"🌐"; margin-left: .5rem; font-size: small; text-decoration: none; align: bottom;}
|
||||
p code {background-color:#eee; padding: .1rem .3rem; border-radius: .25rem; font-size: 90%; }
|
||||
.codeblock {background-color:#eee; padding:.5rem; font-size:16px; white-space: pre-wrap;}
|
||||
.transclusion .codeblock {background-color:#ddd;}
|
||||
.transclusion code, .transclusion .codeblock {background-color:#ddd;}
|
||||
.transclusion {background-color:#eee; padding:0 0 0 1.5rem;}
|
||||
.transclusion__link {display: block; position: absolute; transform-origin: 0 0; transform: rotate(90deg); margin-top: 0.5rem; color: black; text-decoration: none;}
|
||||
|
||||
@ -55,31 +59,31 @@ nav ul li {list-style-type:none;margin-right:1rem;}
|
||||
|
||||
#new-name {width:100%;}
|
||||
`)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
}
|
||||
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
func WriteDefaultCSS(qq422016 qtio422016.Writer) {
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
StreamDefaultCSS(qw422016)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
}
|
||||
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
func DefaultCSS() string {
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
WriteDefaultCSS(qb422016)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
qs422016 := string(qb422016.B)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
return qs422016
|
||||
//line templates/css.qtpl:35
|
||||
//line templates/css.qtpl:39
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{% func EditHTML(hyphaName, textAreaFill, warning string) %}
|
||||
<main>
|
||||
<main class="edit">
|
||||
<h1>Edit {%s hyphaName %}</h1>
|
||||
{%s= warning %}
|
||||
<form method="post" class="upload-text-form"
|
||||
<form method="post" class="edit-form"
|
||||
action="/upload-text/{%s hyphaName %}">
|
||||
<textarea name="text">{%s textAreaFill %}</textarea>
|
||||
<br/>
|
||||
|
@ -21,7 +21,7 @@ var (
|
||||
func StreamEditHTML(qw422016 *qt422016.Writer, hyphaName, textAreaFill, warning string) {
|
||||
//line templates/http_mutators.qtpl:1
|
||||
qw422016.N().S(`
|
||||
<main>
|
||||
<main class="edit">
|
||||
<h1>Edit `)
|
||||
//line templates/http_mutators.qtpl:3
|
||||
qw422016.E().S(hyphaName)
|
||||
@ -32,7 +32,7 @@ func StreamEditHTML(qw422016 *qt422016.Writer, hyphaName, textAreaFill, warning
|
||||
qw422016.N().S(warning)
|
||||
//line templates/http_mutators.qtpl:4
|
||||
qw422016.N().S(`
|
||||
<form method="post" class="upload-text-form"
|
||||
<form method="post" class="edit-form"
|
||||
action="/upload-text/`)
|
||||
//line templates/http_mutators.qtpl:6
|
||||
qw422016.E().S(hyphaName)
|
||||
|
Loading…
Reference in New Issue
Block a user