mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-13 05:50:27 +00:00
Gemini parser rework
This commit is contained in:
parent
0d9a677aca
commit
0f8f819185
@ -1,7 +1,9 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
@ -15,12 +17,17 @@ const (
|
||||
listItemToken = "*"
|
||||
)
|
||||
|
||||
var preState bool
|
||||
var listState bool
|
||||
|
||||
func GeminiToHtml(gemini []byte) string {
|
||||
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)
|
||||
@ -30,29 +37,40 @@ func GeminiToHtml(gemini []byte) string {
|
||||
|
||||
func geminiLineToHtml(line string) (res string) {
|
||||
arr := strings.Fields(line)
|
||||
if len(arr) == 0 {
|
||||
return lineBreak
|
||||
}
|
||||
|
||||
content := arr[1:]
|
||||
token := arr[0]
|
||||
if string(token[0]) == headerToken {
|
||||
return makeHeader(makeOutHeader(arr))
|
||||
}
|
||||
token := checkLineType(arr)
|
||||
|
||||
switch token {
|
||||
case headerToken:
|
||||
level, content := makeOutHeader(arr)
|
||||
res = fmt.Sprintf("<h%v>%v</h%v>", level, content, level)
|
||||
case linkToken:
|
||||
res = makeLink(makeOutLink(content))
|
||||
source, content := makeOutLink(arr[1:])
|
||||
res = fmt.Sprintf(`<a href="%v">%v</a>`, source, content)
|
||||
case quoteToken:
|
||||
res = makeBlockQuote(LinesToString(content, " "))
|
||||
res = "<blockquote>" + LinesToString(arr[1:], " ") + "</blockquote>"
|
||||
case preformattedToken:
|
||||
res = makePreformatted(LinesToString(content, " "))
|
||||
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 = makeListItem(LinesToString(content, " "))
|
||||
res = "<li>" + LinesToString(arr[1:], " ") + "</li>"
|
||||
case "list/end":
|
||||
listState = false
|
||||
res = "</ul>" + geminiLineToHtml(line)
|
||||
case "linebreak":
|
||||
res = "<br>"
|
||||
default:
|
||||
res = makeParagraph(line)
|
||||
res = "<p>" + line + "</p>"
|
||||
}
|
||||
return res
|
||||
return
|
||||
}
|
||||
|
||||
func makeOutLink(arr []string) (source, content string) {
|
||||
@ -71,3 +89,46 @@ func makeOutHeader(arr []string) (level int, content string) {
|
||||
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()
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
lineBreak = "<br>"
|
||||
)
|
||||
|
||||
func makeLink(source, content string) string {
|
||||
return fmt.Sprintf(`<a href="%v">%v</a>`, source, content)
|
||||
}
|
||||
|
||||
func makeParagraph(content string) string {
|
||||
return `<p>` + content + `</p>`
|
||||
}
|
||||
|
||||
func makeBlockQuote(content string) string {
|
||||
return `<blockquote>` + content + `</blockquote>`
|
||||
}
|
||||
|
||||
func makeHeader(level int, content string) string {
|
||||
return fmt.Sprintf("<h%v>%v</h%v>", level, content, level)
|
||||
}
|
||||
|
||||
func makePreformatted(content string) string {
|
||||
return "<pre>" + content + "</pre>"
|
||||
}
|
||||
|
||||
func makeListItem(content string) string {
|
||||
return "<li>" + content + "</li>"
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
@ -19,7 +19,32 @@ 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.
|
||||
``` =>https://not-a-href.com preformatted
|
||||
|
||||
``` 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
|
||||
|
Loading…
Reference in New Issue
Block a user