List of hyphae
This wiki has `) -//line templates/http_stuff.qtpl:18 +//line templates/http_stuff.qtpl:19 qw422016.N().D(pageCount) -//line templates/http_stuff.qtpl:18 +//line templates/http_stuff.qtpl:19 qw422016.N().S(` hyphae.
diff --git a/flag.go b/flag.go
index 2bd83ff..551e0cf 100644
--- a/flag.go
+++ b/flag.go
@@ -10,7 +10,7 @@ import (
)
func init() {
- flag.StringVar(&util.URL, "url", "http://0.0.0.0:$port", "URL at which your wiki can be found. Used to generate feeds")
+ flag.StringVar(&util.URL, "url", "http://0.0.0.0:$port", "URL at which your wiki can be found. Used to generate feeds and social media previews")
flag.StringVar(&util.ServerPort, "port", "1737", "Port to serve the wiki at using HTTP")
flag.StringVar(&util.HomePage, "home", "home", "The home page name")
flag.StringVar(&util.SiteTitle, "title", "🍄", "How to call your wiki in the navititle")
diff --git a/http_readers.go b/http_readers.go
index 6f7c58e..497a30f 100644
--- a/http_readers.go
+++ b/http_readers.go
@@ -36,7 +36,7 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
textContents, err = history.FileAtRevision(textPath, revHash)
)
if err == nil {
- contents = markup.ToHtml(hyphaName, textContents)
+ contents = markup.Doc(hyphaName, textContents).AsHTML()
}
treeHTML, _, _ := tree.Tree(hyphaName, IterateHyphaNamesWith)
page := templates.RevisionHTML(
@@ -81,20 +81,27 @@ func handlerPage(w http.ResponseWriter, rq *http.Request) {
hyphaName = HyphaNameFromRq(rq, "page")
data, hyphaExists = HyphaStorage[hyphaName]
contents string
+ openGraph string
)
if hyphaExists {
fileContentsT, errT := ioutil.ReadFile(data.textPath)
_, errB := os.Stat(data.binaryPath)
if errT == nil {
- contents = markup.ToHtml(hyphaName, string(fileContentsT))
+ md := markup.Doc(hyphaName, string(fileContentsT))
+ contents = md.AsHTML()
+ openGraph = md.OpenGraphHTML()
}
if !os.IsNotExist(errB) {
contents = binaryHtmlBlock(hyphaName, data) + contents
}
}
treeHTML, prevHypha, nextHypha := tree.Tree(hyphaName, IterateHyphaNamesWith)
- util.HTTP200Page(w, base(hyphaName, templates.PageHTML(rq, hyphaName,
- naviTitle(hyphaName),
- contents,
- treeHTML, prevHypha, nextHypha)))
+ util.HTTP200Page(w,
+ templates.BaseHTML(
+ hyphaName,
+ templates.PageHTML(rq, hyphaName,
+ naviTitle(hyphaName),
+ contents,
+ treeHTML, prevHypha, nextHypha),
+ openGraph))
}
diff --git a/hypha.go b/hypha.go
index e412c14..5280639 100644
--- a/hypha.go
+++ b/hypha.go
@@ -33,6 +33,12 @@ func init() {
return
}
markup.HyphaIterate = IterateHyphaNamesWith
+ markup.HyphaImageForOG = func(hyphaName string) string {
+ if hd, isOld := GetHyphaData(hyphaName); isOld && hd.binaryPath != "" {
+ return util.URL + "/binary/" + hyphaName
+ }
+ return util.URL + "/favicon.ico"
+ }
}
// GetHyphaData finds a hypha addressed by `hyphaName` and returns its `hyphaData`. `hyphaData` is set to a zero value if this hypha does not exist. `isOld` is false if this hypha does not exist.
diff --git a/markup/img.go b/markup/img.go
index 9539498..99c919b 100644
--- a/markup/img.go
+++ b/markup/img.go
@@ -4,6 +4,8 @@ import (
"fmt"
"regexp"
"strings"
+
+ "github.com/bouncepaw/mycorrhiza/util"
)
var imgRe = regexp.MustCompile(`^img\s+{`)
@@ -184,6 +186,14 @@ func (img *Img) binaryPathFor(path string) string {
}
}
+func (img *Img) ogBinaryPathFor(path string) string {
+ path = img.binaryPathFor(path)
+ if strings.HasPrefix(path, "/binary/") {
+ return util.URL + path
+ }
+ return path
+}
+
func (img *Img) pagePathFor(path string) string {
path = strings.TrimSpace(path)
if strings.IndexRune(path, ':') != -1 || strings.IndexRune(path, '/') == 0 {
diff --git a/markup/lexer.go b/markup/lexer.go
index 6ba3b94..b1c3abc 100644
--- a/markup/lexer.go
+++ b/markup/lexer.go
@@ -9,6 +9,9 @@ import (
// HyphaExists holds function that checks that a hypha is present.
var HyphaExists func(string) bool
+//
+var HyphaImageForOG func(string) string
+
// HyphaAccess holds function that accesses a hypha by its name.
var HyphaAccess func(string) (rawText, binaryHtml string, err error)
@@ -29,21 +32,21 @@ type GemLexerState struct {
type Line struct {
id int
- // interface{} may be bad. What I need is a sum of string and Transclusion
+ // interface{} may be bad. TODO: a proper type
contents interface{}
}
-func lex(name, content string) (ast []Line) {
- var state = GemLexerState{name: name}
+func (md *MycoDoc) lex() (ast []Line) {
+ var state = GemLexerState{name: md.hyphaName}
- for _, line := range append(strings.Split(content, "\n"), "") {
- geminiLineToAST(line, &state, &ast)
+ for _, line := range append(strings.Split(md.contents, "\n"), "") {
+ lineToAST(line, &state, &ast)
}
return ast
}
// Lex `line` in markup and save it to `ast` using `state`.
-func geminiLineToAST(line string, state *GemLexerState, ast *[]Line) {
+func lineToAST(line string, state *GemLexerState, ast *[]Line) {
addLine := func(text interface{}) {
*ast = append(*ast, Line{id: state.id, contents: text})
}
diff --git a/markup/mycomarkup.go b/markup/mycomarkup.go
index f3fb7a2..656ca28 100644
--- a/markup/mycomarkup.go
+++ b/markup/mycomarkup.go
@@ -2,8 +2,12 @@
package markup
import (
+ "fmt"
"html"
+ "regexp"
"strings"
+
+ "github.com/bouncepaw/mycorrhiza/util"
)
// A Mycomarkup-formatted document
@@ -11,24 +15,75 @@ type MycoDoc struct {
// data
hyphaName string
contents string
+ // indicators
+ parsedAlready bool
+ // results
+ ast []Line
+ html string
+ firstImageURL string
+ description string
}
// Constructor
func Doc(hyphaName, contents string) *MycoDoc {
- return &MycoDoc{
+ md := &MycoDoc{
hyphaName: hyphaName,
contents: contents,
}
+ return md
+}
+
+func (md *MycoDoc) Lex(recursionLevel int) *MycoDoc {
+ if !md.parsedAlready {
+ md.ast = md.lex()
+ }
+ md.parsedAlready = true
+ return md
}
// AsHtml returns an html representation of the document
func (md *MycoDoc) AsHTML() string {
- return ""
+ md.html = Parse(md.Lex(0).ast, 0, 0, 0)
+ return md.html
}
+// Used to clear opengraph description from html tags. This method is usually bad because of dangers of malformed HTML, but I'm going to use it only for Mycorrhiza-generated HTML, so it's okay. The question mark is required; without it the whole string is eaten away.
+var htmlTagRe = regexp.MustCompile(`<.*?>`)
+
// OpenGraphHTML returns an html representation of og: meta tags.
func (md *MycoDoc) OpenGraphHTML() string {
- return ""
+ md.ogFillVars()
+ return strings.Join([]string{
+ ogTag("title", md.hyphaName),
+ ogTag("type", "article"),
+ ogTag("image", md.firstImageURL),
+ ogTag("url", util.URL+"/page/"+md.hyphaName),
+ ogTag("determiner", ""),
+ ogTag("description", htmlTagRe.ReplaceAllString(md.description, "")),
+ }, "\n")
+}
+
+func (md *MycoDoc) ogFillVars() *MycoDoc {
+ foundDesc := false
+ md.firstImageURL = HyphaImageForOG(md.hyphaName)
+ for _, line := range md.ast {
+ switch v := line.contents.(type) {
+ case string:
+ if !foundDesc {
+ md.description = v
+ foundDesc = true
+ }
+ case Img:
+ if len(v.entries) > 0 {
+ md.firstImageURL = v.entries[0].path.String()
+ }
+ }
+ }
+ return md
+}
+
+func ogTag(property, content string) string {
+ return fmt.Sprintf(``, property, content)
}
/* The rest of this file is currently unused. TODO: use it I guess */
diff --git a/markup/parser.go b/markup/parser.go
index 23887d1..50ff158 100644
--- a/markup/parser.go
+++ b/markup/parser.go
@@ -1,35 +1,24 @@
package markup
-import ()
-
const maxRecursionLevel = 3
-type GemParserState struct {
- recursionLevel int
-}
-
-func Parse(ast []Line, from, to int, state GemParserState) (html string) {
- if state.recursionLevel > maxRecursionLevel {
+func Parse(ast []Line, from, to int, recursionLevel int) (html string) {
+ if recursionLevel > maxRecursionLevel {
return "Transclusion depth limit"
}
for _, line := range ast {
if line.id >= from && (line.id <= to || to == 0) || line.id == -1 {
switch v := line.contents.(type) {
case Transclusion:
- html += Transclude(v, state)
+ html += Transclude(v, recursionLevel)
case Img:
html += v.ToHtml()
case string:
html += v
default:
- html += "Unknown"
+ html += "Unknown element."
}
}
}
return html
}
-
-func ToHtml(name, text string) string {
- state := GemParserState{}
- return Parse(lex(name, text), 0, 0, state)
-}
diff --git a/markup/xclusion.go b/markup/xclusion.go
index b4a4370..a5df6c8 100644
--- a/markup/xclusion.go
+++ b/markup/xclusion.go
@@ -17,14 +17,14 @@ type Transclusion struct {
}
// Transclude transcludes `xcl` and returns html representation.
-func Transclude(xcl Transclusion, state GemParserState) (html string) {
- state.recursionLevel++
+func Transclude(xcl Transclusion, recursionLevel int) (html string) {
+ recursionLevel++
tmptOk := ` Failed to transclude %s Hypha %s does not exist
This wiki has `) -//line templates/http_stuff.qtpl:18 +//line templates/http_stuff.qtpl:19 qw422016.N().D(pageCount) -//line templates/http_stuff.qtpl:18 +//line templates/http_stuff.qtpl:19 qw422016.N().S(` hyphae.