Index: api/api.go ================================================================== --- api/api.go +++ api/api.go @@ -97,11 +97,10 @@ } // ZettelListJSON contains data for a zettel list. type ZettelListJSON struct { Query string `json:"query"` - Human string `json:"human"` List []ZidMetaJSON `json:"list"` } // MapMeta maps metadata keys to list of metadata. type MapMeta map[string][]ZettelID Index: api/urlbuilder.go ================================================================== --- api/urlbuilder.go +++ api/urlbuilder.go @@ -87,17 +87,10 @@ ub.rawLocal = "" ub.query = append(ub.query, urlQuery{key, value}) return ub } -// AppendSearch adds a new search -func (ub *URLBuilder) AppendSearch(value string) *URLBuilder { - ub.rawLocal = "" - ub.query = append(ub.query, urlQuery{QueryKeySearch, value}) - return ub -} - // ClearQuery removes all query parameters. func (ub *URLBuilder) ClearQuery() *URLBuilder { ub.rawLocal = "" ub.query = nil ub.fragment = "" Index: client/client.go ================================================================== --- client/client.go +++ client/client.go @@ -286,27 +286,27 @@ } return lines, nil } // ListZettelJSON returns a list of zettel. -func (c *Client) ListZettelJSON(ctx context.Context, query url.Values) (string, string, []api.ZidMetaJSON, error) { +func (c *Client) ListZettelJSON(ctx context.Context, query url.Values) (string, []api.ZidMetaJSON, error) { ub := c.newQueryURLBuilder('j', query) resp, err := c.buildAndExecuteRequest(ctx, http.MethodGet, ub, nil, nil) if err != nil { - return "", "", nil, err + return "", nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return "", "", nil, statusToError(resp) + return "", nil, statusToError(resp) } dec := json.NewDecoder(resp.Body) var zl api.ZettelListJSON err = dec.Decode(&zl) if err != nil { - return "", "", nil, err + return "", nil, err } - return zl.Query, zl.Human, zl.List, nil + return zl.Query, zl.List, nil } // GetZettel returns a zettel as a string. func (c *Client) GetZettel(ctx context.Context, zid api.ZettelID, part string) ([]byte, error) { ub := c.newURLBuilder('z').SetZid(zid) Index: go.mod ================================================================== --- go.mod +++ go.mod @@ -1,5 +1,5 @@ module zettelstore.de/c -go 1.19 +go 1.18 require codeberg.org/t73fde/sxpf v0.0.0-20220719090054-749a39d0a7a0 Index: html/html.go ================================================================== --- html/html.go +++ html/html.go @@ -31,12 +31,15 @@ `<`, htmlLt, `>`, htmlGt, `"`, htmlQuot, "\000", htmlNull, } - htmlEscaper = strings.NewReplacer(htmlEscapes...) - + htmlEscaper = strings.NewReplacer(htmlEscapes...) + htmlLitEscapes = append(append([]string{}, htmlEscapes...), + " ", htmlLitSpace, + ) + htmlLitEscaper = strings.NewReplacer(htmlLitEscapes...) htmlVisEscapes = append(append([]string{}, htmlEscapes...), " ", htmlVisSpace, htmlLitSpace, htmlVisSpace, ) htmlVisEscaper = strings.NewReplacer(htmlVisEscapes...) @@ -43,10 +46,14 @@ ) // Escape writes to w the escaped HTML equivalent of the given string. func Escape(w io.Writer, s string) (int, error) { return htmlEscaper.WriteString(w, s) } +// EscapeLiteral writes the escaped HTML equivaltent of the given string. +// Each space character is written as U+00A0. +func EscapeLiteral(w io.Writer, s string) (int, error) { return htmlLitEscaper.WriteString(w, s) } + // EscapeVisible writes to w the escaped HTML equivalent of the given string. // Each space is written as U-2423. func EscapeVisible(w io.Writer, s string) (int, error) { return htmlVisEscaper.WriteString(w, s) } var ( Index: html/html_test.go ================================================================== --- html/html_test.go +++ html/html_test.go @@ -25,10 +25,30 @@ {"<", "<"}, } for _, tc := range testcases { var buf bytes.Buffer _, err := html.Escape(&buf, tc.in) + if err != nil { + t.Errorf("Escape(%q) got error: %v", tc.in, err) + } + if got := buf.String(); tc.exp != got { + t.Errorf("Escape(%q) == %q, but got %q", tc.in, tc.exp, got) + } + } +} + +func TestEscapeLiteral(t *testing.T) { + testcases := []struct { + in, exp string + }{ + {"", ""}, + {"<", "<"}, + {" a b ", "\u00a0a\u00a0\u00a0b\u00a0"}, + } + for _, tc := range testcases { + var buf bytes.Buffer + _, err := html.EscapeLiteral(&buf, tc.in) if err != nil { t.Errorf("Escape(%q) got error: %v", tc.in, err) } if got := buf.String(); tc.exp != got { t.Errorf("Escape(%q) == %q, but got %q", tc.in, tc.exp, got) Index: html/sencoder.go ================================================================== --- html/sencoder.go +++ html/sencoder.go @@ -13,11 +13,10 @@ import ( "bytes" "fmt" "io" "log" - "net/url" "strconv" "codeberg.org/t73fde/sxpf" "zettelstore.de/c/api" "zettelstore.de/c/attrs" @@ -134,16 +133,16 @@ if env.err == nil { _, env.err = Escape(env.w, s) } } -func (env *EncEnvironment) WriteEscapedOrVisible(s string) { +func (env *EncEnvironment) WriteEscapedLiteral(s string) { if env.err == nil { if env.visibleSpace { _, env.err = EscapeVisible(env.w, s) } else { - _, env.err = Escape(env.w, s) + _, env.err = EscapeLiteral(env.w, s) } } } func (env *EncEnvironment) GetSymbol(p *sxpf.Pair) (res *sxpf.Symbol) { @@ -499,16 +498,10 @@ WriteLink(env, args, a.AddClass("broken"), refValue, "") } }}, {sexpr.SymLinkHosted, 2, func(env *EncEnvironment, args *sxpf.Pair) { WriteHRefLink(env, args) }}, {sexpr.SymLinkBased, 2, func(env *EncEnvironment, args *sxpf.Pair) { WriteHRefLink(env, args) }}, - {sexpr.SymLinkSearch, 2, func(env *EncEnvironment, args *sxpf.Pair) { - if a, refValue, ok := PrepareLink(env, args); ok { - query := "?" + api.QueryKeySearch + "=" + url.QueryEscape(refValue) - WriteLink(env, args, a.Set("href", query), refValue, "") - } - }}, {sexpr.SymLinkExternal, 2, func(env *EncEnvironment, args *sxpf.Pair) { if a, refValue, ok := PrepareLink(env, args); ok { WriteLink(env, args, a.Set("href", refValue).AddClass("external"), refValue, "") } }}, @@ -569,11 +562,11 @@ } }}, {sexpr.SymFormatDelete, 1, makeFormatFn("del")}, {sexpr.SymFormatEmph, 1, makeFormatFn("em")}, {sexpr.SymFormatInsert, 1, makeFormatFn("ins")}, - {sexpr.SymFormatQuote, 1, writeQuote}, + {sexpr.SymFormatQuote, 1, makeFormatFn("q")}, {sexpr.SymFormatSpan, 1, makeFormatFn("span")}, {sexpr.SymFormatStrong, 1, makeFormatFn("strong")}, {sexpr.SymFormatSub, 1, makeFormatFn("sub")}, {sexpr.SymFormatSuper, 1, makeFormatFn("sup")}, {sexpr.SymLiteralComment, 1, func(env *EncEnvironment, args *sxpf.Pair) { @@ -654,11 +647,11 @@ } func (env *EncEnvironment) writeVerbatim(args *sxpf.Pair, a attrs.Attributes) { env.WriteString("
")
 	env.WriteStartTag("code", a)
