mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-01-19 07:02:51 +00:00
commit
de9a837bc6
@ -1,7 +1,134 @@
|
||||
package parser
|
||||
|
||||
import ()
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
)
|
||||
|
||||
const (
|
||||
linkToken = "=>"
|
||||
headerToken = "#"
|
||||
quoteToken = ">"
|
||||
preformattedToken = "```"
|
||||
listItemToken = "*"
|
||||
)
|
||||
|
||||
var preState bool
|
||||
var listState bool
|
||||
|
||||
func GeminiToHtml(gemini []byte) string {
|
||||
return ""
|
||||
lines, _ := StringToLines(string(util.NormalizeEOL(gemini)))
|
||||
var html []string
|
||||
|
||||
for _, line := range lines {
|
||||
html = append(html, geminiLineToHtml(line))
|
||||
}
|
||||
|
||||
buffer := bytes.Buffer{}
|
||||
for _, line := range html {
|
||||
buffer.WriteString(line)
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func geminiLineToHtml(line string) (res string) {
|
||||
arr := strings.Fields(line)
|
||||
token := checkLineType(arr)
|
||||
|
||||
switch token {
|
||||
case headerToken:
|
||||
level, content := makeOutHeader(arr)
|
||||
res = fmt.Sprintf("<h%v>%v</h%v>", level, content, level)
|
||||
case linkToken:
|
||||
source, content := makeOutLink(arr[1:])
|
||||
res = fmt.Sprintf(`<a href="%v">%v</a>`, source, content)
|
||||
case quoteToken:
|
||||
res = "<blockquote>" + LinesToString(arr[1:], " ") + "</blockquote>"
|
||||
case preformattedToken:
|
||||
preState = true
|
||||
res = fmt.Sprintf(`<pre alt="%v">`, LinesToString(arr[1:], " "))
|
||||
case "pre/empty":
|
||||
res = "\n"
|
||||
case "pre/text":
|
||||
res = line + "\n"
|
||||
case "pre/end":
|
||||
preState = false
|
||||
res = "</pre>"
|
||||
case "list/begin":
|
||||
res = "<ul><li>" + LinesToString(arr[1:], " ") + "</li>"
|
||||
case listItemToken:
|
||||
res = "<li>" + LinesToString(arr[1:], " ") + "</li>"
|
||||
case "list/end":
|
||||
listState = false
|
||||
res = "</ul>" + geminiLineToHtml(line)
|
||||
case "linebreak":
|
||||
res = "<br>"
|
||||
default:
|
||||
res = "<p>" + line + "</p>"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func makeOutLink(arr []string) (source, content string) {
|
||||
switch len(arr) {
|
||||
case 0:
|
||||
return "", ""
|
||||
case 1:
|
||||
return arr[0], arr[0]
|
||||
default:
|
||||
return arr[0], LinesToString(arr[1:], " ")
|
||||
}
|
||||
}
|
||||
|
||||
func makeOutHeader(arr []string) (level int, content string) {
|
||||
level = len(arr[0])
|
||||
content = LinesToString(arr[1:], " ")
|
||||
return
|
||||
}
|
||||
|
||||
func checkLineType(arr []string) (res string) {
|
||||
isEmpty := len(arr) == 0
|
||||
if preState {
|
||||
if isEmpty {
|
||||
res = "pre/empty"
|
||||
} else if arr[0] == preformattedToken {
|
||||
res = "pre/end"
|
||||
} else {
|
||||
res = "pre/text"
|
||||
}
|
||||
} else if listState {
|
||||
if arr[0] == listItemToken {
|
||||
res = listItemToken
|
||||
} else {
|
||||
res = "list/end"
|
||||
}
|
||||
} else if isEmpty {
|
||||
res = "linebreak"
|
||||
} else if arr[0][0] == headerToken[0] {
|
||||
res = headerToken
|
||||
} else {
|
||||
return arr[0]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func StringToLines(s string) (lines []string, err error) {
|
||||
scanner := bufio.NewScanner(strings.NewReader(s))
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
err = scanner.Err()
|
||||
return
|
||||
}
|
||||
|
||||
func LinesToString(lines []string, separator string) string {
|
||||
buffer := bytes.Buffer{}
|
||||
for _, line := range lines {
|
||||
buffer.WriteString(line + separator)
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
50
wiki/main/testgemini/1.txt
Normal file
50
wiki/main/testgemini/1.txt
Normal file
@ -0,0 +1,50 @@
|
||||
# Gemtext cheatsheet
|
||||
Here's the basics of how text works in Gemtext:
|
||||
|
||||
Long lines get wrapped by the client to fit the screen
|
||||
Short lines *don't* get joined together
|
||||
Write paragraphs as single long lines
|
||||
Blank lines are rendered verbatim
|
||||
You get three levels of heading:
|
||||
|
||||
# Heading
|
||||
## Sub-heading
|
||||
### Sub-subheading
|
||||
You get one kind of list and you can't nest them:
|
||||
|
||||
* Mercury
|
||||
* Gemini
|
||||
* Apollo
|
||||
Here's a quote from Maciej Cegłowski:
|
||||
|
||||
> I contend that text-based websites should not exceed in size the major works of Russian literature.
|
||||
Lines which start with ``` will cause clients to toggle in and out of ordinary rendering mode and preformatted mode. In preformatted mode, Gemtext syntax is ignored so links etc. will not be rendered, and text will appear in a monospace font.
|
||||
``` ALT TEXT
|
||||
.
|
||||
('
|
||||
'|
|
||||
|'
|
||||
[::]
|
||||
[::] _......_
|
||||
[::].-' _.-`.
|
||||
[:.' .-. '-._.-`.
|
||||
[/ /\ | \ `-..
|
||||
/ / | `-.' .-. `-.
|
||||
/ `-' ( `. `.
|
||||
| /\ `-._/ \
|
||||
' .'\ / `. _.-'|
|
||||
/ / / \_.-' _.':;:/
|
||||
.' \_/ _.-':;_.-'
|
||||
/ .-. _.-' \;.-'
|
||||
/ ( \ _..-' |
|
||||
\ `._/ _..-' .--. |
|
||||
`-.....-'/ _ _ .' '.|
|
||||
| |_|_| | | \ (o)
|
||||
(o) | |_|_| | | | (\'/)
|
||||
(\'/)/ ''''' | o| \;:;
|
||||
:; | | | |/)
|
||||
;: `-.._ /__..--'\.' ;:
|
||||
:; `--' :; :;
|
||||
```
|
||||
=> https://proxy.vulpes.one/gemini/gemini.circumlunar.space/docs/cheatsheet.gmi Original cheatsheet
|
||||
=> https://proxy.vulpes.one/gemini/gemini.circumlunar.space/docs/cheatsheet.gmi
|
17
wiki/main/testgemini/meta.json
Normal file
17
wiki/main/testgemini/meta.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"views": 0,
|
||||
"deleted": false,
|
||||
"revisions": {
|
||||
"1": {
|
||||
"tags": null,
|
||||
"name": "Testgemini",
|
||||
"comment": "Create :Main/Testgemini",
|
||||
"author": "",
|
||||
"time": 1593960824,
|
||||
"text_mime": "text/gemini",
|
||||
"binary_mime": "",
|
||||
"text_name": "1.txt",
|
||||
"binary_name": ""
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user