Refactor formatters
This commit is contained in:
@@ -23,7 +23,7 @@ func View(cfg *config.Config, w http.ResponseWriter, r *http.Request, params *Pa
|
||||
|
||||
tmpl := util.NewTemplate("view.html")
|
||||
title, _, plain, rendered := format.Apply(cfg, params.DbName, content)
|
||||
summary := format.Summarize(plain, 144)
|
||||
summary := format.TrimForSummary(plain, 144)
|
||||
|
||||
subAction := r.URL.Query().Get("b")
|
||||
diffText := ""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package format
|
||||
|
||||
// TODO
|
||||
func creole(cfg formatConfig, title string, text string) (string, string, string, string) {
|
||||
return nomark(cfg, title, text) // fallback
|
||||
func creole(fc formatConfig, title string, text string) (string, string, string, string) {
|
||||
return nomark(fc, title, text) // fallback
|
||||
}
|
||||
|
||||
@@ -6,40 +6,49 @@ import (
|
||||
"github.com/akikareha/himewiki/internal/config"
|
||||
)
|
||||
|
||||
// Returns title, wiki text, plain text, HTML
|
||||
// Apply applies wiki formatting on input text
|
||||
// and returns title, wiki text, plain text, HTML.
|
||||
func Apply(cfg *config.Config, title string, text string) (string, string, string, string) {
|
||||
if len(text) < 1 {
|
||||
return title, text, text, ""
|
||||
return title, "", "", ""
|
||||
}
|
||||
head := text[0]
|
||||
|
||||
fcfg := toFormatConfig(cfg)
|
||||
fc := toFormatConfig(cfg)
|
||||
|
||||
// Detect markup by very first character of input text.
|
||||
// * '=' : Creole
|
||||
// * '#' : Markdown
|
||||
// * Others : Nomark
|
||||
if head == '=' {
|
||||
return creole(fcfg, title, text)
|
||||
return creole(fc, title, text)
|
||||
} else if head == '#' {
|
||||
return markdown(fcfg, title, text)
|
||||
return markdown(fc, title, text)
|
||||
} else {
|
||||
return nomark(fcfg, title, text)
|
||||
return nomark(fc, title, text)
|
||||
}
|
||||
}
|
||||
|
||||
func Summarize(s string, n int) string {
|
||||
if n < 2 {
|
||||
// TrimForSummary trims text to specified length with ellipsis.
|
||||
// Spaces are compressed.
|
||||
func TrimForSummary(text string, length int) string {
|
||||
if length < 0 {
|
||||
panic("program error")
|
||||
}
|
||||
if length < 1 {
|
||||
return ""
|
||||
}
|
||||
if length < 2 {
|
||||
return "."
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
long := false
|
||||
var buf strings.Builder
|
||||
overflowed := false
|
||||
space := false
|
||||
i := 0
|
||||
for _, r := range s {
|
||||
if i >= n-2 {
|
||||
long = true
|
||||
for _, r := range text {
|
||||
if i >= length-2 {
|
||||
overflowed = true
|
||||
break
|
||||
}
|
||||
if r == '\r' || r == '\n' || r == '\t' {
|
||||
@@ -52,13 +61,13 @@ func Summarize(s string, n int) string {
|
||||
} else {
|
||||
space = false
|
||||
}
|
||||
b.WriteRune(r)
|
||||
buf.WriteRune(r)
|
||||
i++
|
||||
}
|
||||
|
||||
if long {
|
||||
return b.String() + ".."
|
||||
if overflowed {
|
||||
return buf.String() + ".."
|
||||
} else {
|
||||
return b.String()
|
||||
return buf.String()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package format
|
||||
|
||||
// TODO
|
||||
func markdown(cfg formatConfig, title string, text string) (string, string, string, string) {
|
||||
return nomark(cfg, title, text) // fallback
|
||||
func markdown(fc formatConfig, title string, text string) (string, string, string, string) {
|
||||
return nomark(fc, title, text) // fallback
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func ensureBlock(s *state, block blockMode) {
|
||||
openBlock(s, block)
|
||||
}
|
||||
|
||||
func math(cfg formatConfig, s *state) bool {
|
||||
func math(fc formatConfig, s *state) bool {
|
||||
line := s.input[s.index:s.lineEnd]
|
||||
if !strings.HasPrefix(line, "%%") {
|
||||
return false
|
||||
@@ -231,7 +231,7 @@ func math(cfg formatConfig, s *state) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func strong(cfg formatConfig, s *state) bool {
|
||||
func strong(fc formatConfig, s *state) bool {
|
||||
line := s.input[s.index:s.lineEnd]
|
||||
if !strings.HasPrefix(line, "**") {
|
||||
return false
|
||||
@@ -266,7 +266,7 @@ func strong(cfg formatConfig, s *state) bool {
|
||||
}
|
||||
s.index += 2
|
||||
|
||||
markup(cfg, s)
|
||||
markup(fc, s)
|
||||
|
||||
if s.innerDeco == decoStrong {
|
||||
s.html.WriteString("</strong>")
|
||||
@@ -287,7 +287,7 @@ func strong(cfg formatConfig, s *state) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func em(cfg formatConfig, s *state) bool {
|
||||
func em(fc formatConfig, s *state) bool {
|
||||
line := s.input[s.index:s.lineEnd]
|
||||
if !strings.HasPrefix(line, "//") {
|
||||
return false
|
||||
@@ -322,7 +322,7 @@ func em(cfg formatConfig, s *state) bool {
|
||||
}
|
||||
s.index += 2
|
||||
|
||||
markup(cfg, s)
|
||||
markup(fc, s)
|
||||
|
||||
if s.innerDeco == decoEm {
|
||||
s.html.WriteString("</em>")
|
||||
@@ -477,7 +477,7 @@ func nonURLIndex(line string) int {
|
||||
return len(line)
|
||||
}
|
||||
|
||||
func link(cfg formatConfig, s *state) bool {
|
||||
func link(fc formatConfig, s *state) bool {
|
||||
line := s.input[s.index:s.lineEnd]
|
||||
if !strings.HasPrefix(line, "https:") {
|
||||
return false
|
||||
@@ -496,7 +496,7 @@ func link(cfg formatConfig, s *state) bool {
|
||||
ext = ext[1:]
|
||||
}
|
||||
extFound := false
|
||||
for _, extension := range cfg.image.extensions {
|
||||
for _, extension := range fc.image.extensions {
|
||||
if ext == extension {
|
||||
extFound = true
|
||||
break
|
||||
@@ -504,7 +504,7 @@ func link(cfg formatConfig, s *state) bool {
|
||||
}
|
||||
domainFound := false
|
||||
if extFound {
|
||||
for _, domain := range cfg.image.domains {
|
||||
for _, domain := range fc.image.domains {
|
||||
if u.Host == domain {
|
||||
domainFound = true
|
||||
break
|
||||
@@ -616,19 +616,19 @@ func parseHeading(s *state, line string) (int, string, bool) {
|
||||
return level, title, true
|
||||
}
|
||||
|
||||
func markup(cfg formatConfig, s *state) {
|
||||
func markup(fc formatConfig, s *state) {
|
||||
for s.index < s.lineEnd {
|
||||
if math(cfg, s) {
|
||||
if math(fc, s) {
|
||||
continue
|
||||
} else if strong(cfg, s) {
|
||||
} else if strong(fc, s) {
|
||||
continue
|
||||
} else if em(cfg, s) {
|
||||
} else if em(fc, s) {
|
||||
continue
|
||||
} else if camel(s) {
|
||||
continue
|
||||
} else if wikiLink(s) {
|
||||
continue
|
||||
} else if link(cfg, s) {
|
||||
} else if link(fc, s) {
|
||||
continue
|
||||
} else if html(s) {
|
||||
continue
|
||||
@@ -640,7 +640,7 @@ func markup(cfg formatConfig, s *state) {
|
||||
}
|
||||
}
|
||||
|
||||
func nomarkLine(cfg formatConfig, s *state) {
|
||||
func nomarkLine(fc formatConfig, s *state) {
|
||||
line := s.input[s.index:s.lineEnd]
|
||||
|
||||
if s.block == blockCode {
|
||||
@@ -696,6 +696,13 @@ func nomarkLine(cfg formatConfig, s *state) {
|
||||
return
|
||||
}
|
||||
|
||||
if line == "" {
|
||||
ensureBlock(s, blockNone)
|
||||
s.text.WriteString("\n")
|
||||
nextLine(s)
|
||||
return
|
||||
}
|
||||
|
||||
prevBlock := s.block
|
||||
ensureBlock(s, blockParagraph)
|
||||
for s.index < s.lineEnd {
|
||||
@@ -707,7 +714,7 @@ func nomarkLine(cfg formatConfig, s *state) {
|
||||
s.html.WriteString(" ")
|
||||
s.index += 1
|
||||
}
|
||||
markup(cfg, s)
|
||||
markup(fc, s)
|
||||
nextLine(s)
|
||||
|
||||
if s.index < len(s.input) {
|
||||
@@ -723,7 +730,7 @@ func nomarkLine(cfg formatConfig, s *state) {
|
||||
skipLastBlanks(s)
|
||||
}
|
||||
|
||||
func nomark(cfg formatConfig, title string, text string) (string, string, string, string) {
|
||||
func nomark(fc formatConfig, title string, text string) (string, string, string, string) {
|
||||
s := state{
|
||||
input: text,
|
||||
index: 0,
|
||||
@@ -768,7 +775,7 @@ func nomark(cfg formatConfig, title string, text string) (string, string, string
|
||||
} else if s.block == blockCode && s.prevLine == "" && line == "}}}" {
|
||||
closeBlock(&s, blockParagraph)
|
||||
ensureBlock(&s, blockParagraph)
|
||||
nomarkLine(cfg, &s)
|
||||
nomarkLine(fc, &s)
|
||||
} else if s.block != blockMath && s.block != blockRaw && s.block != blockCode && line == "%%%" {
|
||||
ensureBlock(&s, blockMath)
|
||||
nextLine(&s)
|
||||
@@ -776,8 +783,13 @@ func nomark(cfg formatConfig, title string, text string) (string, string, string
|
||||
closeBlock(&s, blockParagraph)
|
||||
nextLine(&s)
|
||||
} else if level, title, ok := parseHeading(&s, line); ok {
|
||||
s.text.WriteString("\n" + line + "\n")
|
||||
s.plain.WriteString("\n" + title + "\n")
|
||||
s.text.WriteString("\n")
|
||||
s.text.WriteString(line)
|
||||
s.text.WriteString("\n")
|
||||
|
||||
s.plain.WriteString("\n")
|
||||
s.plain.WriteString(title)
|
||||
s.plain.WriteString("\n")
|
||||
if level == 1 && s.title == "" {
|
||||
s.title = title
|
||||
nextLine(&s)
|
||||
@@ -791,11 +803,21 @@ func nomark(cfg formatConfig, title string, text string) (string, string, string
|
||||
buf.WriteRune('!')
|
||||
}
|
||||
mark := buf.String()
|
||||
s.html.WriteString("<h" + levelStr + ">" + "<span class=\"markup\">" + mark + "</span> " + titleHTML + " <span class=\"markup\">" + mark + "</span>" + "</h" + levelStr + ">\n")
|
||||
s.html.WriteString("<h")
|
||||
s.html.WriteString(levelStr)
|
||||
s.html.WriteString("><span class=\"markup\">")
|
||||
s.html.WriteString(mark)
|
||||
s.html.WriteString("</span> ")
|
||||
s.html.WriteString(titleHTML)
|
||||
s.html.WriteString(" <span class=\"markup\">")
|
||||
s.html.WriteString(mark)
|
||||
s.html.WriteString("</span></h")
|
||||
s.html.WriteString(levelStr)
|
||||
s.html.WriteString(">\n")
|
||||
nextLine(&s)
|
||||
}
|
||||
} else {
|
||||
nomarkLine(cfg, &s)
|
||||
nomarkLine(fc, &s)
|
||||
}
|
||||
}
|
||||
closeBlock(&s, blockNone)
|
||||
|
||||
Reference in New Issue
Block a user