-	env.WriteEscapedOrVisible(env.GetString(args.GetTail()))
+	env.WriteEscapedLiteral(env.GetString(args.GetTail()))
 	env.WriteString("
") } func execHTML(env *EncEnvironment, args *sxpf.Pair) { if s := env.GetString(args.GetTail()); s != "" && IsSafe(s) { @@ -730,26 +723,10 @@ sxpf.EvalSequence(env, args.GetTail()) env.WriteEndTag(tag) } } -func writeQuote(env *EncEnvironment, args *sxpf.Pair) { - const langAttr = "lang" - a := env.GetAttributes(args) - lang, hasLang := a.Get(langAttr) - if hasLang { - a = a.Remove(langAttr) - env.WriteStartTag("span", attrs.Attributes{}.Set(langAttr, lang)) - } - env.WriteStartTag("q", a) - sxpf.EvalSequence(env, args.GetTail()) - env.WriteEndTag("q") - if hasLang { - env.WriteEndTag("span") - } -} - func (env *EncEnvironment) writeLiteral(args *sxpf.Pair, a attrs.Attributes, tag string) { if a == nil { a = env.GetAttributes(args) } oldVisible := env.visibleSpace @@ -756,11 +733,11 @@ if a.HasDefault() { env.visibleSpace = true a = a.RemoveDefault() } env.WriteStartTag(tag, a) - env.WriteEscapedOrVisible(env.GetString(args.GetTail())) + env.WriteEscapedLiteral(env.GetString(args.GetTail())) env.visibleSpace = oldVisible env.WriteEndTag(tag) } func setProgLang(a attrs.Attributes) attrs.Attributes { Index: sexpr/const.go ================================================================== --- sexpr/const.go +++ sexpr/const.go @@ -42,11 +42,10 @@ SymLinkSelf = Smk.MakeSymbol("LINK-SELF") SymLinkFound = Smk.MakeSymbol("LINK-FOUND") SymLinkBroken = Smk.MakeSymbol("LINK-BROKEN") SymLinkHosted = Smk.MakeSymbol("LINK-HOSTED") SymLinkBased = Smk.MakeSymbol("LINK-BASED") - SymLinkSearch = Smk.MakeSymbol("LINK-SEARCH") SymLinkExternal = Smk.MakeSymbol("LINK-EXTERNAL") SymListOrdered = Smk.MakeSymbol("ORDERED") SymListUnordered = Smk.MakeSymbol("UNORDERED") SymListQuote = Smk.MakeSymbol("QUOTATION") SymLiteralProg = Smk.MakeSymbol("LITERAL-CODE") @@ -84,11 +83,10 @@ SymRefStateSelf = Smk.MakeSymbol("SELF") SymRefStateFound = Smk.MakeSymbol("FOUND") SymRefStateBroken = Smk.MakeSymbol("BROKEN") SymRefStateHosted = Smk.MakeSymbol("HOSTED") SymRefStateBased = Smk.MakeSymbol("BASED") - SymRefStateSearch = Smk.MakeSymbol("SEARCH") SymRefStateExternal = Smk.MakeSymbol("EXTERNAL") ) // Symbols for metadata types var ( DELETED www/changes.wiki Index: www/changes.wiki ================================================================== --- www/changes.wiki +++ /dev/null @@ -1,15 +0,0 @@ -Change Log - - -

Changes for Version 0.6.0 (2022-08-11)

- * Add support to build URLs with search expressions - * Use Go 1.19 - * Fix some bugs - - -

Changes for Version 0.5.1 (2022-08-08)

- * Support for search references - (minor: api, zjson, sexpr, html) - -

Changes for Version 0.5 (2022-07-29)

- * Initial public release. Index: www/index.wiki ================================================================== --- www/index.wiki +++ www/index.wiki @@ -1,12 +1,12 @@ Home This repository contains Go client software to access [https://zettelstore.de|Zettelstore] via its API. -

Latest Release: 0.6.0 (2022-08-11)

- * [./changes.wiki#0_6|Change summary] - * [/timeline?p=v0.6.0&bt=v0.5&y=ci|Check-ins for version 0.6.0], - [/vdiff?to=v0.6.0&from=v0.5|content diff] - * [/timeline?df=v0.6.0&y=ci|Check-ins derived from the 0.6.0 release], - [/vdiff?from=v0.6.0&to=trunk|content diff] +

Latest Release: 0.5 (2022-07-29)

+ * [./changes.wiki#0_5|Change summary] + * [/timeline?p=v0.5&bt=v0.4&y=ci|Check-ins for version 0.5], + [/vdiff?to=v0.5&from=v0.4|content diff] + * [/timeline?df=v0.5&y=ci|Check-ins derived from the 0.5 release], + [/vdiff?from=v0.5&to=trunk|content diff] * [/timeline?t=release|Timeline of all past releases] Index: zjson/const.go ================================================================== --- zjson/const.go +++ zjson/const.go @@ -84,11 +84,10 @@ RefStateBroken = "broken" RefStateExternal = "external" RefStateFound = "found" RefStateHosted = "local" RefStateInvalid = "invalid" - RefStateSearch = "search" RefStateSelf = "self" RefStateZettel = "zettel" ) // Values for table cell alignment