1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-16 06:50:26 +00:00
mycorrhiza/markup/img.go

204 lines
4.4 KiB
Go
Raw Normal View History

2020-11-03 15:41:50 +00:00
package markup
import (
"fmt"
"regexp"
"strings"
2020-12-17 12:59:59 +00:00
"github.com/bouncepaw/mycorrhiza/link"
2020-11-03 15:41:50 +00:00
)
var imgRe = regexp.MustCompile(`^img\s+{`)
func MatchesImg(line string) bool {
return imgRe.MatchString(line)
}
2020-11-26 18:41:26 +00:00
type imgState int
const (
inRoot imgState = iota
inName
inDimensionsW
inDimensionsH
inDescription
)
2020-11-03 15:41:50 +00:00
type Img struct {
entries []imgEntry
2020-11-26 18:41:26 +00:00
currEntry imgEntry
2020-11-03 15:41:50 +00:00
hyphaName string
2020-11-26 18:41:26 +00:00
state imgState
}
func (img *Img) pushEntry() {
if strings.TrimSpace(img.currEntry.path.String()) != "" {
img.currEntry.srclink = link.From(img.currEntry.path.String(), "", img.hyphaName)
img.currEntry.srclink.DoubtExistence()
2020-11-26 18:41:26 +00:00
img.entries = append(img.entries, img.currEntry)
img.currEntry = imgEntry{}
img.currEntry.path.Reset()
}
2020-11-03 15:41:50 +00:00
}
func (img *Img) Process(line string) (shouldGoBackToNormal bool) {
2020-11-26 18:41:26 +00:00
stateToProcessor := map[imgState]func(rune) bool{
inRoot: img.processInRoot,
inName: img.processInName,
inDimensionsW: img.processInDimensionsW,
inDimensionsH: img.processInDimensionsH,
inDescription: img.processInDescription,
}
for _, r := range line {
if shouldReturnTrue := stateToProcessor[img.state](r); shouldReturnTrue {
2020-11-03 15:41:50 +00:00
return true
}
}
return false
}
2020-11-26 18:41:26 +00:00
func (img *Img) processInDescription(r rune) (shouldReturnTrue bool) {
switch r {
case '}':
img.state = inName
default:
img.currEntry.desc.WriteRune(r)
}
return false
}
func (img *Img) processInRoot(r rune) (shouldReturnTrue bool) {
switch r {
case '}':
img.pushEntry()
return true
case '\n', '\r':
img.pushEntry()
case ' ', '\t':
default:
img.state = inName
img.currEntry = imgEntry{}
img.currEntry.path.Reset()
img.currEntry.path.WriteRune(r)
}
return false
}
func (img *Img) processInName(r rune) (shouldReturnTrue bool) {
switch r {
case '}':
img.pushEntry()
return true
case '|':
img.state = inDimensionsW
case '{':
img.state = inDescription
case '\n', '\r':
img.pushEntry()
img.state = inRoot
default:
img.currEntry.path.WriteRune(r)
}
return false
}
func (img *Img) processInDimensionsW(r rune) (shouldReturnTrue bool) {
switch r {
case '}':
img.pushEntry()
return true
case '*':
img.state = inDimensionsH
case ' ', '\t', '\n':
case '{':
img.state = inDescription
default:
img.currEntry.sizeW.WriteRune(r)
}
return false
}
func (img *Img) processInDimensionsH(r rune) (shouldGoBackToNormal bool) {
switch r {
case '}':
img.pushEntry()
return true
case ' ', '\t', '\n':
case '{':
img.state = inDescription
default:
img.currEntry.sizeH.WriteRune(r)
}
return false
}
func ImgFromFirstLine(line, hyphaName string) (img *Img, shouldGoBackToNormal bool) {
img = &Img{
2020-11-03 15:41:50 +00:00
hyphaName: hyphaName,
entries: make([]imgEntry, 0),
}
2020-11-26 18:41:26 +00:00
line = line[strings.IndexRune(line, '{')+1:]
return img, img.Process(line)
2020-11-03 15:41:50 +00:00
}
2020-11-26 18:41:26 +00:00
func (img *Img) pagePathFor(path string) string {
path = strings.TrimSpace(path)
if strings.IndexRune(path, ':') != -1 || strings.IndexRune(path, '/') == 0 {
return path
2020-11-03 15:41:50 +00:00
} else {
2020-11-26 18:41:26 +00:00
return "/page/" + xclCanonicalName(img.hyphaName, path)
2020-11-03 15:41:50 +00:00
}
}
2020-11-26 18:41:26 +00:00
func parseDimensions(dimensions string) (sizeW, sizeH string) {
2020-11-03 15:41:50 +00:00
xIndex := strings.IndexRune(dimensions, '*')
if xIndex == -1 { // If no x in dimensions
2020-11-26 18:41:26 +00:00
sizeW = strings.TrimSpace(dimensions)
2020-11-03 15:41:50 +00:00
} else {
2020-11-26 18:41:26 +00:00
sizeW = strings.TrimSpace(dimensions[:xIndex])
sizeH = strings.TrimSpace(strings.TrimPrefix(dimensions, dimensions[:xIndex+1]))
2020-11-03 15:41:50 +00:00
}
return
}
func (img *Img) markExistenceOfSrcLinks() {
HyphaIterate(func(hn string) {
2020-11-26 18:41:26 +00:00
for _, entry := range img.entries {
if hn == entry.srclink.Address {
entry.srclink.DestinationUnknown = false
2020-11-03 15:41:50 +00:00
}
}
2020-11-26 18:41:26 +00:00
})
}
func (img *Img) ToHtml() (html string) {
img.markExistenceOfSrcLinks()
2020-11-26 18:41:26 +00:00
isOneImageOnly := len(img.entries) == 1 && img.entries[0].desc.Len() == 0
if isOneImageOnly {
html += `<section class="img-gallery img-gallery_one-image">`
} else {
html += `<section class="img-gallery img-gallery_many-images">`
}
for _, entry := range img.entries {
html += `<figure>`
if entry.srclink.DestinationUnknown {
html += fmt.Sprintf(
`<a class="%s" href="%s">Hypha <i>%s</i> does not exist</a>`,
entry.srclink.Classes(),
entry.srclink.Href(),
entry.srclink.Address)
} else {
2020-11-26 18:41:26 +00:00
html += fmt.Sprintf(
`<a href="%s"><img src="%s" %s %s></a>`,
entry.srclink.Href(),
entry.srclink.ImgSrc(),
entry.sizeWAsAttr(),
entry.sizeHAsAttr())
2020-11-26 18:41:26 +00:00
}
html += entry.descriptionAsHtml(img.hyphaName)
2020-11-03 15:41:50 +00:00
html += `</figure>`
}
2020-11-26 18:41:26 +00:00
return html + `</section>`
2020-11-03 15:41:50 +00:00
}