diff --git a/markup/img.go b/markup/img.go
new file mode 100644
index 0000000..18e75d8
--- /dev/null
+++ b/markup/img.go
@@ -0,0 +1,140 @@
+package markup
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+)
+
+var imgRe = regexp.MustCompile(`^img\s+{`)
+
+func MatchesImg(line string) bool {
+ return imgRe.MatchString(line)
+}
+
+type imgEntry struct {
+ path string
+ sizeH string
+ sizeV string
+ desc string
+}
+
+type Img struct {
+ entries []imgEntry
+ inDesc bool
+ hyphaName string
+}
+
+func (img *Img) Process(line string) (shouldGoBackToNormal bool) {
+ if img.inDesc {
+ rightBraceIndex := strings.IndexRune(line, '}')
+ if cnt := len(img.entries); rightBraceIndex == -1 && cnt != 0 {
+ img.entries[cnt-1].desc += "\n" + line
+ } else if rightBraceIndex != -1 && cnt != 0 {
+ img.entries[cnt-1].desc += "\n" + line[:rightBraceIndex]
+ img.inDesc = false
+ }
+ if strings.Count(line, "}") > 1 {
+ return true
+ }
+ } else if s := strings.TrimSpace(line); s != "" {
+ if s[0] == '}' {
+ return true
+ }
+ img.parseStartOfEntry(line)
+ }
+ return false
+}
+
+func ImgFromFirstLine(line, hyphaName string) Img {
+ img := Img{
+ hyphaName: hyphaName,
+ entries: make([]imgEntry, 0),
+ }
+ line = line[strings.IndexRune(line, '{'):]
+ if len(line) == 1 { // if { only
+ } else {
+ line = line[1:] // Drop the {
+ }
+ return img
+}
+
+func (img *Img) canonicalPathFor(path string) string {
+ path = strings.TrimSpace(path)
+ if strings.IndexRune(path, ':') != -1 || strings.IndexRune(path, '/') == 0 {
+ return path
+ } else {
+ return "/binary/" + xclCanonicalName(img.hyphaName, path)
+ }
+}
+
+func (img *Img) parseStartOfEntry(line string) (entry imgEntry, followedByDesc bool) {
+ pipeIndex := strings.IndexRune(line, '|')
+ if pipeIndex == -1 { // If no : in string
+ entry.path = img.canonicalPathFor(line)
+ } else {
+ entry.path = img.canonicalPathFor(line[:pipeIndex])
+ line = strings.TrimPrefix(line, line[:pipeIndex+1])
+
+ var (
+ leftBraceIndex = strings.IndexRune(line, '{')
+ rightBraceIndex = strings.IndexRune(line, '}')
+ dimensions string
+ )
+
+ if leftBraceIndex == -1 {
+ dimensions = line
+ } else {
+ dimensions = line[:leftBraceIndex]
+ }
+
+ sizeH, sizeV := parseDimensions(dimensions)
+ entry.sizeH = sizeH
+ entry.sizeV = sizeV
+
+ if leftBraceIndex != -1 && rightBraceIndex == -1 {
+ img.inDesc = true
+ followedByDesc = true
+ entry.desc = strings.TrimPrefix(line, line[:leftBraceIndex+1])
+ } else if leftBraceIndex != -1 && rightBraceIndex != -1 {
+ entry.desc = line[leftBraceIndex+1 : rightBraceIndex]
+ }
+ }
+ img.entries = append(img.entries, entry)
+ return
+}
+
+func parseDimensions(dimensions string) (sizeH, sizeV string) {
+ xIndex := strings.IndexRune(dimensions, '*')
+ if xIndex == -1 { // If no x in dimensions
+ sizeH = strings.TrimSpace(dimensions)
+ } else {
+ sizeH = strings.TrimSpace(dimensions[:xIndex])
+ sizeV = strings.TrimSpace(strings.TrimPrefix(dimensions, dimensions[:xIndex+1]))
+ }
+ return
+}
+
+func (img Img) ToHtml() (html string) {
+ for _, entry := range img.entries {
+ html += fmt.Sprintf(``
+ }
+ return `
%s
", state.id, ParagraphToHtml(line))) } diff --git a/markup/lexer_test.go b/markup/lexer_test.go index e03eafa..41dc64b 100644 --- a/markup/lexer_test.go +++ b/markup/lexer_test.go @@ -19,8 +19,8 @@ func TestLex(t *testing.T) { return } for i, e := range ast { - if e != expectedAst[i] { - t.Error("Mismatch when lexing", name, "\nExpected:", expectedAst[i], "\nGot:", e) + if !reflect.DeepEqual(e, expectedAst[i]) { + t.Error(fmt.Sprintf("Expected: %q\nGot:%q", expectedAst[i], e)) } } } @@ -43,7 +43,7 @@ func TestLex(t *testing.T) { {7, "more text
"}, {8, ``}, {9, `=> preformatted text
where markup is not lexed
`},
@@ -51,7 +51,17 @@ where markup is not lexed`},
{12, "text
"}, {13, `()
/\
`},
- // More thorough testing of xclusions is done in xclusion_test.go
{14, Transclusion{"apple", 1, 3}},
+ {15, Img{
+ hyphaName: "Apple",
+ inDesc: false,
+ entries: []imgEntry{
+ {"hypha1", "", "", ""},
+ {"hypha2", "", "", ""},
+ {"hypha3", "60", "", ""},
+ {"hypha4", "", "", " line1\nline2\n"},
+ {"hypha5", "", "", "\nstate of minnesota\n"},
+ },
+ }},
})
}
diff --git a/markup/paragraph_test.go b/markup/paragraph_test.go
index 7ef9c07..49505a9 100644
--- a/markup/paragraph_test.go
+++ b/markup/paragraph_test.go
@@ -32,7 +32,7 @@ func TestParagraphToHtml(t *testing.T) {
{"Embedded //italic//", "Embedded italic"},
{"double //italian// //text//", "double italian text"},
{"it has `mono`", "it has mono
"},
- {"this is a left **bold", "this is a left bold"},
+ {"this is a left **bold", "this is a left bold"},
{"this line has a ,comma, two of them", "this line has a ,comma, two of them"},
{"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."},
}
diff --git a/markup/parser.go b/markup/parser.go
index 66f81a0..dd7e110 100644
--- a/markup/parser.go
+++ b/markup/parser.go
@@ -17,6 +17,8 @@ func Parse(ast []Line, from, to int, state GemParserState) (html string) {
switch v := line.contents.(type) {
case Transclusion:
html += Transclude(v, state)
+ case Img:
+ html += v.ToHtml()
case string:
html += v
}
diff --git a/markup/testdata/test.myco b/markup/testdata/test.myco
index 6646148..389188e 100644
--- a/markup/testdata/test.myco
+++ b/markup/testdata/test.myco
@@ -22,3 +22,17 @@ text
/\
```
<= Apple : 1..3
+
+img {
+hypha1
+hypha2:
+hypha3: 60
+hypha4: { line1
+line2
+} this is ignored
+
+hypha5: {
+state of minnesota
+}
+}
+
diff --git a/metarrhiza b/metarrhiza
index 2e2e3a7..a54be90 160000
--- a/metarrhiza
+++ b/metarrhiza
@@ -1 +1 @@
-Subproject commit 2e2e3a70f9de67b54f912dd9fdaa04497bf795b0
+Subproject commit a54be905923b10524d74435fb62dbdd9a0aac06a
diff --git a/templates/css.qtpl b/templates/css.qtpl
index 546f829..c66fe91 100644
--- a/templates/css.qtpl
+++ b/templates/css.qtpl
@@ -33,6 +33,8 @@ p code {background-color:#eee; padding: .1rem .3rem; border-radius: .25rem; font
.binary-container_with-video video,
.binary-container_with-audio audio {width: 100%}
.navi-title a {text-decoration:none;}
+.img-gallery img { max-width: 100%; }
+figure { margin: 0; }
nav ul {display:flex; padding-left:0; flex-wrap:wrap; margin-top:0;}
nav ul li {list-style-type:none;margin-right:1rem;}
diff --git a/templates/css.qtpl.go b/templates/css.qtpl.go
index 0d7c694..17f118f 100644
--- a/templates/css.qtpl.go
+++ b/templates/css.qtpl.go
@@ -55,37 +55,39 @@ p code {background-color:#eee; padding: .1rem .3rem; border-radius: .25rem; font
.binary-container_with-video video,
.binary-container_with-audio audio {width: 100%}
.navi-title a {text-decoration:none;}
+.img-gallery img { max-width: 100%; }
+figure { margin: 0; }
nav ul {display:flex; padding-left:0; flex-wrap:wrap; margin-top:0;}
nav ul li {list-style-type:none;margin-right:1rem;}
#new-name {width:100%;}
`)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
}
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
func WriteDefaultCSS(qq422016 qtio422016.Writer) {
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
qw422016 := qt422016.AcquireWriter(qq422016)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
StreamDefaultCSS(qw422016)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
qt422016.ReleaseWriter(qw422016)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
}
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
func DefaultCSS() string {
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
qb422016 := qt422016.AcquireByteBuffer()
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
WriteDefaultCSS(qb422016)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
qs422016 := string(qb422016.B)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
qt422016.ReleaseByteBuffer(qb422016)
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
return qs422016
-//line templates/css.qtpl:41
+//line templates/css.qtpl:43
}