diff --git a/internal/action/edit.go b/internal/action/edit.go
index 7e4ce90..d34e7c0 100644
--- a/internal/action/edit.go
+++ b/internal/action/edit.go
@@ -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 := ""
diff --git a/internal/format/creole.go b/internal/format/creole.go
index a7e4069..8f16ae2 100644
--- a/internal/format/creole.go
+++ b/internal/format/creole.go
@@ -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
}
diff --git a/internal/format/format.go b/internal/format/format.go
index de2f2db..83c060d 100644
--- a/internal/format/format.go
+++ b/internal/format/format.go
@@ -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()
}
}
diff --git a/internal/format/markdown.go b/internal/format/markdown.go
index f558b6a..b84f790 100644
--- a/internal/format/markdown.go
+++ b/internal/format/markdown.go
@@ -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
}
diff --git a/internal/format/nomark.go b/internal/format/nomark.go
index 41fbb17..c487e1f 100644
--- a/internal/format/nomark.go
+++ b/internal/format/nomark.go
@@ -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("")
@@ -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("")
@@ -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("" + "" + mark + " " + titleHTML + " " + mark + "" + "\n")
+ s.html.WriteString("")
+ s.html.WriteString(mark)
+ s.html.WriteString(" ")
+ s.html.WriteString(titleHTML)
+ s.html.WriteString(" ")
+ s.html.WriteString(mark)
+ s.html.WriteString("\n")
nextLine(&s)
}
} else {
- nomarkLine(cfg, &s)
+ nomarkLine(fc, &s)
}
}
closeBlock(&s, blockNone)