aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md43
-rw-r--r--example/Caddyfile4
-rw-r--r--http/handlers/templates/functions/gemtext.go46
3 files changed, 81 insertions, 12 deletions
diff --git a/README.md b/README.md
index a914f51..30a3285 100644
--- a/README.md
+++ b/README.md
@@ -20,11 +20,45 @@ function][mdfunc] in its usage. It can be enabled by being included in the
```text
templates {
extensions {
- gemtext
+ gemtext {
+ # All parameters are optional
+ gateway_url "https://some.gateway/x/"
+ }
}
}
```
+See the `template.localhost` virtual host in `example/Caddyfile`, and the
+associated `example/tpl/render_gemtext.html` template file, for an example of
+how to use this directive.
+
+[gemtext]: https://geminiprotocol.net/docs/gemtext.gmi
+[mdfunc]: https://caddyserver.com/docs/modules/http.handlers.templates#markdown
+
+#### Parameters
+
+Optional parameters to the gemtext extension include:
+
+**gateway_url**
+
+If given then any `gemini://` URLs encountered as links within
+the document will be appended to this URL, having their `gemini://` scheme
+stripped off first.
+
+e.g. if `gateway_url` is `https://some.gateway/x/` then the following line:
+
+```text
+=> gemini://geminiprotocol.net Check it out!
+```
+
+becomes
+
+```html
+<a href="https://some.gateway/x/geminiprotocol.net">Check it out!</a>
+```
+
+#### Template function
+
Within a template being rendered the `gemtext` function will be available and
can be passed any string. The function will return a struct with the following
fields:
@@ -36,13 +70,6 @@ fields:
* `Title`: A suggested title, based on the first `# Header` line found in the
gemtext input.
-See the `template.localhost` virtual host in `example/Caddyfile`, and the
-associated `example/tpl/render_gemtext.html` template file, for an example of
-how to use the template function.
-
-[gemtext]: https://geminiprotocol.net/docs/gemtext.gmi
-[mdfunc]: https://caddyserver.com/docs/modules/http.handlers.templates#markdown
-
## Development
A nix-based development environment is provided with the correct versions of all
diff --git a/example/Caddyfile b/example/Caddyfile
index 8d9dd50..05ad0ba 100644
--- a/example/Caddyfile
+++ b/example/Caddyfile
@@ -26,7 +26,9 @@ http://template.localhost {
# Include the gemtext extention to make the gemtext function
# available within the template.
extensions {
- gemtext
+ gemtext {
+ gateway_url "https://gemini.tildeverse.org/?gemini://"
+ }
}
}
diff --git a/http/handlers/templates/functions/gemtext.go b/http/handlers/templates/functions/gemtext.go
index 57ea751..179d558 100644
--- a/http/handlers/templates/functions/gemtext.go
+++ b/http/handlers/templates/functions/gemtext.go
@@ -7,6 +7,7 @@ import (
"fmt"
"html"
"io"
+ "net/url"
"strings"
"text/template"
@@ -30,7 +31,22 @@ func init() {
)
}
-type Gemtext struct{}
+type Gemtext struct {
+
+ // If given then any `gemini://` URLs encountered as links within the
+ // document will be appended to this URL, having their `gemini://` scheme
+ // stripped off first.
+ //
+ // e.g. if `gateway_url` is `https://some.gateway/x/` then the following
+ // line:
+ //
+ // => gemini://geminiprotocol.net Check it out!
+ //
+ // becomes
+ //
+ // <a href="https://some.gateway/x/geminiprotocol.net">Check it out!</a>
+ GatewayURL string `json:"gateway_url,omitempty"`
+}
var _ templates.CustomFunctions = (*Gemtext)(nil)
@@ -56,7 +72,7 @@ type gemtextResult struct {
Body string
}
-func (*Gemtext) funcGemtext(input any) (gemtextResult, error) {
+func (g *Gemtext) funcGemtext(input any) (gemtextResult, error) {
var (
r = bufio.NewReader(strings.NewReader(caddy.ToString(input)))
w = new(bytes.Buffer)
@@ -126,9 +142,17 @@ loop:
urlStr = line
label = urlStr
)
+
if i := strings.IndexAny(urlStr, " \t"); i > -1 {
urlStr, label = urlStr[:i], sanitizeText(urlStr[i:])
}
+
+ if g.GatewayURL != "" {
+ if u, err := url.Parse(urlStr); err == nil && u.Scheme == "gemini" {
+ urlStr = g.GatewayURL + u.Host + u.Path
+ }
+ }
+
write("<p><a href=\"%s\">%s</a></p>\n", urlStr, label)
case strings.HasPrefix(line, "###"):
@@ -160,7 +184,23 @@ loop:
}
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
-func (*Gemtext) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
+func (g *Gemtext) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
d.Next() // consume directive name
+
+ for nesting := d.Nesting(); d.NextBlock(nesting); {
+ v := d.Val()
+ switch v {
+ case "gateway_url":
+ if !d.Args(&g.GatewayURL) {
+ return d.ArgErr()
+ } else if _, err := url.Parse(g.GatewayURL); err != nil {
+ return fmt.Errorf("invalid gateway url: %w", err)
+ }
+
+ default:
+ return fmt.Errorf("unknown directive %q", v)
+ }
+ }
+
return nil
}