Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From v0.17.0 To trunk
2024-04-22
| ||
15:01 | Rename package sxhtml to sxwebs/sxhtml; update some dependencies ... (Leaf check-in: 3e4f0da507 user: stern tags: trunk) | |
2024-04-18
| ||
13:30 | Adapt to client change: api.URLBuilder ... (check-in: 85cb9d749b user: stern tags: trunk) | |
2024-03-06
| ||
15:02 |
Increase version to 0.18.0-dev to begin next development cycle... (check-in: 51c141a192 user: stern tags: trunk) | |
2024-03-04
| ||
17:08 | Version 0.17.0 ... (check-in: c863ee5f61 user: stern tags: trunk, release, v0.17.0) | |
13:47 | Adapt to sx changes; add SPDX license identifiers ... (check-in: 5485ba3ce3 user: stern tags: trunk) | |
Changes to README.md.
︙ | ︙ | |||
9 10 11 12 13 14 15 | gradually, one major focus is a long-term store of these notes, hence the name “Zettelstore”. To get an initial impression, take a look at the [manual](https://zettelstore.de/manual/). It is a live example of the zettelstore software, running in read-only mode. | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | gradually, one major focus is a long-term store of these notes, hence the name “Zettelstore”. To get an initial impression, take a look at the [manual](https://zettelstore.de/manual/). It is a live example of the zettelstore software, running in read-only mode. [Zettelstore Client](https://t73f.de/r/zsc) provides client software to access Zettelstore via its API more easily, [Zettelstore Contrib](https://zettelstore.de/contrib) contains contributed software, which often connects to Zettelstore via its API. Some of the software packages may be experimental. The software, including the manual, is licensed under the [European Union Public License 1.2 (or later)](https://zettelstore.de/home/file?name=LICENSE.txt&ci=trunk). [Stay tuned](https://mastodon.social/tags/Zettelstore) … |
Changes to VERSION.
|
| | | 1 | 0.18.0-dev |
Changes to ast/block.go.
︙ | ︙ | |||
9 10 11 12 13 14 15 | // // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package ast | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package ast import "t73f.de/r/zsc/attrs" // Definition of Block nodes. // BlockSlice is a slice of BlockNodes. type BlockSlice []BlockNode func (*BlockSlice) blockNode() { /* Just a marker */ } |
︙ | ︙ |
Changes to ast/inline.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package ast import ( "unicode/utf8" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package ast import ( "unicode/utf8" "t73f.de/r/zsc/attrs" ) // Definitions of inline nodes. // InlineSlice is a list of BlockNodes. type InlineSlice []InlineNode |
︙ | ︙ |
Changes to ast/ref.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package ast import ( "net/url" "strings" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package ast import ( "net/url" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" ) // QueryPrefix is the prefix that denotes a query expression. const QueryPrefix = api.QueryPrefix // ParseReference parses a string and returns a reference. |
︙ | ︙ |
Changes to ast/walk_test.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package ast_test import ( "testing" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package ast_test import ( "testing" "t73f.de/r/zsc/attrs" "zettelstore.de/z/ast" ) func BenchmarkWalk(b *testing.B) { root := ast.BlockSlice{ &ast.HeadingNode{ Inlines: ast.CreateInlineSliceFromWords("A", "Simple", "Heading"), |
︙ | ︙ |
Changes to auth/impl/digest.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "bytes" "crypto" "crypto/hmac" "encoding/base64" | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "bytes" "crypto" "crypto/hmac" "encoding/base64" "t73f.de/r/sx" "t73f.de/r/sx/sxreader" ) var encoding = base64.RawURLEncoding const digestAlg = crypto.SHA384 func sign(claim sx.Object, secret []byte) ([]byte, error) { |
︙ | ︙ |
Changes to auth/impl/impl.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "errors" "hash/fnv" "io" "time" | | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import ( "errors" "hash/fnv" "io" "time" "t73f.de/r/sx" "t73f.de/r/zsc/api" "t73f.de/r/zsc/sexp" "zettelstore.de/z/auth" "zettelstore.de/z/auth/policy" "zettelstore.de/z/box" "zettelstore.de/z/config" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" |
︙ | ︙ | |||
88 89 90 91 92 93 94 | if !ok || subject == "" { return nil, ErrNoIdent } now := time.Now().Round(time.Second) sClaim := sx.MakeList( sx.Int64(kind), | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | if !ok || subject == "" { return nil, ErrNoIdent } now := time.Now().Round(time.Second) sClaim := sx.MakeList( sx.Int64(kind), sx.MakeString(subject), sx.Int64(now.Unix()), sx.Int64(now.Add(d).Unix()), sx.Int64(ident.Zid), ) return sign(sClaim, a.secret) } |
︙ | ︙ | |||
121 122 123 124 125 126 127 | vals, err := sexp.ParseList(obj, "isiii") if err != nil { return ErrMalformedToken } if auth.TokenKind(vals[0].(sx.Int64)) != k { return ErrOtherKind } | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | vals, err := sexp.ParseList(obj, "isiii") if err != nil { return ErrMalformedToken } if auth.TokenKind(vals[0].(sx.Int64)) != k { return ErrOtherKind } ident := vals[1].(sx.String).GetValue() if ident == "" { return ErrNoIdent } issued := time.Unix(int64(vals[2].(sx.Int64)), 0) expires := time.Unix(int64(vals[3].(sx.Int64)), 0) now := time.Now().Round(time.Second) if expires.Before(now) { |
︙ | ︙ |
Changes to auth/policy/default.go.
︙ | ︙ | |||
10 11 12 13 14 15 16 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package policy import ( | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package policy import ( "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/zettel/meta" ) type defaultPolicy struct { manager auth.AuthzManager } |
︙ | ︙ |
Changes to auth/policy/owner.go.
︙ | ︙ | |||
10 11 12 13 14 15 16 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package policy import ( | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package policy import ( "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/config" "zettelstore.de/z/zettel/meta" ) type ownerPolicy struct { manager auth.AuthzManager |
︙ | ︙ |
Changes to auth/policy/policy_test.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package policy import ( "fmt" "testing" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package policy import ( "fmt" "testing" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func TestPolicies(t *testing.T) { t.Parallel() |
︙ | ︙ |
Changes to box/box.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | import ( "context" "errors" "fmt" "io" "time" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import ( "context" "errors" "fmt" "io" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/query" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // BaseBox is implemented by all Zettel boxes. |
︙ | ︙ |
Changes to box/compbox/compbox.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | // Package compbox provides zettel that have computed content. package compbox import ( "context" "net/url" | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // Package compbox provides zettel that have computed content. package compbox import ( "context" "net/url" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/box/manager" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/query" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" |
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | meta func(id.Zid) *meta.Meta content func(*meta.Meta) []byte }{ id.MustParse(api.ZidVersion): {genVersionBuildM, genVersionBuildC}, id.MustParse(api.ZidHost): {genVersionHostM, genVersionHostC}, id.MustParse(api.ZidOperatingSystem): {genVersionOSM, genVersionOSC}, id.MustParse(api.ZidLog): {genLogM, genLogC}, id.MustParse(api.ZidBoxManager): {genManagerM, genManagerC}, id.MustParse(api.ZidMetadataKey): {genKeysM, genKeysC}, id.MustParse(api.ZidParser): {genParserM, genParserC}, id.MustParse(api.ZidStartupConfiguration): {genConfigZettelM, genConfigZettelC}, } // Get returns the one program box. | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | meta func(id.Zid) *meta.Meta content func(*meta.Meta) []byte }{ id.MustParse(api.ZidVersion): {genVersionBuildM, genVersionBuildC}, id.MustParse(api.ZidHost): {genVersionHostM, genVersionHostC}, id.MustParse(api.ZidOperatingSystem): {genVersionOSM, genVersionOSC}, id.MustParse(api.ZidLog): {genLogM, genLogC}, id.MustParse(api.ZidMemory): {genMemoryM, genMemoryC}, id.MustParse(api.ZidBoxManager): {genManagerM, genManagerC}, id.MustParse(api.ZidMetadataKey): {genKeysM, genKeysC}, id.MustParse(api.ZidParser): {genParserM, genParserC}, id.MustParse(api.ZidStartupConfiguration): {genConfigZettelM, genConfigZettelC}, } // Get returns the one program box. |
︙ | ︙ |
Changes to box/compbox/config.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package compbox import ( "bytes" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package compbox import ( "bytes" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func genConfigZettelM(zid id.Zid) *meta.Meta { if myConfig == nil { |
︙ | ︙ |
Changes to box/compbox/keys.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package compbox import ( "bytes" "fmt" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package compbox import ( "bytes" "fmt" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func genKeysM(zid id.Zid) *meta.Meta { m := meta.New(zid) |
︙ | ︙ |
Changes to box/compbox/log.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package compbox import ( "bytes" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package compbox import ( "bytes" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func genLogM(zid id.Zid) *meta.Meta { m := meta.New(zid) |
︙ | ︙ |
Changes to box/compbox/manager.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package compbox import ( "bytes" "fmt" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package compbox import ( "bytes" "fmt" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func genManagerM(zid id.Zid) *meta.Meta { m := meta.New(zid) |
︙ | ︙ |
Added box/compbox/memory.go.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | //----------------------------------------------------------------------------- // Copyright (c) 2024-present Detlef Stern // // This file is part of Zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. // // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2024-present Detlef Stern //----------------------------------------------------------------------------- package compbox import ( "bytes" "fmt" "os" "runtime" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func genMemoryM(zid id.Zid) *meta.Meta { if myConfig == nil { return nil } m := meta.New(zid) m.Set(api.KeyTitle, "Zettelstore Memory") m.Set(api.KeyCreated, kernel.Main.GetConfig(kernel.CoreService, kernel.CoreStarted).(string)) m.Set(api.KeyVisibility, api.ValueVisibilityExpert) return m } func genMemoryC(*meta.Meta) []byte { pageSize := os.Getpagesize() var m runtime.MemStats runtime.GC() runtime.ReadMemStats(&m) var buf bytes.Buffer buf.WriteString("|=Name|=Value>\n") fmt.Fprintf(&buf, "|Page Size|%d\n", pageSize) fmt.Fprintf(&buf, "|Pages|%d\n", m.HeapSys/uint64(pageSize)) fmt.Fprintf(&buf, "|Heap Objects|%d\n", m.HeapObjects) fmt.Fprintf(&buf, "|Heap Sys (KiB)|%d\n", m.HeapSys/1024) fmt.Fprintf(&buf, "|Heap Inuse (KiB)|%d\n", m.HeapInuse/1024) debug := kernel.Main.GetConfig(kernel.CoreService, kernel.CoreDebug).(bool) if debug { for i, bysize := range m.BySize { fmt.Fprintf(&buf, "|Size %2d: %d|%d - %d → %d\n", i, bysize.Size, bysize.Mallocs, bysize.Frees, bysize.Mallocs-bysize.Frees) } } return buf.Bytes() } |
Changes to box/compbox/parser.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "bytes" "fmt" "sort" "strings" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "bytes" "fmt" "sort" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func genParserM(zid id.Zid) *meta.Meta { |
︙ | ︙ |
Changes to box/compbox/version.go.
︙ | ︙ | |||
10 11 12 13 14 15 16 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package compbox import ( | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- package compbox import ( "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func getVersionMeta(zid id.Zid, title string) *meta.Meta { m := meta.New(zid) |
︙ | ︙ |
Changes to box/constbox/constbox.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package constbox import ( "context" _ "embed" // Allow to embed file content "net/url" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package constbox import ( "context" _ "embed" // Allow to embed file content "net/url" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/box/manager" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/query" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" |
︙ | ︙ | |||
168 169 170 171 172 173 174 | api.KeyTitle: "Zettelstore Dependencies", api.KeyRole: api.ValueRoleConfiguration, api.KeySyntax: meta.SyntaxZmk, api.KeyLang: api.ValueLangEN, api.KeyReadOnly: api.ValueTrue, api.KeyVisibility: api.ValueVisibilityPublic, api.KeyCreated: "20210504135842", | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | api.KeyTitle: "Zettelstore Dependencies", api.KeyRole: api.ValueRoleConfiguration, api.KeySyntax: meta.SyntaxZmk, api.KeyLang: api.ValueLangEN, api.KeyReadOnly: api.ValueTrue, api.KeyVisibility: api.ValueVisibilityPublic, api.KeyCreated: "20210504135842", api.KeyModified: "20240418095500", }, zettel.NewContent(contentDependencies)}, id.BaseTemplateZid: { constHeader{ api.KeyTitle: "Zettelstore Base HTML Template", api.KeyRole: api.ValueRoleConfiguration, api.KeySyntax: meta.SyntaxSxn, |
︙ | ︙ |
Changes to box/constbox/dependencies.zettel.
︙ | ︙ | |||
126 127 128 129 130 131 132 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` | | | | | > > | > > | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` === Sx, SxWebs, Webs, Zettelstore-Client These are companion projects, written by the main developer of Zettelstore. They are published under the same license, [[EUPL v1.2, or later|00000000000004]]. ; URL & Source Sx : [[https://t73f.de/r/sx]] ; URL & Source SxWebs : [[https://t73f.de/r/sxwebs]] ; URL & Source Webs : [[https://t73f.de/r/webs]] ; URL & Source Zettelstore-Client : [[https://t73f.de/r/zsc]] ; License: : European Union Public License, version 1.2 (EUPL v1.2), or later. |
Changes to box/constbox/prelude.sxn.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ;;; ;;; SPDX-License-Identifier: EUPL-1.2 ;;; SPDX-FileCopyrightText: 2023-present Detlef Stern ;;;---------------------------------------------------------------------------- ;;; This zettel contains sxn definitions that are independent of specific ;;; subsystems, such as WebUI, API, or other. It just contains generic code to | | < < < < < < < < < < < < < < < < < | | | < | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ;;; ;;; SPDX-License-Identifier: EUPL-1.2 ;;; SPDX-FileCopyrightText: 2023-present Detlef Stern ;;;---------------------------------------------------------------------------- ;;; This zettel contains sxn definitions that are independent of specific ;;; subsystems, such as WebUI, API, or other. It just contains generic code to ;;; be used in all places. It asumes that the symbols NIL and T are defined. ;; not macro (defmacro not (x) `(if ,x NIL T)) ;; not= macro, to negate an equivalence (defmacro not= args `(not (= ,@args))) ;; let* macro ;; ;; (let* (BINDING ...) EXPR ...), where SYMBOL may occur in later bindings. (defmacro let* (bindings . body) (if (null? bindings) `(begin ,@body) `(let ((,(caar bindings) ,(cadar bindings))) (let* ,(cdr bindings) ,@body)))) ;; cond macro ;; ;; (cond ((COND EXPR) ...)) (defmacro cond clauses (if (null? clauses) () (let* ((clause (car clauses)) (the-cond (car clause))) (if (= the-cond T) `(begin ,@(cdr clause)) `(if ,the-cond (begin ,@(cdr clause)) (cond ,@(cdr clauses))))))) ;; and macro ;; ;; (and EXPR ...) (defmacro and args (cond ((null? args) T) |
︙ | ︙ |
Changes to box/constbox/wuicode.sxn.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ;;; SPDX-License-Identifier: EUPL-1.2 ;;; SPDX-FileCopyrightText: 2023-present Detlef Stern ;;;---------------------------------------------------------------------------- ;; Contains WebUI specific code, but not related to a specific template. ;; wui-list-item returns the argument as a HTML list item. | | | | | | | | | | | | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | ;;; SPDX-License-Identifier: EUPL-1.2 ;;; SPDX-FileCopyrightText: 2023-present Detlef Stern ;;;---------------------------------------------------------------------------- ;; Contains WebUI specific code, but not related to a specific template. ;; wui-list-item returns the argument as a HTML list item. (defun wui-item (s) `(li ,s)) ;; wui-info-meta-table-row takes a pair and translates it into a HTML table row ;; with two columns. (defun wui-info-meta-table-row (p) `(tr (td (@ (class zs-info-meta-key)) ,(car p)) (td (@ (class zs-info-meta-value)) ,(cdr p)))) ;; wui-valid-link translates a local link into a HTML link. A link is a pair ;; (valid . url). If valid is not truish, only the invalid url is returned. (defun wui-valid-link (l) (if (car l) `(li (a (@ (href ,(cdr l))) ,(cdr l))) `(li ,(cdr l)))) ;; wui-link takes a link (title . url) and returns a HTML reference. (defun wui-link (q) `(a (@ (href ,(cdr q))) ,(car q))) ;; wui-item-link taks a pair (text . url) and returns a HTML link inside ;; a list item. (defun wui-item-link (q) `(li ,(wui-link q))) ;; wui-tdata-link taks a pair (text . url) and returns a HTML link inside ;; a table data item. (defun wui-tdata-link (q) `(td ,(wui-link q))) ;; wui-item-popup-link is like 'wui-item-link, but the HTML link will open ;; a new tab / window. (defun wui-item-popup-link (e) `(li (a (@ (href ,e) (target "_blank") (rel "noopener noreferrer")) ,e))) ;; wui-option-value returns a value for an HTML option element. (defun wui-option-value (v) `(option (@ (value ,v)))) ;; wui-datalist returns a HTML datalist with the given HTML identifier and a ;; list of values. (defun wui-datalist (id lst) (if lst `((datalist (@ (id ,id)) ,@(map wui-option-value lst))))) ;; wui-pair-desc-item takes a pair '(term . text) and returns a list with ;; a HTML description term and a HTML description data. (defun wui-pair-desc-item (p) `((dt ,(car p)) (dd ,(cdr p)))) ;; wui-meta-desc returns a HTML description list made from the list of pairs ;; given. (defun wui-meta-desc (l) `(dl ,@(apply append (map wui-pair-desc-item l)))) ;; wui-enc-matrix returns the HTML table of all encodings and parts. (defun wui-enc-matrix (matrix) `(table ,@(map (lambda (row) `(tr (th ,(car row)) ,@(map wui-tdata-link (cdr row)))) matrix))) ;; CSS-ROLE-map is a mapping (pair list, assoc list) of role names to zettel ;; identifier. It is used in the base template to update the metadata of the |
︙ | ︙ |
Changes to box/dirbox/service.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "context" "fmt" "io" "os" "path/filepath" "time" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | "context" "fmt" "io" "os" "path/filepath" "time" "t73f.de/r/zsc/input" "zettelstore.de/z/box/filebox" "zettelstore.de/z/box/notify" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" |
︙ | ︙ |
Changes to box/filebox/filebox.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "errors" "net/url" "path/filepath" "strings" | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "errors" "net/url" "path/filepath" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/box/manager" "zettelstore.de/z/kernel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to box/filebox/zipbox.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "archive/zip" "context" "fmt" "io" "strings" | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "archive/zip" "context" "fmt" "io" "strings" "t73f.de/r/zsc/input" "zettelstore.de/z/box" "zettelstore.de/z/box/notify" "zettelstore.de/z/logger" "zettelstore.de/z/query" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" |
︙ | ︙ |
Changes to box/manager/enrich.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package manager import ( "context" "strconv" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package manager import ( "context" "strconv" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // Enrich computes additional properties and updates the given metadata. func (mgr *Manager) Enrich(ctx context.Context, m *meta.Meta, boxNumber int) { |
︙ | ︙ |
Changes to box/manager/mapstore/mapstore.go.
︙ | ︙ | |||
18 19 20 21 22 23 24 | "context" "fmt" "io" "sort" "strings" "sync" | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | "context" "fmt" "io" "sort" "strings" "sync" "t73f.de/r/zsc/api" "t73f.de/r/zsc/maps" "zettelstore.de/z/box" "zettelstore.de/z/box/manager/store" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) type zettelData struct { |
︙ | ︙ |
Changes to box/notify/entry.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package notify import ( "path/filepath" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package notify import ( "path/filepath" "t73f.de/r/zsc/api" "zettelstore.de/z/parser" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) const ( |
︙ | ︙ |
Changes to cmd/cmd_file.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "context" "flag" "fmt" "io" "os" | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import ( "context" "flag" "fmt" "io" "os" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/encoder" "zettelstore.de/z/parser" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to cmd/cmd_password.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "flag" "fmt" "os" "golang.org/x/term" | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "flag" "fmt" "os" "golang.org/x/term" "t73f.de/r/zsc/api" "zettelstore.de/z/auth/cred" "zettelstore.de/z/zettel/id" ) // ---------- Subcommand: password ------------------------------------------- func cmdPassword(fs *flag.FlagSet) (int, error) { |
︙ | ︙ |
Changes to cmd/command.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package cmd import ( "flag" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package cmd import ( "flag" "t73f.de/r/zsc/maps" "zettelstore.de/z/logger" ) // Command stores information about commands / sub-commands. type Command struct { Name string // command name as it appears on the command line Func CommandFunc // function that executes a command |
︙ | ︙ |
Changes to cmd/main.go.
︙ | ︙ | |||
21 22 23 24 25 26 27 | "net/url" "os" "runtime/debug" "strconv" "strings" "time" | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | "net/url" "os" "runtime/debug" "strconv" "strings" "time" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/auth" "zettelstore.de/z/auth/impl" "zettelstore.de/z/box" "zettelstore.de/z/box/compbox" "zettelstore.de/z/box/manager" "zettelstore.de/z/config" "zettelstore.de/z/kernel" |
︙ | ︙ |
Changes to docs/manual/00001005090000.zettel.
1 2 3 4 5 6 | id: 00001005090000 title: List of predefined zettel role: manual tags: #manual #reference #zettelstore syntax: zmk created: 20210126175322 | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | id: 00001005090000 title: List of predefined zettel role: manual tags: #manual #reference #zettelstore syntax: zmk created: 20210126175322 modified: 20240318115839 The following table lists all predefined zettel with their purpose. |= Identifier :|= Title | Purpose | [[00000000000001]] | Zettelstore Version | Contains the version string of the running Zettelstore | [[00000000000002]] | Zettelstore Host | Contains the name of the computer running the Zettelstore | [[00000000000003]] | Zettelstore Operating System | Contains the operating system and CPU architecture of the computer running the Zettelstore | [[00000000000004]] | Zettelstore License | Lists the license of Zettelstore | [[00000000000005]] | Zettelstore Contributors | Lists all contributors of Zettelstore | [[00000000000006]] | Zettelstore Dependencies | Lists all licensed content | [[00000000000007]] | Zettelstore Log | Lists the last 8192 log messages | [[00000000000008]] | Zettelstore Memory | Some statistics about main memory usage | [[00000000000020]] | Zettelstore Box Manager | Contains some statistics about zettel boxes and the the index process | [[00000000000090]] | Zettelstore Supported Metadata Keys | Contains all supported metadata keys, their [[types|00001006030000]], and more | [[00000000000092]] | Zettelstore Supported Parser | Lists all supported values for metadata [[syntax|00001006020000#syntax]] that are recognized by Zettelstore | [[00000000000096]] | Zettelstore Startup Configuration | Contains the effective values of the [[startup configuration|00001004010000]] | [[00000000000100]] | Zettelstore Runtime Configuration | Allows to [[configure Zettelstore at runtime|00001004020000]] | [[00000000010100]] | Zettelstore Base HTML Template | Contains the general layout of the HTML view | [[00000000010200]] | Zettelstore Login Form HTML Template | Layout of the login form, when authentication is [[enabled|00001010040100]] |
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 | | [[00000000090001]] | New Zettel | Template for a new zettel with role ""[[zettel|00001006020100#zettel]]"" | [[00000000090002]] | New User | Template for a new [[user zettel|00001010040200]] | [[00000000090003]] | New Tag | Template for a new [[tag zettel|00001006020100#tag]] | [[00000000090004]] | New Role | Template for a new [[role zettel|00001006020100#role]] | [[00010000000000]] | Home | Default home zettel, contains some welcome information If a zettel is not linked, it is not accessible for the current user. **Important:** All identifier may change until a stable version of the software is released. | > | 44 45 46 47 48 49 50 51 52 53 | | [[00000000090001]] | New Zettel | Template for a new zettel with role ""[[zettel|00001006020100#zettel]]"" | [[00000000090002]] | New User | Template for a new [[user zettel|00001010040200]] | [[00000000090003]] | New Tag | Template for a new [[tag zettel|00001006020100#tag]] | [[00000000090004]] | New Role | Template for a new [[role zettel|00001006020100#role]] | [[00010000000000]] | Home | Default home zettel, contains some welcome information If a zettel is not linked, it is not accessible for the current user. In most cases, you must at least enable [[''expert-mode''|00001004020000#expert-mode]]. **Important:** All identifier may change until a stable version of the software is released. |
Changes to docs/manual/00001008000000.zettel.
1 2 3 4 5 6 | id: 00001008000000 title: Other Markup Languages role: manual tags: #manual #zettelstore syntax: zmk created: 20210126175300 | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | id: 00001008000000 title: Other Markup Languages role: manual tags: #manual #zettelstore syntax: zmk created: 20210126175300 modified: 20240413160242 [[Zettelmarkup|00001007000000]] is not the only markup language you can use to define your content. Zettelstore is quite agnostic with respect to markup languages. Of course, Zettelmarkup plays an important role. However, with the exception of zettel titles, you can use any (markup) language that is supported: * CSS |
︙ | ︙ | |||
45 46 47 48 49 50 51 | : Only the metadata of a zettel is ""parsed"". Useful for displaying the full metadata. The [[runtime configuration zettel|00000000000100]] uses this syntax. The zettel content is ignored. ; [!svg|''svg''] : [[Scalable Vector Graphics|https://www.w3.org/TR/SVG2/]]. ; [!sxn|''sxn''] | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | : Only the metadata of a zettel is ""parsed"". Useful for displaying the full metadata. The [[runtime configuration zettel|00000000000100]] uses this syntax. The zettel content is ignored. ; [!svg|''svg''] : [[Scalable Vector Graphics|https://www.w3.org/TR/SVG2/]]. ; [!sxn|''sxn''] : S-Expressions, as implemented by [[Sx|https://t73f.de/r/sx]]. Often used to specify templates when rendering a zettel as HTML for the [[web user interface|00001014000000]] (with the help of sxhtml]). ; [!text|''text''], [!plain|''plain''], [!txt|''txt''] : Plain text that must not be interpreted further. ; [!zmk|''zmk''] : [[Zettelmarkup|00001007000000]]. The actual values are also listed in a zettel named [[Zettelstore Supported Parser|00000000000092]]. If you specify something else, your content will be interpreted as plain text. |
Changes to docs/manual/00001012930500.zettel.
1 2 3 4 5 6 | id: 00001012930500 title: Syntax of Symbolic Expressions role: manual tags: #manual #reference #zettelstore syntax: zmk created: 20230403151127 | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | id: 00001012930500 title: Syntax of Symbolic Expressions role: manual tags: #manual #reference #zettelstore syntax: zmk created: 20230403151127 modified: 20240413160345 === Syntax of lists A list always starts with the left parenthesis (""''(''"", U+0028) and ends with a right parenthesis (""'')''"", U+0029). A list may contain a possibly empty sequence of elements, i.e. lists and / or atoms. Internally, lists are composed of __cells__. A cell allows to store two values. |
︙ | ︙ | |||
67 68 69 70 71 72 73 | To allow a string to contain a backslash, it also must be prefixed by one backslash. Unicode characters with a code less than U+FF are encoded by by the sequence ""''\\xNM''"", where ''NM'' is the hex encoding of the character. Unicode characters with a code less than U+FFFF are encoded by by the sequence ""''\\uNMOP''"", where ''NMOP'' is the hex encoding of the character. Unicode characters with a code less than U+FFFFFF are encoded by by the sequence ""''\\UNMOPQR''"", where ''NMOPQR'' is the hex encoding of the character. In addition, the sequence ""''\\t''"" encodes a horizontal tab (U+0009), the sequence ""''\\n''"" encodes a line feed (U+000A). === See also | | | 67 68 69 70 71 72 73 74 75 76 77 | To allow a string to contain a backslash, it also must be prefixed by one backslash. Unicode characters with a code less than U+FF are encoded by by the sequence ""''\\xNM''"", where ''NM'' is the hex encoding of the character. Unicode characters with a code less than U+FFFF are encoded by by the sequence ""''\\uNMOP''"", where ''NMOP'' is the hex encoding of the character. Unicode characters with a code less than U+FFFFFF are encoded by by the sequence ""''\\UNMOPQR''"", where ''NMOPQR'' is the hex encoding of the character. In addition, the sequence ""''\\t''"" encodes a horizontal tab (U+0009), the sequence ""''\\n''"" encodes a line feed (U+000A). === See also * Currently, Zettelstore uses [[Sx|https://t73f.de/r/sx]] (""Symbolic eXpression framework"") to implement symbolic expressions. The project page might contain additional information about the full syntax. Zettelstore only uses lists, numbers, string, and symbols to represent zettel. |
Changes to encoder/encoder.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | package encoder import ( "errors" "fmt" "io" | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package encoder import ( "errors" "fmt" "io" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/zettel/meta" ) // Encoder is an interface that allows to encode different parts of a zettel. type Encoder interface { WriteZettel(io.Writer, *ast.ZettelNode, EvalMetaFunc) (int, error) |
︙ | ︙ |
Changes to encoder/encoder_blob_test.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package encoder_test import ( "testing" | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //----------------------------------------------------------------------------- package encoder_test import ( "testing" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" _ "zettelstore.de/z/parser/blob" // Allow to use BLOB parser. ) |
︙ | ︙ |
Changes to encoder/encoder_test.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package encoder_test import ( "fmt" "strings" "testing" | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package encoder_test import ( "fmt" "strings" "testing" "t73f.de/r/sx/sxreader" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/config" "zettelstore.de/z/encoder" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" _ "zettelstore.de/z/encoder/htmlenc" // Allow to use HTML encoder. |
︙ | ︙ |
Changes to encoder/htmlenc/htmlenc.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | // Package htmlenc encodes the abstract syntax tree into HTML5 via zettelstore-client. package htmlenc import ( "io" "strings" | | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // Package htmlenc encodes the abstract syntax tree into HTML5 via zettelstore-client. package htmlenc import ( "io" "strings" "t73f.de/r/sx" "t73f.de/r/sxwebs/sxhtml" "t73f.de/r/zsc/api" "t73f.de/r/zsc/shtml" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/encoder/szenc" "zettelstore.de/z/encoder/textenc" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ | |||
78 79 80 81 82 83 84 | if err != nil { return 0, err } hen := he.th.Endnotes(&env) var head sx.ListBuilder head.Add(shtml.SymHead) | | | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | if err != nil { return 0, err } hen := he.th.Endnotes(&env) var head sx.ListBuilder head.Add(shtml.SymHead) head.Add(sx.Nil().Cons(sx.Nil().Cons(sx.Cons(sx.MakeSymbol("charset"), sx.MakeString("utf-8"))).Cons(sxhtml.SymAttr)).Cons(shtml.SymMeta)) head.ExtendBang(hm) var sb strings.Builder if hasTitle { he.textEnc.WriteInlines(&sb, &isTitle) } else { sb.Write(zn.Meta.Zid.Bytes()) } head.Add(sx.MakeList(shtml.SymAttrTitle, sx.MakeString(sb.String()))) var body sx.ListBuilder body.Add(shtml.SymBody) if hasTitle { body.Add(htitle.Cons(shtml.SymH1)) } body.ExtendBang(hast) if hen != nil { body.Add(sx.Cons(shtml.SymHR, nil)) body.Add(hen) } doc := sx.MakeList( sxhtml.SymDoctype, sx.MakeList(shtml.SymHtml, head.List(), body.List()), ) gen := sxhtml.NewGenerator().SetNewline() return gen.WriteHTML(w, doc) } // WriteMeta encodes meta data as HTML5. func (he *Encoder) WriteMeta(w io.Writer, m *meta.Meta, evalMeta encoder.EvalMetaFunc) (int, error) { env := shtml.MakeEnvironment(he.lang) hm, err := he.th.Evaluate(he.tx.GetMeta(m, evalMeta), &env) if err != nil { return 0, err } gen := sxhtml.NewGenerator().SetNewline() return gen.WriteListHTML(w, hm) } func (he *Encoder) WriteContent(w io.Writer, zn *ast.ZettelNode) (int, error) { return he.WriteBlocks(w, &zn.Ast) } |
︙ | ︙ |
Changes to encoder/mdenc/mdenc.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | // Package mdenc encodes the abstract syntax tree back into Markdown. package mdenc import ( "io" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Package mdenc encodes the abstract syntax tree back into Markdown. package mdenc import ( "io" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/zettel/meta" ) func init() { encoder.Register(api.EncoderMD, func(*encoder.CreateParameter) encoder.Encoder { return Create() }) |
︙ | ︙ |
Changes to encoder/shtmlenc/shtmlenc.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | // Package shtmlenc encodes the abstract syntax tree into a s-expr which represents HTML. package shtmlenc import ( "io" | | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // Package shtmlenc encodes the abstract syntax tree into a s-expr which represents HTML. package shtmlenc import ( "io" "t73f.de/r/sx" "t73f.de/r/zsc/api" "t73f.de/r/zsc/shtml" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/encoder/szenc" "zettelstore.de/z/zettel/meta" ) func init() { |
︙ | ︙ |
Changes to encoder/szenc/szenc.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | // Package szenc encodes the abstract syntax tree into a s-expr for zettel. package szenc import ( "io" | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // Package szenc encodes the abstract syntax tree into a s-expr for zettel. package szenc import ( "io" "t73f.de/r/sx" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/zettel/meta" ) func init() { encoder.Register(api.EncoderSz, func(*encoder.CreateParameter) encoder.Encoder { return Create() }) |
︙ | ︙ |
Changes to encoder/szenc/transform.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package szenc import ( "encoding/base64" "fmt" "strings" | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package szenc import ( "encoding/base64" "fmt" "strings" "t73f.de/r/sx" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/sz" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/zettel/meta" ) // NewTransformer returns a new transformer to create s-expressions from AST nodes. func NewTransformer() *Transformer { |
︙ | ︙ | |||
44 45 46 47 48 49 50 | return t.getInlineList(*n).Cons(sz.SymInline) case *ast.ParaNode: return t.getInlineList(n.Inlines).Cons(sz.SymPara) case *ast.VerbatimNode: return sx.MakeList( mapGetS(mapVerbatimKindS, n.Kind), getAttributes(n.Attrs), | | | | | | | | | | | | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | return t.getInlineList(*n).Cons(sz.SymInline) case *ast.ParaNode: return t.getInlineList(n.Inlines).Cons(sz.SymPara) case *ast.VerbatimNode: return sx.MakeList( mapGetS(mapVerbatimKindS, n.Kind), getAttributes(n.Attrs), sx.MakeString(string(n.Content)), ) case *ast.RegionNode: return t.getRegion(n) case *ast.HeadingNode: return t.getInlineList(n.Inlines). Cons(sx.MakeString(n.Fragment)). Cons(sx.MakeString(n.Slug)). Cons(getAttributes(n.Attrs)). Cons(sx.Int64(int64(n.Level))). Cons(sz.SymHeading) case *ast.HRuleNode: return sx.MakeList(sz.SymThematic, getAttributes(n.Attrs)) case *ast.NestedListNode: return t.getNestedList(n) case *ast.DescriptionListNode: return t.getDescriptionList(n) case *ast.TableNode: return t.getTable(n) case *ast.TranscludeNode: return sx.MakeList(sz.SymTransclude, getAttributes(n.Attrs), getReference(n.Ref)) case *ast.BLOBNode: return t.getBLOB(n) case *ast.TextNode: return sx.MakeList(sz.SymText, sx.MakeString(n.Text)) case *ast.SpaceNode: if t.inVerse { return sx.MakeList(sz.SymSpace, sx.MakeString(n.Lexeme)) } return sx.MakeList(sz.SymSpace) case *ast.BreakNode: if n.Hard { return sx.MakeList(sz.SymHard) } return sx.MakeList(sz.SymSoft) case *ast.LinkNode: return t.getLink(n) case *ast.EmbedRefNode: return t.getInlineList(n.Inlines). Cons(sx.MakeString(n.Syntax)). Cons(getReference(n.Ref)). Cons(getAttributes(n.Attrs)). Cons(sz.SymEmbed) case *ast.EmbedBLOBNode: return t.getEmbedBLOB(n) case *ast.CiteNode: return t.getInlineList(n.Inlines). Cons(sx.MakeString(n.Key)). Cons(getAttributes(n.Attrs)). Cons(sz.SymCite) case *ast.FootnoteNode: // (ENDNODE attrs InlineElement ...) return t.getInlineList(n.Inlines).Cons(getAttributes(n.Attrs)).Cons(sz.SymEndnote) case *ast.MarkNode: return t.getInlineList(n.Inlines). Cons(sx.MakeString(n.Fragment)). Cons(sx.MakeString(n.Slug)). Cons(sx.MakeString(n.Mark)). Cons(sz.SymMark) case *ast.FormatNode: return t.getInlineList(n.Inlines). Cons(getAttributes(n.Attrs)). Cons(mapGetS(mapFormatKindS, n.Kind)) case *ast.LiteralNode: return sx.MakeList( mapGetS(mapLiteralKindS, n.Kind), getAttributes(n.Attrs), sx.MakeString(string(n.Content)), ) } return sx.MakeList(sz.SymUnknown, sx.MakeString(fmt.Sprintf("%T %v", node, node))) } var mapVerbatimKindS = map[ast.VerbatimKind]*sx.Symbol{ ast.VerbatimZettel: sz.SymVerbatimZettel, ast.VerbatimProg: sz.SymVerbatimProg, ast.VerbatimEval: sz.SymVerbatimEval, ast.VerbatimMath: sz.SymVerbatimMath, |
︙ | ︙ | |||
264 265 266 267 268 269 270 | func (t *Transformer) getCell(cell *ast.TableCell) *sx.Pair { return t.getInlineList(cell.Inlines).Cons(mapGetS(alignmentSymbolS, cell.Align)) } func (t *Transformer) getBLOB(bn *ast.BLOBNode) *sx.Pair { var lastObj sx.Object if bn.Syntax == meta.SyntaxSVG { | | | | | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | func (t *Transformer) getCell(cell *ast.TableCell) *sx.Pair { return t.getInlineList(cell.Inlines).Cons(mapGetS(alignmentSymbolS, cell.Align)) } func (t *Transformer) getBLOB(bn *ast.BLOBNode) *sx.Pair { var lastObj sx.Object if bn.Syntax == meta.SyntaxSVG { lastObj = sx.MakeString(string(bn.Blob)) } else { lastObj = getBase64String(bn.Blob) } return sx.MakeList( sz.SymBLOB, t.getInlineList(bn.Description), sx.MakeString(bn.Syntax), lastObj, ) } var mapRefStateLink = map[ast.RefState]*sx.Symbol{ ast.RefStateInvalid: sz.SymLinkInvalid, ast.RefStateZettel: sz.SymLinkZettel, ast.RefStateSelf: sz.SymLinkSelf, ast.RefStateFound: sz.SymLinkFound, ast.RefStateBroken: sz.SymLinkBroken, ast.RefStateHosted: sz.SymLinkHosted, ast.RefStateBased: sz.SymLinkBased, ast.RefStateQuery: sz.SymLinkQuery, ast.RefStateExternal: sz.SymLinkExternal, } func (t *Transformer) getLink(ln *ast.LinkNode) *sx.Pair { return t.getInlineList(ln.Inlines). Cons(sx.MakeString(ln.Ref.Value)). Cons(getAttributes(ln.Attrs)). Cons(mapGetS(mapRefStateLink, ln.Ref.State)) } func (t *Transformer) getEmbedBLOB(en *ast.EmbedBLOBNode) *sx.Pair { tail := t.getInlineList(en.Inlines) if en.Syntax == meta.SyntaxSVG { tail = tail.Cons(sx.MakeString(string(en.Blob))) } else { tail = tail.Cons(getBase64String(en.Blob)) } return tail.Cons(sx.MakeString(en.Syntax)).Cons(getAttributes(en.Attrs)).Cons(sz.SymEmbedBLOB) } func (t *Transformer) getBlockList(bs *ast.BlockSlice) *sx.Pair { objs := make(sx.Vector, len(*bs)) for i, n := range *bs { objs[i] = t.GetSz(n) } |
︙ | ︙ | |||
327 328 329 330 331 332 333 | func getAttributes(a attrs.Attributes) sx.Object { if a.IsEmpty() { return sx.Nil() } keys := a.Keys() objs := make(sx.Vector, 0, len(keys)) for _, k := range keys { | | | | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | func getAttributes(a attrs.Attributes) sx.Object { if a.IsEmpty() { return sx.Nil() } keys := a.Keys() objs := make(sx.Vector, 0, len(keys)) for _, k := range keys { objs = append(objs, sx.Cons(sx.MakeString(k), sx.MakeString(a[k]))) } return sx.MakeList(objs...) } var mapRefStateS = map[ast.RefState]*sx.Symbol{ ast.RefStateInvalid: sz.SymRefStateInvalid, ast.RefStateZettel: sz.SymRefStateZettel, ast.RefStateSelf: sz.SymRefStateSelf, ast.RefStateFound: sz.SymRefStateFound, ast.RefStateBroken: sz.SymRefStateBroken, ast.RefStateHosted: sz.SymRefStateHosted, ast.RefStateBased: sz.SymRefStateBased, ast.RefStateQuery: sz.SymRefStateQuery, ast.RefStateExternal: sz.SymRefStateExternal, } func getReference(ref *ast.Reference) *sx.Pair { return sx.MakeList(mapGetS(mapRefStateS, ref.State), sx.MakeString(ref.Value)) } var mapMetaTypeS = map[*meta.DescriptionType]*sx.Symbol{ meta.TypeCredential: sz.SymTypeCredential, meta.TypeEmpty: sz.SymTypeEmpty, meta.TypeID: sz.SymTypeID, meta.TypeIDSet: sz.SymTypeIDSet, |
︙ | ︙ | |||
374 375 376 377 378 379 380 | ty := m.Type(key) symType := mapGetS(mapMetaTypeS, ty) var obj sx.Object if ty.IsSet { setList := meta.ListFromValue(p.Value) setObjs := make(sx.Vector, len(setList)) for i, val := range setList { | | | | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | ty := m.Type(key) symType := mapGetS(mapMetaTypeS, ty) var obj sx.Object if ty.IsSet { setList := meta.ListFromValue(p.Value) setObjs := make(sx.Vector, len(setList)) for i, val := range setList { setObjs[i] = sx.MakeString(val) } obj = sx.MakeList(setObjs...) } else if ty == meta.TypeZettelmarkup { is := evalMeta(p.Value) obj = t.getInlineList(is) } else { obj = sx.MakeString(p.Value) } objs = append(objs, sx.Nil().Cons(obj).Cons(sx.MakeSymbol(key)).Cons(symType)) } return sx.MakeList(objs...).Cons(sz.SymMeta) } func mapGetS[T comparable](m map[T]*sx.Symbol, k T) *sx.Symbol { |
︙ | ︙ | |||
403 404 405 406 407 408 409 | var sb strings.Builder encoder := base64.NewEncoder(base64.StdEncoding, &sb) _, err := encoder.Write(data) if err == nil { err = encoder.Close() } if err == nil { | | | | 403 404 405 406 407 408 409 410 411 412 413 | var sb strings.Builder encoder := base64.NewEncoder(base64.StdEncoding, &sb) _, err := encoder.Write(data) if err == nil { err = encoder.Close() } if err == nil { return sx.MakeString(sb.String()) } return sx.MakeString("") } |
Changes to encoder/textenc/textenc.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | // Package textenc encodes the abstract syntax tree into its text. package textenc import ( "io" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Package textenc encodes the abstract syntax tree into its text. package textenc import ( "io" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/zettel/meta" ) func init() { encoder.Register(api.EncoderText, func(*encoder.CreateParameter) encoder.Encoder { return Create() }) |
︙ | ︙ |
Changes to encoder/zmkenc/zmkenc.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package zmkenc import ( "fmt" "io" "strings" | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package zmkenc import ( "fmt" "io" "strings" "t73f.de/r/zsc/api" "t73f.de/r/zsc/attrs" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/encoder/textenc" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to encoding/atom/atom.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | // Package atom provides an Atom encoding. package atom import ( "bytes" "time" | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // Package atom provides an Atom encoding. package atom import ( "bytes" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/config" "zettelstore.de/z/encoding" "zettelstore.de/z/encoding/xml" "zettelstore.de/z/kernel" "zettelstore.de/z/query" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/id" |
︙ | ︙ |
Changes to encoding/encoding.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | // Package encoding provides helper functions for encodings. package encoding import ( "time" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Package encoding provides helper functions for encodings. package encoding import ( "time" "t73f.de/r/zsc/api" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // LastUpdated returns the formated time of the zettel which was updated at the latest time. func LastUpdated(ml []*meta.Meta, timeFormat string) string { |
︙ | ︙ |
Changes to encoding/rss/rss.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package rss import ( "bytes" "context" "time" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package rss import ( "bytes" "context" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/config" "zettelstore.de/z/encoding" "zettelstore.de/z/encoding/xml" "zettelstore.de/z/kernel" "zettelstore.de/z/query" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/id" |
︙ | ︙ |
Changes to evaluator/evaluator.go.
︙ | ︙ | |||
19 20 21 22 23 24 25 | "context" "errors" "fmt" "path" "strconv" "strings" | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | "context" "errors" "fmt" "path" "strconv" "strings" "t73f.de/r/sx/sxbuiltins" "t73f.de/r/sx/sxreader" "t73f.de/r/zsc/api" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/box" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/parser/cleaner" "zettelstore.de/z/parser/draw" "zettelstore.de/z/query" |
︙ | ︙ |
Changes to evaluator/list.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "bytes" "context" "math" "sort" "strconv" "strings" | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | "bytes" "context" "math" "sort" "strconv" "strings" "t73f.de/r/zsc/api" "t73f.de/r/zsc/attrs" "zettelstore.de/z/ast" "zettelstore.de/z/config" "zettelstore.de/z/encoding/atom" "zettelstore.de/z/encoding/rss" "zettelstore.de/z/parser" "zettelstore.de/z/query" "zettelstore.de/z/zettel/meta" |
︙ | ︙ |
Changes to go.mod.
1 2 3 4 5 6 | module zettelstore.de/z go 1.22 require ( github.com/fsnotify/fsnotify v1.7.0 | | | | | > | > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | module zettelstore.de/z go 1.22 require ( github.com/fsnotify/fsnotify v1.7.0 github.com/yuin/goldmark v1.7.1 golang.org/x/crypto v0.22.0 golang.org/x/term v0.19.0 golang.org/x/text v0.14.0 t73f.de/r/sx v0.0.0-20240418072254-b6eff7d787f9 t73f.de/r/sxwebs v0.0.0-20240422143910-320427142398 t73f.de/r/zsc v0.0.0-20240422145115-3bbfcfd9394c ) require ( golang.org/x/sys v0.19.0 // indirect t73f.de/r/webs v0.0.0-20240422103534-8f5067bc11bc // indirect ) |
Changes to go.sum.
1 2 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= | | | | | | | | | | | > > | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= t73f.de/r/sx v0.0.0-20240418072254-b6eff7d787f9 h1:lVPkYN8+J9f6JA9SmoF6icvpLxz4u3h1MCTuDYJYwdU= t73f.de/r/sx v0.0.0-20240418072254-b6eff7d787f9/go.mod h1:G9pD1j2R6y9ZkPBb81mSnmwaAvTOg7r6jKp/OF7WeFA= t73f.de/r/sxwebs v0.0.0-20240422143910-320427142398 h1:/G054FNxS8zEYbdhOTNk+GhdhjWBVt398FTm1Ud4A4o= t73f.de/r/sxwebs v0.0.0-20240422143910-320427142398/go.mod h1:PtIkpRfTTiQITciKaWcTiAwy9FJ63WSQKciTp/dJbOA= t73f.de/r/webs v0.0.0-20240422103534-8f5067bc11bc h1:i6tm/AEJUs8J8m7iDP8bTZgM0wYERh97RR47soJglxs= t73f.de/r/webs v0.0.0-20240422103534-8f5067bc11bc/go.mod h1:UGAAtul0TK5ACeZ6zTS3SX6GqwMFXxlUpHiV8oqNq5w= t73f.de/r/zsc v0.0.0-20240422145115-3bbfcfd9394c h1:TOvMeqVXG5s1Rj2a2q3r1+K8LlS9fHruMon0n7Aw5qM= t73f.de/r/zsc v0.0.0-20240422145115-3bbfcfd9394c/go.mod h1:YdsjqbI1th0bJoMclgbNycJUVr8ovAV02ZgA91uOhkU= |
Changes to kernel/impl/cfg.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "context" "errors" "fmt" "strconv" "strings" "sync" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | "context" "errors" "fmt" "strconv" "strings" "sync" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/config" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" |
︙ | ︙ |
Changes to kernel/impl/cmd.go.
︙ | ︙ | |||
18 19 20 21 22 23 24 | "io" "os" "runtime/metrics" "sort" "strconv" "strings" | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | "io" "os" "runtime/metrics" "sort" "strconv" "strings" "t73f.de/r/zsc/maps" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/strfun" ) type cmdSession struct { w io.Writer |
︙ | ︙ |
Changes to kernel/impl/config.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "errors" "fmt" "sort" "strconv" "strings" "sync" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | "errors" "fmt" "sort" "strconv" "strings" "sync" "t73f.de/r/zsc/maps" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/zettel/id" ) type parseFunc func(string) (any, error) type configDescription struct { |
︙ | ︙ |
Changes to kernel/impl/core.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "fmt" "net" "os" "runtime" "sync" "time" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | "fmt" "net" "os" "runtime" "sync" "time" "t73f.de/r/zsc/maps" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/id" ) type coreService struct { |
︙ | ︙ |
Changes to logger/message.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "context" "net/http" "strconv" "sync" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "context" "net/http" "strconv" "sync" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" ) // Message presents a message to log. type Message struct { logger *Logger level Level |
︙ | ︙ |
Changes to parser/blob/blob.go.
︙ | ︙ | |||
11 12 13 14 15 16 17 | // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- // Package blob provides a parser of binary data. package blob import ( | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- // Package blob provides a parser of binary data. package blob import ( "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func init() { parser.Register(&parser.Info{ |
︙ | ︙ |
Changes to parser/draw/draw.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | // It is not a parser registered by the general parser framework (directed by // metadata "syntax" of a zettel). It will be used when a zettel is evaluated. package draw import ( "strconv" | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // It is not a parser registered by the general parser framework (directed by // metadata "syntax" of a zettel). It will be used when a zettel is evaluated. package draw import ( "strconv" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func init() { parser.Register(&parser.Info{ |
︙ | ︙ |
Changes to parser/draw/draw_test.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package draw_test import ( "testing" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //----------------------------------------------------------------------------- package draw_test import ( "testing" "t73f.de/r/zsc/input" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func FuzzParseBlocks(f *testing.F) { f.Fuzz(func(t *testing.T, src []byte) { t.Parallel() inp := input.NewInput(src) parser.ParseBlocks(inp, nil, meta.SyntaxDraw, config.NoHTML) }) } |
Changes to parser/markdown/markdown.go.
︙ | ︙ | |||
20 21 22 23 24 25 26 | "strconv" "strings" gm "github.com/yuin/goldmark" gmAst "github.com/yuin/goldmark/ast" gmText "github.com/yuin/goldmark/text" | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | "strconv" "strings" gm "github.com/yuin/goldmark" gmAst "github.com/yuin/goldmark/ast" gmText "github.com/yuin/goldmark/text" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/encoder/textenc" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func init() { |
︙ | ︙ |
Changes to parser/none/none.go.
︙ | ︙ | |||
11 12 13 14 15 16 17 | // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- // Package none provides a none-parser, e.g. for zettel with just metadata. package none import ( | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // SPDX-FileCopyrightText: 2020-present Detlef Stern //----------------------------------------------------------------------------- // Package none provides a none-parser, e.g. for zettel with just metadata. package none import ( "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func init() { parser.Register(&parser.Info{ |
︙ | ︙ |
Changes to parser/parser.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package parser import ( "context" "fmt" "strings" | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package parser import ( "context" "fmt" "strings" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/config" "zettelstore.de/z/parser/cleaner" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to parser/plain/plain.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | // Package plain provides a parser for plain text data. package plain import ( "bytes" "strings" | > | | < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // Package plain provides a parser for plain text data. package plain import ( "bytes" "strings" "t73f.de/r/sx/sxreader" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func init() { parser.Register(&parser.Info{ |
︙ | ︙ |
Changes to parser/zettelmark/block.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package zettelmark import ( "fmt" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package zettelmark import ( "fmt" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" ) // parseBlockSlice parses a sequence of blocks. func (cp *zmkP) parseBlockSlice() ast.BlockSlice { inp := cp.inp var lastPara *ast.ParaNode |
︙ | ︙ |
Changes to parser/zettelmark/inline.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package zettelmark import ( "bytes" "fmt" "strings" | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package zettelmark import ( "bytes" "fmt" "strings" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/zettel/meta" ) // parseInlineSlice parses a sequence of Inlines until EOS. func (cp *zmkP) parseInlineSlice() (ins ast.InlineSlice) { inp := cp.inp |
︙ | ︙ |
Changes to parser/zettelmark/zettelmark.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | // Package zettelmark provides a parser for zettelmarkup. package zettelmark import ( "strings" "unicode" | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // Package zettelmark provides a parser for zettelmarkup. package zettelmark import ( "strings" "unicode" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func init() { parser.Register(&parser.Info{ |
︙ | ︙ |
Changes to parser/zettelmark/zettelmark_fuzz_test.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package zettelmark_test import ( "testing" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //----------------------------------------------------------------------------- package zettelmark_test import ( "testing" "t73f.de/r/zsc/input" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) func FuzzParseBlocks(f *testing.F) { f.Fuzz(func(t *testing.T, src []byte) { t.Parallel() inp := input.NewInput(src) parser.ParseBlocks(inp, nil, meta.SyntaxZmk, config.NoHTML) }) } |
Changes to parser/zettelmark/zettelmark_test.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package zettelmark_test import ( "fmt" "strings" "testing" | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package zettelmark_test import ( "fmt" "strings" "testing" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) type TestCase struct{ source, want string } |
︙ | ︙ |
Changes to query/context.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package query import ( "container/heap" "context" "math" | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package query import ( "container/heap" "context" "math" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // ContextSpec contains all specification values for calculating a context. type ContextSpec struct { Direction ContextDirection |
︙ | ︙ |
Changes to query/parser.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package query import ( "strconv" | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //----------------------------------------------------------------------------- package query import ( "strconv" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // Parse the query specification and return a Query object. func Parse(spec string) (q *Query) { return q.Parse(spec) } |
︙ | ︙ |
Changes to query/print.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package query import ( "io" "strconv" "strings" | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package query import ( "io" "strconv" "strings" "t73f.de/r/zsc/api" "t73f.de/r/zsc/maps" "zettelstore.de/z/zettel/id" ) var op2string = map[compareOp]string{ cmpExist: api.ExistOperator, cmpNotExist: api.ExistNotOperator, cmpEqual: api.SearchOperatorEqual, |
︙ | ︙ |
Changes to query/select_test.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package query_test import ( "context" "testing" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package query_test import ( "context" "testing" "t73f.de/r/zsc/api" "zettelstore.de/z/query" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func TestMatchZidNegate(t *testing.T) { q := query.Parse(api.KeyID + api.SearchOperatorHasNot + string(api.ZidVersion) + " " + api.KeyID + api.SearchOperatorHasNot + string(api.ZidLicense)) |
︙ | ︙ |
Changes to query/sorter.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package query import ( "strconv" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package query import ( "strconv" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/meta" ) type sortFunc func(i, j int) bool func createSortFunc(order []sortOrder, ml []*meta.Meta) sortFunc { hasID := false |
︙ | ︙ |
Changes to query/specs.go.
︙ | ︙ | |||
9 10 11 12 13 14 15 | // // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2023-present Detlef Stern //----------------------------------------------------------------------------- package query | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2023-present Detlef Stern //----------------------------------------------------------------------------- package query import "t73f.de/r/zsc/api" // IdentSpec contains all specification values to calculate the ident directive. type IdentSpec struct{} func (spec *IdentSpec) Print(pe *PrintEnv) { pe.printSpace() pe.writeString(api.IdentDirective) |
︙ | ︙ |
Changes to query/unlinked.go.
︙ | ︙ | |||
10 11 12 13 14 15 16 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2023-present Detlef Stern //----------------------------------------------------------------------------- package query import ( | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // SPDX-License-Identifier: EUPL-1.2 // SPDX-FileCopyrightText: 2023-present Detlef Stern //----------------------------------------------------------------------------- package query import ( "t73f.de/r/zsc/api" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/meta" ) // UnlinkedSpec contains all specification values to calculate unlinked references. type UnlinkedSpec struct { words []string |
︙ | ︙ |
Changes to tests/client/client_test.go.
︙ | ︙ | |||
21 22 23 24 25 26 27 | "io" "net/http" "net/url" "slices" "strconv" "testing" | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | "io" "net/http" "net/url" "slices" "strconv" "testing" "t73f.de/r/zsc/api" "t73f.de/r/zsc/client" "zettelstore.de/z/kernel" ) func nextZid(zid api.ZettelID) api.ZettelID { numVal, err := strconv.ParseUint(string(zid), 10, 64) if err != nil { panic(err) |
︙ | ︙ | |||
50 51 52 53 54 55 56 | } } } func TestListZettel(t *testing.T) { const ( | | | | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | } } } func TestListZettel(t *testing.T) { const ( ownerZettel = 56 configRoleZettel = 34 writerZettel = ownerZettel - 25 readerZettel = ownerZettel - 25 creatorZettel = 10 publicZettel = 5 ) testdata := []struct { user string exp int |
︙ | ︙ |
Changes to tests/client/crud_test.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package client_test import ( "context" "strings" "testing" | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package client_test import ( "context" "strings" "testing" "t73f.de/r/zsc/api" "t73f.de/r/zsc/client" ) // --------------------------------------------------------------------------- // Tests that change the Zettelstore must nor run parallel to other tests. func TestCreateGetRenameDeleteZettel(t *testing.T) { // Is not to be allowed to run in parallel with other tests. |
︙ | ︙ |
Changes to tests/client/embed_test.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package client_test import ( "context" "strings" "testing" | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package client_test import ( "context" "strings" "testing" "t73f.de/r/zsc/api" ) const ( abcZid = api.ZettelID("20211020121000") abc10Zid = api.ZettelID("20211020121100") ) |
︙ | ︙ |
Changes to tests/markdown_test.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "bytes" "encoding/json" "fmt" "os" "strings" "testing" | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | "bytes" "encoding/json" "fmt" "os" "strings" "testing" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/ast" "zettelstore.de/z/config" "zettelstore.de/z/encoder" _ "zettelstore.de/z/encoder/htmlenc" _ "zettelstore.de/z/encoder/mdenc" _ "zettelstore.de/z/encoder/shtmlenc" _ "zettelstore.de/z/encoder/szenc" |
︙ | ︙ |
Changes to tests/naughtystrings_test.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "bufio" "io" "os" "path/filepath" "testing" | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import ( "bufio" "io" "os" "path/filepath" "testing" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" _ "zettelstore.de/z/cmd" "zettelstore.de/z/encoder" "zettelstore.de/z/parser" "zettelstore.de/z/zettel/meta" ) // Test all parser / encoder with a list of "naughty strings", i.e. unusual strings |
︙ | ︙ |
Changes to tests/regression_test.go.
︙ | ︙ | |||
20 21 22 23 24 25 26 | "io" "net/url" "os" "path/filepath" "strings" "testing" | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | "io" "net/url" "os" "path/filepath" "strings" "testing" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/box" "zettelstore.de/z/box/manager" "zettelstore.de/z/config" "zettelstore.de/z/encoder" "zettelstore.de/z/kernel" "zettelstore.de/z/parser" |
︙ | ︙ |
Changes to tools/build/build.go.
︙ | ︙ | |||
22 23 24 25 26 27 28 | "io" "io/fs" "os" "path/filepath" "strings" "time" | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | "io" "io/fs" "os" "path/filepath" "strings" "time" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/strfun" "zettelstore.de/z/tools" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func readVersionFile() (string, error) { |
︙ | ︙ |
Changes to tools/htmllint/htmllint.go.
︙ | ︙ | |||
21 22 23 24 25 26 27 | "math/rand/v2" "net/url" "os" "regexp" "sort" "strings" | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | "math/rand/v2" "net/url" "os" "regexp" "sort" "strings" "t73f.de/r/zsc/api" "t73f.de/r/zsc/client" "zettelstore.de/z/tools" ) func main() { flag.BoolVar(&tools.Verbose, "v", false, "Verbose output") flag.Parse() |
︙ | ︙ |
Changes to tools/tools.go.
︙ | ︙ | |||
23 24 25 26 27 28 29 | "os/exec" "strings" "zettelstore.de/z/strfun" ) var EnvDirectProxy = []string{"GOPROXY=direct"} | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | "os/exec" "strings" "zettelstore.de/z/strfun" ) var EnvDirectProxy = []string{"GOPROXY=direct"} var EnvGoVCS = []string{"GOVCS=zettelstore.de:fossil,t73f.de:fossil"} var Verbose bool func ExecuteCommand(env []string, name string, arg ...string) (string, error) { LogCommand("EXEC", env, name, arg) var out strings.Builder cmd := PrepareCommand(env, name, arg, nil, &out, os.Stderr) err := cmd.Run() |
︙ | ︙ |
Changes to usecase/authenticate.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "context" "math/rand/v2" "net/http" "time" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "context" "math/rand/v2" "net/http" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/auth/cred" "zettelstore.de/z/logger" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to usecase/create_zettel.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package usecase import ( "context" "time" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package usecase import ( "context" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/config" "zettelstore.de/z/logger" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to usecase/get_special_zettel.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package usecase import ( "context" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package usecase import ( "context" "t73f.de/r/zsc/api" "zettelstore.de/z/query" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // TagZettel is the usecase of retrieving a "tag zettel", i.e. a zettel that |
︙ | ︙ |
Changes to usecase/get_user.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package usecase import ( "context" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package usecase import ( "context" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/box" "zettelstore.de/z/query" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to usecase/lists.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package usecase import ( "context" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package usecase import ( "context" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/parser" "zettelstore.de/z/query" "zettelstore.de/z/zettel/meta" ) // -------- List syntax ------------------------------------------------------ |
︙ | ︙ |
Changes to usecase/query.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "context" "errors" "fmt" "strings" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "context" "errors" "fmt" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/box" "zettelstore.de/z/collect" "zettelstore.de/z/parser" "zettelstore.de/z/query" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel" |
︙ | ︙ |
Changes to usecase/update_zettel.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package usecase import ( "context" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package usecase import ( "context" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/logger" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to web/adapter/adapter.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | // Package adapter provides handlers for web requests, and some helper tools. package adapter import ( "context" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Package adapter provides handlers for web requests, and some helper tools. package adapter import ( "context" "t73f.de/r/zsc/api" "zettelstore.de/z/usecase" "zettelstore.de/z/zettel/meta" ) // TryReIndex executes a re-index if the appropriate query action is given. func TryReIndex(ctx context.Context, actions []string, metaSeq []*meta.Meta, reIndex *usecase.ReIndex) ([]string, error) { if lenActions := len(actions); lenActions > 0 { |
︙ | ︙ |
Changes to web/adapter/api/api.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "bytes" "context" "net/http" "time" | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "bytes" "context" "net/http" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/config" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel/meta" |
︙ | ︙ |
Changes to web/adapter/api/command.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package api import ( "context" "net/http" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package api import ( "context" "net/http" "t73f.de/r/zsc/api" "zettelstore.de/z/usecase" ) // MakePostCommandHandler creates a new HTTP handler to execute certain commands. func (a *API) MakePostCommandHandler( ucIsAuth *usecase.IsAuthenticated, ucRefresh *usecase.Refresh, |
︙ | ︙ |
Changes to web/adapter/api/create_zettel.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package api import ( "net/http" | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //----------------------------------------------------------------------------- package api import ( "net/http" "t73f.de/r/sx" "t73f.de/r/zsc/api" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/content" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" ) |
︙ | ︙ |
Changes to web/adapter/api/get_data.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package api import ( "net/http" | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | //----------------------------------------------------------------------------- package api import ( "net/http" "t73f.de/r/sx" "zettelstore.de/z/usecase" "zettelstore.de/z/zettel/id" ) // MakeGetDataHandler creates a new HTTP handler to return zettelstore data. func (a *API) MakeGetDataHandler(ucVersion usecase.Version) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { version := ucVersion.Run() err := a.writeObject(w, id.Invalid, sx.MakeList( sx.Int64(version.Major), sx.Int64(version.Minor), sx.Int64(version.Patch), sx.MakeString(version.Info), sx.MakeString(version.Hash), )) if err != nil { a.log.Error().Err(err).Msg("Write Version Info") } } } |
Changes to web/adapter/api/get_zettel.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "bytes" "context" "fmt" "net/http" | | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import ( "bytes" "context" "fmt" "net/http" "t73f.de/r/sx" "t73f.de/r/zsc/api" "t73f.de/r/zsc/sexp" "zettelstore.de/z/ast" "zettelstore.de/z/box" "zettelstore.de/z/encoder" "zettelstore.de/z/parser" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/content" |
︙ | ︙ |
Changes to web/adapter/api/login.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package api import ( "net/http" "time" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package api import ( "net/http" "time" "t73f.de/r/sx" "zettelstore.de/z/auth" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/zettel/id" ) // MakePostLoginHandler creates a new HTTP handler to authenticate the given user via API. |
︙ | ︙ | |||
99 100 101 102 103 104 105 | a.log.Error().Err(err).Msg("Write renewed token") } } } func (a *API) writeToken(w http.ResponseWriter, token string, lifetime time.Duration) error { return a.writeObject(w, id.Invalid, sx.MakeList( | | | | 99 100 101 102 103 104 105 106 107 108 109 110 | a.log.Error().Err(err).Msg("Write renewed token") } } } func (a *API) writeToken(w http.ResponseWriter, token string, lifetime time.Duration) error { return a.writeObject(w, id.Invalid, sx.MakeList( sx.MakeString("Bearer"), sx.MakeString(token), sx.Int64(int64(lifetime/time.Second)), )) } |
Changes to web/adapter/api/query.go.
︙ | ︙ | |||
18 19 20 21 22 23 24 | "fmt" "io" "net/http" "net/url" "strconv" "strings" | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | "fmt" "io" "net/http" "net/url" "strconv" "strings" "t73f.de/r/sx" "t73f.de/r/zsc/api" "t73f.de/r/zsc/sexp" "zettelstore.de/z/query" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/content" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ | |||
212 213 214 215 216 217 218 | }) msz = sx.Cons(sx.MakeList(symID, sx.Int64(m.Zid)), msz.Cdr()).Cons(symZettel) result[i+1] = msz } _, err := sx.Print(w, sx.MakeList( sx.MakeSymbol("meta-list"), | | | | | | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | }) msz = sx.Cons(sx.MakeList(symID, sx.Int64(m.Zid)), msz.Cdr()).Cons(symZettel) result[i+1] = msz } _, err := sx.Print(w, sx.MakeList( sx.MakeSymbol("meta-list"), sx.MakeList(sx.MakeSymbol("query"), sx.MakeString(dze.sq.String())), sx.MakeList(sx.MakeSymbol("human"), sx.MakeString(dze.sq.Human())), sx.MakeList(result...), )) return err } func (dze *dataZettelEncoder) writeArrangement(w io.Writer, act string, arr meta.Arrangement) error { result := sx.Nil() for aggKey, metaList := range arr { sxMeta := sx.Nil() for i := len(metaList) - 1; i >= 0; i-- { sxMeta = sxMeta.Cons(sx.Int64(metaList[i].Zid)) } sxMeta = sxMeta.Cons(sx.MakeString(aggKey)) result = result.Cons(sxMeta) } _, err := sx.Print(w, sx.MakeList( sx.MakeSymbol("aggregate"), sx.MakeString(act), sx.MakeList(sx.MakeSymbol("query"), sx.MakeString(dze.sq.String())), sx.MakeList(sx.MakeSymbol("human"), sx.MakeString(dze.sq.Human())), result.Cons(sx.SymbolList), )) return err } func (a *API) handleTagZettel(w http.ResponseWriter, r *http.Request, tagZettel *usecase.TagZettel, vals url.Values) bool { tag := vals.Get(api.QueryKeyTag) |
︙ | ︙ |
Changes to web/adapter/api/rename_zettel.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package api import ( "net/http" "net/url" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package api import ( "net/http" "net/url" "t73f.de/r/zsc/api" "zettelstore.de/z/usecase" "zettelstore.de/z/zettel/id" ) // MakeRenameZettelHandler creates a new HTTP handler to update a zettel. func (a *API) MakeRenameZettelHandler(renameZettel *usecase.RenameZettel) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { |
︙ | ︙ |
Changes to web/adapter/api/request.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package api import ( "io" "net/http" "net/url" | | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package api import ( "io" "net/http" "net/url" "t73f.de/r/sx/sxreader" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "t73f.de/r/zsc/sexp" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // getEncoding returns the data encoding selected by the caller. func getEncoding(r *http.Request, q url.Values) (api.EncodingEnum, string) { |
︙ | ︙ |
Changes to web/adapter/api/response.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package api import ( "bytes" "net/http" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package api import ( "bytes" "net/http" "t73f.de/r/sx" "zettelstore.de/z/web/content" "zettelstore.de/z/zettel/id" ) func (a *API) writeObject(w http.ResponseWriter, zid id.Zid, obj sx.Object) error { var buf bytes.Buffer if _, err := sx.Print(&buf, obj); err != nil { |
︙ | ︙ |
Changes to web/adapter/api/update_zettel.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package api import ( "net/http" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package api import ( "net/http" "t73f.de/r/zsc/api" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" ) // MakeUpdateZettelHandler creates a new HTTP handler to update a zettel. |
︙ | ︙ |
Changes to web/adapter/request.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "net/http" "net/url" "strconv" "strings" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "net/http" "net/url" "strconv" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/kernel" "zettelstore.de/z/query" ) // GetCredentialsViaForm retrieves the authentication credentions from a form. func GetCredentialsViaForm(r *http.Request) (ident, cred string, ok bool) { err := r.ParseForm() |
︙ | ︙ |
Changes to web/adapter/response.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "errors" "fmt" "net/http" "strings" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "errors" "fmt" "net/http" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/usecase" ) // WriteData emits the given data to the response writer. func WriteData(w http.ResponseWriter, data []byte, contentType string) error { if len(data) == 0 { |
︙ | ︙ |
Changes to web/adapter/webui/create_zettel.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "bytes" "context" "net/http" "strings" | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "bytes" "context" "net/http" "strings" "t73f.de/r/sx" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/encoder/zmkenc" "zettelstore.de/z/evaluator" "zettelstore.de/z/parser" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/server" |
︙ | ︙ | |||
103 104 105 106 107 108 109 | for _, p := range m.PairsRest() { sb.WriteString(p.Key) sb.WriteString(": ") sb.WriteString(p.Value) sb.WriteByte('\n') } env, rb := wui.createRenderEnv(ctx, "form", wui.rtConfig.Get(ctx, nil, api.KeyLang), title, user) | | | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | for _, p := range m.PairsRest() { sb.WriteString(p.Key) sb.WriteString(": ") sb.WriteString(p.Value) sb.WriteByte('\n') } env, rb := wui.createRenderEnv(ctx, "form", wui.rtConfig.Get(ctx, nil, api.KeyLang), title, user) rb.bindString("heading", sx.MakeString(title)) rb.bindString("form-action-url", sx.MakeString(formActionURL)) rb.bindString("role-data", makeStringList(roleData)) rb.bindString("syntax-data", makeStringList(syntaxData)) rb.bindString("meta", sx.MakeString(sb.String())) if !ztl.Content.IsBinary() { rb.bindString("content", sx.MakeString(ztl.Content.AsString())) } wui.bindCommonZettelData(ctx, &rb, user, m, &ztl.Content) if rb.err == nil { rb.err = wui.renderSxnTemplate(ctx, w, id.FormTemplateZid, env) } if err := rb.err; err != nil { wui.reportError(ctx, w, err) |
︙ | ︙ |
Changes to web/adapter/webui/delete_zettel.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package webui import ( "net/http" | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //----------------------------------------------------------------------------- package webui import ( "net/http" "t73f.de/r/sx" "t73f.de/r/zsc/api" "t73f.de/r/zsc/maps" "zettelstore.de/z/box" "zettelstore.de/z/strfun" "zettelstore.de/z/usecase" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ | |||
47 48 49 50 51 52 53 | m := zs[0].Meta user := server.GetUser(ctx) env, rb := wui.createRenderEnv( ctx, "delete", wui.rtConfig.Get(ctx, nil, api.KeyLang), "Delete Zettel "+m.Zid.String(), user) if len(zs) > 1 { | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | m := zs[0].Meta user := server.GetUser(ctx) env, rb := wui.createRenderEnv( ctx, "delete", wui.rtConfig.Get(ctx, nil, api.KeyLang), "Delete Zettel "+m.Zid.String(), user) if len(zs) > 1 { rb.bindString("shadowed-box", sx.MakeString(zs[1].Meta.GetDefault(api.KeyBoxNumber, "???"))) rb.bindString("incoming", nil) } else { rb.bindString("shadowed-box", nil) rb.bindString("incoming", wui.encodeIncoming(m, wui.makeGetTextTitle(ctx, getZettel))) } wui.bindCommonZettelData(ctx, &rb, user, m, nil) |
︙ | ︙ |
Changes to web/adapter/webui/forms.go.
︙ | ︙ | |||
18 19 20 21 22 23 24 | "errors" "io" "net/http" "regexp" "strings" "unicode" | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | "errors" "io" "net/http" "regexp" "strings" "unicode" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/kernel" "zettelstore.de/z/parser" "zettelstore.de/z/web/content" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ |
Changes to web/adapter/webui/get_info.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "context" "net/http" "sort" "strings" | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import ( "context" "net/http" "sort" "strings" "t73f.de/r/sx" "t73f.de/r/zsc/api" "zettelstore.de/z/ast" "zettelstore.de/z/box" "zettelstore.de/z/collect" "zettelstore.de/z/encoder" "zettelstore.de/z/evaluator" "zettelstore.de/z/parser" "zettelstore.de/z/query" |
︙ | ︙ | |||
65 66 67 68 69 70 71 | return ucEvaluate.RunMetadata(ctx, val) } pairs := zn.Meta.ComputedPairs() metadata := sx.Nil() for i := len(pairs) - 1; i >= 0; i-- { key := pairs[i].Key sxval := wui.writeHTMLMetaValue(key, pairs[i].Value, getTextTitle, evalMeta, enc) | | | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | return ucEvaluate.RunMetadata(ctx, val) } pairs := zn.Meta.ComputedPairs() metadata := sx.Nil() for i := len(pairs) - 1; i >= 0; i-- { key := pairs[i].Key sxval := wui.writeHTMLMetaValue(key, pairs[i].Value, getTextTitle, evalMeta, enc) metadata = metadata.Cons(sx.Cons(sx.MakeString(key), sxval)) } summary := collect.References(zn) locLinks, queryLinks, extLinks := wui.splitLocSeaExtLinks(append(summary.Links, summary.Embeds...)) title := parser.NormalizedSpacedText(zn.InhMeta.GetTitle()) phrase := q.Get(api.QueryKeyPhrase) |
︙ | ︙ | |||
99 100 101 102 103 104 105 | user := server.GetUser(ctx) env, rb := wui.createRenderEnv(ctx, "info", wui.rtConfig.Get(ctx, nil, api.KeyLang), title, user) rb.bindString("metadata", metadata) rb.bindString("local-links", locLinks) rb.bindString("query-links", queryLinks) rb.bindString("ext-links", extLinks) rb.bindString("unlinked-content", unlinkedContent) | | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | user := server.GetUser(ctx) env, rb := wui.createRenderEnv(ctx, "info", wui.rtConfig.Get(ctx, nil, api.KeyLang), title, user) rb.bindString("metadata", metadata) rb.bindString("local-links", locLinks) rb.bindString("query-links", queryLinks) rb.bindString("ext-links", extLinks) rb.bindString("unlinked-content", unlinkedContent) rb.bindString("phrase", sx.MakeString(phrase)) rb.bindString("query-key-phrase", sx.MakeString(api.QueryKeyPhrase)) rb.bindString("enc-eval", wui.infoAPIMatrix(zid, false, encTexts)) rb.bindString("enc-parsed", wui.infoAPIMatrixParsed(zid, encTexts)) rb.bindString("shadow-links", shadowLinks) wui.bindCommonZettelData(ctx, &rb, user, zn.InhMeta, &zn.Content) if rb.err == nil { err = wui.renderSxnTemplate(ctx, w, id.InfoTemplateZid, env) } else { |
︙ | ︙ | |||
125 126 127 128 129 130 131 | ref := links[i] if ref.State == ast.RefStateSelf || ref.IsZettel() { continue } if ref.State == ast.RefStateQuery { queries = queries.Cons( sx.Cons( | | | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | ref := links[i] if ref.State == ast.RefStateSelf || ref.IsZettel() { continue } if ref.State == ast.RefStateQuery { queries = queries.Cons( sx.Cons( sx.MakeString(ref.Value), sx.MakeString(wui.NewURLBuilder('h').AppendQuery(ref.Value).String()))) continue } if ref.IsExternal() { extLinks = extLinks.Cons(sx.MakeString(ref.String())) continue } locLinks = locLinks.Cons(sx.Cons(sx.MakeBoolean(ref.IsValid()), sx.MakeString(ref.String()))) } return locLinks, queries, extLinks } func createUnlinkedQuery(zid id.Zid, phrase string) *query.Query { var sb strings.Builder sb.Write(zid.Bytes()) |
︙ | ︙ | |||
181 182 183 184 185 186 187 | for je := len(encTexts) - 1; je >= 0; je-- { enc := encTexts[je] if parseOnly { u.AppendKVQuery(api.QueryKeyParseOnly, "") } u.AppendKVQuery(api.QueryKeyPart, part) u.AppendKVQuery(api.QueryKeyEncoding, enc) | | | | | | | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | for je := len(encTexts) - 1; je >= 0; je-- { enc := encTexts[je] if parseOnly { u.AppendKVQuery(api.QueryKeyParseOnly, "") } u.AppendKVQuery(api.QueryKeyPart, part) u.AppendKVQuery(api.QueryKeyEncoding, enc) row = row.Cons(sx.Cons(sx.MakeString(enc), sx.MakeString(u.String()))) u.ClearQuery() } matrix = matrix.Cons(sx.Cons(sx.MakeString(part), row)) } return matrix } func (wui *WebUI) infoAPIMatrixParsed(zid id.Zid, encTexts []string) *sx.Pair { matrix := wui.infoAPIMatrix(zid, true, encTexts) u := wui.NewURLBuilder('z').SetZid(zid.ZettelID()) for i, row := 0, matrix; i < len(apiParts) && row != nil; row = row.Tail() { line, isLine := sx.GetPair(row.Car()) if !isLine || line == nil { continue } last := line.LastPair() part := apiParts[i] u.AppendKVQuery(api.QueryKeyPart, part) last = last.AppendBang(sx.Cons(sx.MakeString("plain"), sx.MakeString(u.String()))) u.ClearQuery() if i < 2 { u.AppendKVQuery(api.QueryKeyEncoding, api.EncodingData) u.AppendKVQuery(api.QueryKeyPart, part) last.AppendBang(sx.Cons(sx.MakeString("data"), sx.MakeString(u.String()))) u.ClearQuery() } i++ } return matrix } func getShadowLinks(ctx context.Context, zid id.Zid, getAllZettel usecase.GetAllZettel) *sx.Pair { result := sx.Nil() if zl, err := getAllZettel.Run(ctx, zid); err == nil { for i := len(zl) - 1; i >= 1; i-- { if boxNo, ok := zl[i].Meta.Get(api.KeyBoxNumber); ok { result = result.Cons(sx.MakeString(boxNo)) } } } return result } |
Changes to web/adapter/webui/get_zettel.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package webui import ( "context" "net/http" "strings" | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package webui import ( "context" "net/http" "strings" "t73f.de/r/sx" "t73f.de/r/zsc/api" "t73f.de/r/zsc/shtml" "zettelstore.de/z/box" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/usecase" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" |
︙ | ︙ | |||
58 59 60 61 62 63 64 | user := server.GetUser(ctx) getTextTitle := wui.makeGetTextTitle(ctx, getZettel) title := parser.NormalizedSpacedText(zn.InhMeta.GetTitle()) env, rb := wui.createRenderEnv(ctx, "zettel", wui.rtConfig.Get(ctx, zn.InhMeta, api.KeyLang), title, user) rb.bindSymbol(symMetaHeader, metaObj) | | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | user := server.GetUser(ctx) getTextTitle := wui.makeGetTextTitle(ctx, getZettel) title := parser.NormalizedSpacedText(zn.InhMeta.GetTitle()) env, rb := wui.createRenderEnv(ctx, "zettel", wui.rtConfig.Get(ctx, zn.InhMeta, api.KeyLang), title, user) rb.bindSymbol(symMetaHeader, metaObj) rb.bindString("heading", sx.MakeString(title)) if role, found := zn.InhMeta.Get(api.KeyRole); found && role != "" { rb.bindString("role-url", sx.MakeString(wui.NewURLBuilder('h').AppendQuery(api.KeyRole+api.SearchOperatorHas+role).String())) } if folgeRole, found := zn.InhMeta.Get(api.KeyFolgeRole); found && folgeRole != "" { rb.bindString("folge-role-url", sx.MakeString(wui.NewURLBuilder('h').AppendQuery(api.KeyRole+api.SearchOperatorHas+folgeRole).String())) } rb.bindString("tag-refs", wui.transformTagSet(api.KeyTags, meta.ListFromValue(zn.InhMeta.GetDefault(api.KeyTags, "")))) rb.bindString("predecessor-refs", wui.identifierSetAsLinks(zn.InhMeta, api.KeyPredecessor, getTextTitle)) rb.bindString("precursor-refs", wui.identifierSetAsLinks(zn.InhMeta, api.KeyPrecursor, getTextTitle)) rb.bindString("superior-refs", wui.identifierSetAsLinks(zn.InhMeta, api.KeySuperior, getTextTitle)) rb.bindString("urls", metaURLAssoc(zn.InhMeta)) rb.bindString("content", content) |
︙ | ︙ | |||
105 106 107 108 109 110 111 | } func metaURLAssoc(m *meta.Meta) *sx.Pair { var result sx.ListBuilder for _, p := range m.PairsRest() { if key := p.Key; strings.HasSuffix(key, meta.SuffixKeyURL) { if val := p.Value; val != "" { | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | } func metaURLAssoc(m *meta.Meta) *sx.Pair { var result sx.ListBuilder for _, p := range m.PairsRest() { if key := p.Key; strings.HasSuffix(key, meta.SuffixKeyURL) { if val := p.Value; val != "" { result.Add(sx.Cons(sx.MakeString(capitalizeMetaKey(key)), sx.MakeString(val))) } } } return result.List() } func (wui *WebUI) bindLinks(ctx context.Context, rb *renderBinder, varPrefix string, m *meta.Meta, key, configKey string, getTextTitle getTextTitleFunc) { |
︙ | ︙ | |||
147 148 149 150 151 152 153 | for i := len(values) - 1; i >= 0; i-- { val := values[i] zid, err := id.Parse(val) if err != nil { continue } if title, found := getTextTitle(zid); found > 0 { | | | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | for i := len(values) - 1; i >= 0; i-- { val := values[i] zid, err := id.Parse(val) if err != nil { continue } if title, found := getTextTitle(zid); found > 0 { url := sx.MakeString(wui.NewURLBuilder('h').SetZid(zid.ZettelID()).String()) if title == "" { lst = lst.Cons(sx.Cons(sx.MakeString(val), url)) } else { lst = lst.Cons(sx.Cons(sx.MakeString(title), url)) } } } return lst } |
Changes to web/adapter/webui/htmlgen.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package webui import ( "net/url" "strings" | | | | | | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package webui import ( "net/url" "strings" "t73f.de/r/sx" "t73f.de/r/sxwebs/sxhtml" "t73f.de/r/zsc/api" "t73f.de/r/zsc/attrs" "t73f.de/r/zsc/maps" "t73f.de/r/zsc/shtml" "t73f.de/r/zsc/sz" "zettelstore.de/z/ast" "zettelstore.de/z/encoder" "zettelstore.de/z/encoder/szenc" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/meta" ) |
︙ | ︙ | |||
73 74 75 76 77 78 79 | if hrefP == nil { return obj } href, ok := sx.GetString(hrefP.Cdr()) if !ok { return obj } | | | | | | | | | | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | if hrefP == nil { return obj } href, ok := sx.GetString(hrefP.Cdr()) if !ok { return obj } zid, fragment, hasFragment := strings.Cut(href.GetValue(), "#") u := builder.NewURLBuilder('h').SetZid(api.ZettelID(zid)) if hasFragment { u = u.SetFragment(fragment) } assoc = assoc.Cons(sx.Cons(shtml.SymAttrHref, sx.MakeString(u.String()))) return rest.Cons(assoc.Cons(sxhtml.SymAttr)).Cons(shtml.SymA) } rebind(th, sz.SymLinkZettel, linkZettel) rebind(th, sz.SymLinkFound, linkZettel) rebind(th, sz.SymLinkBased, func(obj sx.Object) sx.Object { attr, assoc, rest := findA(obj) if attr == nil { return obj } hrefP := assoc.Assoc(shtml.SymAttrHref) if hrefP == nil { return obj } href, ok := sx.GetString(hrefP.Cdr()) if !ok { return obj } u := builder.NewURLBuilder('/') assoc = assoc.Cons(sx.Cons(shtml.SymAttrHref, sx.MakeString(u.String()+href.GetValue()[1:]))) return rest.Cons(assoc.Cons(sxhtml.SymAttr)).Cons(shtml.SymA) }) rebind(th, sz.SymLinkQuery, func(obj sx.Object) sx.Object { attr, assoc, rest := findA(obj) if attr == nil { return obj } hrefP := assoc.Assoc(shtml.SymAttrHref) if hrefP == nil { return obj } href, ok := sx.GetString(hrefP.Cdr()) if !ok { return obj } ur, err := url.Parse(href.GetValue()) if err != nil { return obj } q := ur.Query().Get(api.QueryKeyQuery) if q == "" { return obj } u := builder.NewURLBuilder('h').AppendQuery(q) assoc = assoc.Cons(sx.Cons(shtml.SymAttrHref, sx.MakeString(u.String()))) return rest.Cons(assoc.Cons(sxhtml.SymAttr)).Cons(shtml.SymA) }) rebind(th, sz.SymLinkExternal, func(obj sx.Object) sx.Object { attr, assoc, rest := findA(obj) if attr == nil { return obj } assoc = assoc.Cons(sx.Cons(shtml.SymAttrClass, sx.MakeString("external"))). Cons(sx.Cons(shtml.SymAttrTarget, sx.MakeString("_blank"))). Cons(sx.Cons(shtml.SymAttrRel, sx.MakeString("noopener noreferrer"))) return rest.Cons(assoc.Cons(sxhtml.SymAttr)).Cons(shtml.SymA) }) rebind(th, sz.SymEmbed, func(obj sx.Object) sx.Object { pair, isPair := sx.GetPair(obj) if !isPair || !shtml.SymIMG.IsEqual(pair.Car()) { return obj } attr, isPair := sx.GetPair(pair.Tail().Car()) if !isPair || !sxhtml.SymAttr.IsEqual(attr.Car()) { return obj } srcP := attr.Tail().Assoc(shtml.SymAttrSrc) if srcP == nil { return obj } src, isString := sx.GetString(srcP.Cdr()) if !isString { return obj } zid := api.ZettelID(src.GetValue()) if !zid.IsValid() { return obj } u := builder.NewURLBuilder('z').SetZid(zid) imgAttr := attr.Tail().Cons(sx.Cons(shtml.SymAttrSrc, sx.MakeString(u.String()))).Cons(sxhtml.SymAttr) return pair.Tail().Tail().Cons(imgAttr).Cons(shtml.SymIMG) }) return &htmlGenerator{ tx: szenc.NewTransformer(), th: th, lang: lang, |
︙ | ︙ |
Changes to web/adapter/webui/htmlmeta.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package webui import ( "context" "errors" | | | | | | | | | | | | | | | | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | package webui import ( "context" "errors" "t73f.de/r/sx" "t73f.de/r/sxwebs/sxhtml" "t73f.de/r/zsc/api" "t73f.de/r/zsc/shtml" "zettelstore.de/z/ast" "zettelstore.de/z/box" "zettelstore.de/z/parser" "zettelstore.de/z/usecase" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func (wui *WebUI) writeHTMLMetaValue( key, value string, getTextTitle getTextTitleFunc, evalMetadata evalMetadataFunc, gen *htmlGenerator, ) sx.Object { switch kt := meta.Type(key); kt { case meta.TypeCredential: return sx.MakeString(value) case meta.TypeEmpty: return sx.MakeString(value) case meta.TypeID: return wui.transformIdentifier(value, getTextTitle) case meta.TypeIDSet: return wui.transformIdentifierSet(meta.ListFromValue(value), getTextTitle) case meta.TypeNumber: return wui.transformKeyValueText(key, value, value) case meta.TypeString: return sx.MakeString(value) case meta.TypeTagSet: return wui.transformTagSet(key, meta.ListFromValue(value)) case meta.TypeTimestamp: if ts, ok := meta.TimeValue(value); ok { return sx.MakeList( sx.MakeSymbol("time"), sx.MakeList( sxhtml.SymAttr, sx.Cons(sx.MakeSymbol("datetime"), sx.MakeString(ts.Format("2006-01-02T15:04:05"))), ), sx.MakeList(sxhtml.SymNoEscape, sx.MakeString(ts.Format("2006-01-02 15:04:05"))), ) } return sx.Nil() case meta.TypeURL: return wui.url2html(sx.MakeString(value)) case meta.TypeWord: return wui.transformKeyValueText(key, value, value) case meta.TypeZettelmarkup: return wui.transformZmkMetadata(value, evalMetadata, gen) default: return sx.MakeList(shtml.SymSTRONG, sx.MakeString("Unhandled type: "), sx.MakeString(kt.Name)) } } func (wui *WebUI) transformIdentifier(val string, getTextTitle getTextTitleFunc) sx.Object { text := sx.MakeString(val) zid, err := id.Parse(val) if err != nil { return text } title, found := getTextTitle(zid) switch { case found > 0: ub := wui.NewURLBuilder('h').SetZid(zid.ZettelID()) attrs := sx.Nil() if title != "" { attrs = attrs.Cons(sx.Cons(shtml.SymAttrTitle, sx.MakeString(title))) } attrs = attrs.Cons(sx.Cons(shtml.SymAttrHref, sx.MakeString(ub.String()))).Cons(sxhtml.SymAttr) return sx.Nil().Cons(sx.MakeString(zid.String())).Cons(attrs).Cons(shtml.SymA) case found == 0: return sx.MakeList(sx.MakeSymbol("s"), text) default: // case found < 0: return text } } func (wui *WebUI) transformIdentifierSet(vals []string, getTextTitle getTextTitleFunc) *sx.Pair { if len(vals) == 0 { return nil } var space = sx.MakeString(" ") text := make(sx.Vector, 0, 2*len(vals)) for _, val := range vals { text = append(text, space, wui.transformIdentifier(val, getTextTitle)) } return sx.MakeList(text[1:]...).Cons(shtml.SymSPAN) } func (wui *WebUI) transformTagSet(key string, tags []string) *sx.Pair { if len(tags) == 0 { return nil } var space = sx.MakeString(" ") text := make(sx.Vector, 0, 2*len(tags)+2) for _, tag := range tags { text = append(text, space, wui.transformKeyValueText(key, tag, tag)) } if len(tags) > 1 { text = append(text, space, wui.transformKeyValuesText(key, tags, "(all)")) } |
︙ | ︙ | |||
137 138 139 140 141 142 143 | } func buildHref(ub *api.URLBuilder, text string) *sx.Pair { return sx.MakeList( shtml.SymA, sx.MakeList( sxhtml.SymAttr, | | | | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | } func buildHref(ub *api.URLBuilder, text string) *sx.Pair { return sx.MakeList( shtml.SymA, sx.MakeList( sxhtml.SymAttr, sx.Cons(shtml.SymAttrHref, sx.MakeString(ub.String())), ), sx.MakeString(text), ) } type evalMetadataFunc = func(string) ast.InlineSlice func createEvalMetadataFunc(ctx context.Context, evaluate *usecase.Evaluate) evalMetadataFunc { return func(value string) ast.InlineSlice { return evaluate.RunMetadata(ctx, value) } |
︙ | ︙ |
Changes to web/adapter/webui/lists.go.
︙ | ︙ | |||
18 19 20 21 22 23 24 | "io" "net/http" "net/url" "slices" "strconv" "strings" | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | "io" "net/http" "net/url" "slices" "strconv" "strings" "t73f.de/r/sx" "t73f.de/r/sxwebs/sxhtml" "t73f.de/r/zsc/api" "t73f.de/r/zsc/shtml" "zettelstore.de/z/ast" "zettelstore.de/z/encoding/atom" "zettelstore.de/z/encoding/rss" "zettelstore.de/z/encoding/xml" "zettelstore.de/z/evaluator" "zettelstore.de/z/query" "zettelstore.de/z/usecase" |
︙ | ︙ | |||
94 95 96 97 98 99 100 | user := server.GetUser(ctx) env, rb := wui.createRenderEnv( ctx, "list", wui.rtConfig.Get(ctx, nil, api.KeyLang), wui.rtConfig.GetSiteName(), user) if q == nil { | | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | user := server.GetUser(ctx) env, rb := wui.createRenderEnv( ctx, "list", wui.rtConfig.Get(ctx, nil, api.KeyLang), wui.rtConfig.GetSiteName(), user) if q == nil { rb.bindString("heading", sx.MakeString(wui.rtConfig.GetSiteName())) } else { var sb strings.Builder q.PrintHuman(&sb) rb.bindString("heading", sx.MakeString(sb.String())) } rb.bindString("query-value", sx.MakeString(q.String())) if tzl := q.GetMetaValues(api.KeyTags, false); len(tzl) > 0 { sxTzl, sxNoTzl := wui.transformTagZettelList(ctx, tagZettel, tzl) if !sx.IsNil(sxTzl) { rb.bindString("tag-zettel", sxTzl) } if !sx.IsNil(sxNoTzl) && wui.canCreate(ctx, user) { rb.bindString("create-tag-zettel", sxNoTzl) |
︙ | ︙ | |||
131 132 133 134 135 136 137 | seed, found := q.GetSeed() if found { apiURL = apiURL.AppendKVQuery(api.QueryKeySeed, strconv.Itoa(seed)) } else { seed = 0 } if len(metaSeq) > 0 { | | | | | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | seed, found := q.GetSeed() if found { apiURL = apiURL.AppendKVQuery(api.QueryKeySeed, strconv.Itoa(seed)) } else { seed = 0 } if len(metaSeq) > 0 { rb.bindString("plain-url", sx.MakeString(apiURL.String())) rb.bindString("data-url", sx.MakeString(apiURL.AppendKVQuery(api.QueryKeyEncoding, api.EncodingData).String())) if wui.canCreate(ctx, user) { rb.bindString("create-url", sx.MakeString(wui.createNewURL)) rb.bindString("seed", sx.Int64(seed)) } } if rb.err == nil { err = wui.renderSxnTemplate(ctx, w, id.ListTemplateZid, env) } else { err = rb.err |
︙ | ︙ | |||
183 184 185 186 187 188 189 | } func (wui *WebUI) prependZettelLink(sxZtl *sx.Pair, name string, u *api.URLBuilder) *sx.Pair { link := sx.MakeList( shtml.SymA, sx.MakeList( sxhtml.SymAttr, | | | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | } func (wui *WebUI) prependZettelLink(sxZtl *sx.Pair, name string, u *api.URLBuilder) *sx.Pair { link := sx.MakeList( shtml.SymA, sx.MakeList( sxhtml.SymAttr, sx.Cons(shtml.SymAttrHref, sx.MakeString(u.String())), ), sx.MakeString(name), ) if sxZtl != nil { sxZtl = sxZtl.Cons(sx.MakeString(", ")) } return sxZtl.Cons(link) } func (wui *WebUI) renderRSS(ctx context.Context, w http.ResponseWriter, q *query.Query, ml []*meta.Meta) { var rssConfig rss.Configuration rssConfig.Setup(ctx, wui.rtConfig) |
︙ | ︙ |
Changes to web/adapter/webui/login.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package webui import ( "context" "net/http" | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package webui import ( "context" "net/http" "t73f.de/r/sx" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/zettel/id" ) // MakeGetLoginOutHandler creates a new HTTP handler to display the HTML login view, |
︙ | ︙ |
Changes to web/adapter/webui/rename_zettel.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package webui import ( "fmt" "net/http" "strings" | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package webui import ( "fmt" "net/http" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/box" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel/id" ) |
︙ | ︙ |
Changes to web/adapter/webui/response.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package webui import ( "net/http" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package webui import ( "net/http" "t73f.de/r/zsc/api" ) func (wui *WebUI) redirectFound(w http.ResponseWriter, r *http.Request, ub *api.URLBuilder) { us := ub.String() wui.log.Debug().Str("uri", us).Msg("redirect") http.Redirect(w, r, us, http.StatusFound) } |
Changes to web/adapter/webui/sxn_code.go.
︙ | ︙ | |||
14 15 16 17 18 19 20 | package webui import ( "context" "fmt" "io" | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package webui import ( "context" "fmt" "io" "t73f.de/r/sx/sxeval" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func (wui *WebUI) loadAllSxnCodeZettel(ctx context.Context) (id.Digraph, *sxeval.Binding, error) { // getMeta MUST currently use GetZettel, because GetMeta just uses the // Index, which might not be current. |
︙ | ︙ |
Changes to web/adapter/webui/template.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "bytes" "context" "fmt" "net/http" "net/url" | | | | | | | | > > | | | | | | | | | | | | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | import ( "bytes" "context" "fmt" "net/http" "net/url" "t73f.de/r/sx" "t73f.de/r/sx/sxbuiltins" "t73f.de/r/sx/sxeval" "t73f.de/r/sx/sxreader" "t73f.de/r/sxwebs/sxhtml" "t73f.de/r/zsc/api" "t73f.de/r/zsc/shtml" "zettelstore.de/z/box" "zettelstore.de/z/collect" "zettelstore.de/z/config" "zettelstore.de/z/parser" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) func (wui *WebUI) createRenderBinding() *sxeval.Binding { root := sxeval.MakeRootBinding(len(specials) + len(builtins) + 3) for _, syntax := range specials { root.BindSpecial(syntax) } for _, b := range builtins { root.BindBuiltin(b) } _ = root.Bind(sx.MakeSymbol("NIL"), sx.Nil()) _ = root.Bind(sx.MakeSymbol("T"), sx.MakeSymbol("T")) root.BindBuiltin(&sxeval.Builtin{ Name: "url-to-html", MinArity: 1, MaxArity: 1, TestPure: sxeval.AssertPure, Fn1: func(_ *sxeval.Environment, arg sx.Object) (sx.Object, error) { text, err := sxbuiltins.GetString(arg, 0) if err != nil { return nil, err } return wui.url2html(text), nil }, }) root.BindBuiltin(&sxeval.Builtin{ Name: "zid-content-path", MinArity: 1, MaxArity: 1, TestPure: sxeval.AssertPure, Fn1: func(_ *sxeval.Environment, arg sx.Object) (sx.Object, error) { s, err := sxbuiltins.GetString(arg, 0) if err != nil { return nil, err } zid, err := id.Parse(s.GetValue()) if err != nil { return nil, fmt.Errorf("parsing zettel identifier %q: %w", s.GetValue(), err) } ub := wui.NewURLBuilder('z').SetZid(zid.ZettelID()) return sx.MakeString(ub.String()), nil }, }) root.BindBuiltin(&sxeval.Builtin{ Name: "query->url", MinArity: 1, MaxArity: 1, TestPure: sxeval.AssertPure, Fn1: func(_ *sxeval.Environment, arg sx.Object) (sx.Object, error) { qs, err := sxbuiltins.GetString(arg, 0) if err != nil { return nil, err } u := wui.NewURLBuilder('h').AppendQuery(qs.GetValue()) return sx.MakeString(u.String()), nil }, }) root.Freeze() return root } var ( specials = []*sxeval.Special{ &sxbuiltins.QuoteS, &sxbuiltins.QuasiquoteS, // quote, quasiquote &sxbuiltins.UnquoteS, &sxbuiltins.UnquoteSplicingS, // unquote, unquote-splicing &sxbuiltins.DefVarS, // defvar &sxbuiltins.DefunS, &sxbuiltins.LambdaS, // defun, lambda &sxbuiltins.SetXS, // set! &sxbuiltins.IfS, // if &sxbuiltins.BeginS, // begin &sxbuiltins.DefMacroS, // defmacro &sxbuiltins.LetS, // let } builtins = []*sxeval.Builtin{ &sxbuiltins.Equal, // = &sxbuiltins.NumGreater, // > &sxbuiltins.NullP, // null? &sxbuiltins.PairP, // pair? &sxbuiltins.Car, &sxbuiltins.Cdr, // car, cdr |
︙ | ︙ | |||
125 126 127 128 129 130 131 | &sxbuiltins.Defined, // defined? &sxbuiltins.CurrentBinding, // current-binding &sxbuiltins.BindingLookup, // binding-lookup } ) func (wui *WebUI) url2html(text sx.String) sx.Object { | | | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | &sxbuiltins.Defined, // defined? &sxbuiltins.CurrentBinding, // current-binding &sxbuiltins.BindingLookup, // binding-lookup } ) func (wui *WebUI) url2html(text sx.String) sx.Object { if u, errURL := url.Parse(text.GetValue()); errURL == nil { if us := u.String(); us != "" { return sx.MakeList( shtml.SymA, sx.MakeList( sxhtml.SymAttr, sx.Cons(shtml.SymAttrHref, sx.MakeString(us)), sx.Cons(shtml.SymAttrTarget, sx.MakeString("_blank")), sx.Cons(shtml.SymAttrRel, sx.MakeString("noopener noreferrer")), ), text) } } return text } |
︙ | ︙ | |||
163 164 165 166 167 168 169 | // createRenderEnv creates a new environment and populates it with all relevant data for the base template. func (wui *WebUI) createRenderEnv(ctx context.Context, name, lang, title string, user *meta.Meta) (*sxeval.Binding, renderBinder) { userIsValid, userZettelURL, userIdent := wui.getUserRenderData(user) parentEnv, err := wui.getParentEnv(ctx) bind := parentEnv.MakeChildBinding(name, 128) rb := makeRenderBinder(bind, err) | | | | | | | | | | | | | | | | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | // createRenderEnv creates a new environment and populates it with all relevant data for the base template. func (wui *WebUI) createRenderEnv(ctx context.Context, name, lang, title string, user *meta.Meta) (*sxeval.Binding, renderBinder) { userIsValid, userZettelURL, userIdent := wui.getUserRenderData(user) parentEnv, err := wui.getParentEnv(ctx) bind := parentEnv.MakeChildBinding(name, 128) rb := makeRenderBinder(bind, err) rb.bindString("lang", sx.MakeString(lang)) rb.bindString("css-base-url", sx.MakeString(wui.cssBaseURL)) rb.bindString("css-user-url", sx.MakeString(wui.cssUserURL)) rb.bindString("title", sx.MakeString(title)) rb.bindString("home-url", sx.MakeString(wui.homeURL)) rb.bindString("with-auth", sx.MakeBoolean(wui.withAuth)) rb.bindString("user-is-valid", sx.MakeBoolean(userIsValid)) rb.bindString("user-zettel-url", sx.MakeString(userZettelURL)) rb.bindString("user-ident", sx.MakeString(userIdent)) rb.bindString("login-url", sx.MakeString(wui.loginURL)) rb.bindString("logout-url", sx.MakeString(wui.logoutURL)) rb.bindString("list-zettel-url", sx.MakeString(wui.listZettelURL)) rb.bindString("list-roles-url", sx.MakeString(wui.listRolesURL)) rb.bindString("list-tags-url", sx.MakeString(wui.listTagsURL)) if wui.canRefresh(user) { rb.bindString("refresh-url", sx.MakeString(wui.refreshURL)) } rb.bindString("new-zettel-links", wui.fetchNewTemplatesSxn(ctx, user)) rb.bindString("search-url", sx.MakeString(wui.searchURL)) rb.bindString("query-key-query", sx.MakeString(api.QueryKeyQuery)) rb.bindString("query-key-seed", sx.MakeString(api.QueryKeySeed)) rb.bindString("FOOTER", wui.calculateFooterSxn(ctx)) // TODO: use real footer rb.bindString("debug-mode", sx.MakeBoolean(wui.debug)) rb.bindSymbol(symMetaHeader, sx.Nil()) rb.bindSymbol(symDetail, sx.Nil()) return bind, rb } |
︙ | ︙ | |||
217 218 219 220 221 222 223 | } func (rb *renderBinder) bindSymbol(sym *sx.Symbol, obj sx.Object) { if rb.err == nil { rb.err = rb.binding.Bind(sym, obj) } } func (rb *renderBinder) bindKeyValue(key string, value string) { | | | | | | | | | | | | | | | | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | } func (rb *renderBinder) bindSymbol(sym *sx.Symbol, obj sx.Object) { if rb.err == nil { rb.err = rb.binding.Bind(sym, obj) } } func (rb *renderBinder) bindKeyValue(key string, value string) { rb.bindString("meta-"+key, sx.MakeString(value)) if kt := meta.Type(key); kt.IsSet { rb.bindString("set-meta-"+key, makeStringList(meta.ListFromValue(value))) } } func (rb *renderBinder) rebindResolved(key, defKey string) { if rb.err == nil { if obj, found := rb.binding.Resolve(sx.MakeSymbol(key)); found { rb.bindString(defKey, obj) } } } func (wui *WebUI) bindCommonZettelData(ctx context.Context, rb *renderBinder, user, m *meta.Meta, content *zettel.Content) { strZid := m.Zid.String() apiZid := api.ZettelID(strZid) newURLBuilder := wui.NewURLBuilder rb.bindString("zid", sx.MakeString(strZid)) rb.bindString("web-url", sx.MakeString(newURLBuilder('h').SetZid(apiZid).String())) if content != nil && wui.canWrite(ctx, user, m, *content) { rb.bindString("edit-url", sx.MakeString(newURLBuilder('e').SetZid(apiZid).String())) } rb.bindString("info-url", sx.MakeString(newURLBuilder('i').SetZid(apiZid).String())) if wui.canCreate(ctx, user) { if content != nil && !content.IsBinary() { rb.bindString("copy-url", sx.MakeString(newURLBuilder('c').SetZid(apiZid).AppendKVQuery(queryKeyAction, valueActionCopy).String())) } rb.bindString("version-url", sx.MakeString(newURLBuilder('c').SetZid(apiZid).AppendKVQuery(queryKeyAction, valueActionVersion).String())) rb.bindString("child-url", sx.MakeString(newURLBuilder('c').SetZid(apiZid).AppendKVQuery(queryKeyAction, valueActionChild).String())) rb.bindString("folge-url", sx.MakeString(newURLBuilder('c').SetZid(apiZid).AppendKVQuery(queryKeyAction, valueActionFolge).String())) } if wui.canRename(ctx, user, m) { rb.bindString("rename-url", sx.MakeString(newURLBuilder('b').SetZid(apiZid).String())) } if wui.canDelete(ctx, user, m) { rb.bindString("delete-url", sx.MakeString(newURLBuilder('d').SetZid(apiZid).String())) } if val, found := m.Get(api.KeyUselessFiles); found { rb.bindString("useless", sx.Cons(sx.MakeString(val), nil)) } queryContext := strZid + " " + api.ContextDirective rb.bindString("context-url", sx.MakeString(newURLBuilder('h').AppendQuery(queryContext).String())) queryContext += " " + api.FullDirective rb.bindString("context-full-url", sx.MakeString(newURLBuilder('h').AppendQuery(queryContext).String())) if wui.canRefresh(user) { rb.bindString("reindex-url", sx.MakeString(newURLBuilder('h').AppendQuery( strZid+" "+api.IdentDirective+api.ActionSeparator+api.ReIndexAction).String())) } // Ensure to have title, role, tags, and syntax included as "meta-*" rb.bindKeyValue(api.KeyTitle, m.GetDefault(api.KeyTitle, "")) rb.bindKeyValue(api.KeyRole, m.GetDefault(api.KeyRole, "")) rb.bindKeyValue(api.KeyTags, m.GetDefault(api.KeyTags, "")) rb.bindKeyValue(api.KeySyntax, m.GetDefault(api.KeySyntax, meta.DefaultSyntax)) var metaPairs sx.ListBuilder for _, p := range m.ComputedPairs() { key, value := p.Key, p.Value metaPairs.Add(sx.Cons(sx.MakeString(key), sx.MakeString(value))) rb.bindKeyValue(key, value) } rb.bindString("metapairs", metaPairs.List()) } func (wui *WebUI) fetchNewTemplatesSxn(ctx context.Context, user *meta.Meta) (lst *sx.Pair) { if !wui.canCreate(ctx, user) { |
︙ | ︙ | |||
303 304 305 306 307 308 309 | z, err2 := wui.box.GetZettel(ctx, zid) if err2 != nil { continue } if !wui.policy.CanRead(user, z.Meta) { continue } | | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | z, err2 := wui.box.GetZettel(ctx, zid) if err2 != nil { continue } if !wui.policy.CanRead(user, z.Meta) { continue } text := sx.MakeString(parser.NormalizedSpacedText(z.Meta.GetTitle())) link := sx.MakeString(wui.NewURLBuilder('c').SetZid(zid.ZettelID()). AppendKVQuery(queryKeyAction, valueActionNew).String()) lst = lst.Cons(sx.Cons(text, link)) } return lst } func (wui *WebUI) calculateFooterSxn(ctx context.Context) *sx.Pair { |
︙ | ︙ | |||
391 392 393 394 395 396 397 | return err } if msg := wui.log.Debug(); msg != nil { // pageObj.String() can be expensive to calculate. msg.Str("page", pageObj.String()).Msg("render") } | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | return err } if msg := wui.log.Debug(); msg != nil { // pageObj.String() can be expensive to calculate. msg.Str("page", pageObj.String()).Msg("render") } gen := sxhtml.NewGenerator().SetNewline() var sb bytes.Buffer _, err = gen.WriteHTML(&sb, pageObj) if err != nil { return err } wui.prepareAndWriteHeader(w, code) if _, err = w.Write(sb.Bytes()); err != nil { |
︙ | ︙ | |||
413 414 415 416 417 418 419 | if code == http.StatusInternalServerError { wui.log.Error().Msg(err.Error()) } else { wui.log.Debug().Err(err).Msg("reportError") } user := server.GetUser(ctx) env, rb := wui.createRenderEnv(ctx, "error", api.ValueLangEN, "Error", user) | | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 | if code == http.StatusInternalServerError { wui.log.Error().Msg(err.Error()) } else { wui.log.Debug().Err(err).Msg("reportError") } user := server.GetUser(ctx) env, rb := wui.createRenderEnv(ctx, "error", api.ValueLangEN, "Error", user) rb.bindString("heading", sx.MakeString(http.StatusText(code))) rb.bindString("message", sx.MakeString(text)) if rb.err == nil { rb.err = wui.renderSxnTemplateStatus(ctx, w, code, id.ErrorTemplateZid, env) } errSx := rb.err if errSx == nil { return } |
︙ | ︙ | |||
444 445 446 447 448 449 450 | func makeStringList(sl []string) *sx.Pair { if len(sl) == 0 { return nil } result := sx.Nil() for i := len(sl) - 1; i >= 0; i-- { | | | 447 448 449 450 451 452 453 454 455 456 457 | func makeStringList(sl []string) *sx.Pair { if len(sl) == 0 { return nil } result := sx.Nil() for i := len(sl) - 1; i >= 0; i-- { result = result.Cons(sx.MakeString(sl[i])) } return result } |
Changes to web/adapter/webui/webui.go.
︙ | ︙ | |||
16 17 18 19 20 21 22 | import ( "context" "net/http" "sync" "time" | | | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import ( "context" "net/http" "sync" "time" "t73f.de/r/sx" "t73f.de/r/sx/sxeval" "t73f.de/r/sxwebs/sxhtml" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/box" "zettelstore.de/z/config" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" |
︙ | ︙ | |||
116 117 118 119 120 121 122 | withAuth: authz.WithAuth(), loginURL: loginoutBase.String(), logoutURL: loginoutBase.AppendKVQuery("logout", "").String(), searchURL: ab.NewURLBuilder('h').String(), createNewURL: ab.NewURLBuilder('c').String(), zettelBinding: nil, | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | withAuth: authz.WithAuth(), loginURL: loginoutBase.String(), logoutURL: loginoutBase.AppendKVQuery("logout", "").String(), searchURL: ab.NewURLBuilder('h').String(), createNewURL: ab.NewURLBuilder('c').String(), zettelBinding: nil, genHTML: sxhtml.NewGenerator().SetNewline(), } wui.rootBinding = wui.createRenderBinding() wui.observe(box.UpdateInfo{Box: mgr, Reason: box.OnReload, Zid: id.Invalid}) mgr.RegisterObserver(wui.observe) return wui } |
︙ | ︙ |
Changes to web/content/content.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | // It translates syntax values into content types, and vice versa. package content import ( "mime" "net/http" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // It translates syntax values into content types, and vice versa. package content import ( "mime" "net/http" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/meta" ) const ( UnknownMIME = "application/octet-stream" mimeGIF = "image/gif" |
︙ | ︙ |
Changes to web/server/impl/impl.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package impl import ( "context" "net/http" "time" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package impl import ( "context" "net/http" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/logger" "zettelstore.de/z/web/server" "zettelstore.de/z/zettel/meta" ) type myServer struct { |
︙ | ︙ |
Changes to web/server/impl/router.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "io" "net/http" "regexp" "strings" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "io" "net/http" "regexp" "strings" "t73f.de/r/zsc/api" "zettelstore.de/z/auth" "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/web/server" ) type ( |
︙ | ︙ |
Changes to web/server/server.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | package server import ( "context" "net/http" "time" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package server import ( "context" "net/http" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // UserRetriever allows to retrieve user data based on a given zettel identifier. type UserRetriever interface { GetUser(ctx context.Context, zid id.Zid, ident string) (*meta.Meta, error) |
︙ | ︙ |
Changes to www/build.md.
︙ | ︙ | |||
67 68 69 70 71 72 73 | * `go run tools/devtools/devtools.go` install all needed software (see above). * `go run tools/htmllint/htmllint.go [URL]` checks all generated HTML of a Zettelstore accessible at the given URL (default: http://localhost:23123). * `go run tools/testapi/testapi.go` tests the API against a running Zettelstore, which is started automatically. ## A note on the use of Fossil | | | | | < | > < | | | | | | < | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | * `go run tools/devtools/devtools.go` install all needed software (see above). * `go run tools/htmllint/htmllint.go [URL]` checks all generated HTML of a Zettelstore accessible at the given URL (default: http://localhost:23123). * `go run tools/testapi/testapi.go` tests the API against a running Zettelstore, which is started automatically. ## A note on the use of Fossil Zettelstore is managed by the Fossil version control system. Fossil is an alternative to the ubiquitous Git version control system. However, Go seems to prefer Git and popular platforms that just support Git. Some dependencies of Zettelstore, namely [Zettelstore client](https://t73f.de/r/zsc) and [Sx](https://t73f.de/r/sx), are also managed by Fossil. Depending on your development setup, some error messages might occur. If the error message mentions an environment variable called `GOVCS` you should set it to the value `GOVCS=zettelstore.de:fossil` (alternatively more generous to `GOVCS=*:all`). Since the Go build system is coupled with Git and some special platforms, you allow ot to download a Fossil repository from the host `zettelstore.de`. The build tool set `GOVCS` to the right value, but you may use other `go` commands that try to download a Fossil repository. On some operating systems, namely Termux on Android, an error message might state that an user cannot be determined (`cannot determine user`). In this case, Fossil is allowed to download the repository, but cannot associate it with an user name. Set the environment variable `USER` to any user name, like: `USER=nobody go run tools/build.go build`. |
Changes to www/changes.wiki.
1 2 3 4 5 6 7 8 9 10 11 | <title>Change Log</title> <a id="0_18"></a> <h2>Changes for Version 0.18.0 (pending)</h2> <a id="0_17"></a> <h2>Changes for Version 0.17.0 (2024-03-04)</h2> * Context search operates only on explicit references. Add the directive <code>FULL</code> to follow zettel tags additionally. (breaking) * Context cost calculation has been changed. Prepare to retrieve different | > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <title>Change Log</title> <a id="0_18"></a> <h2>Changes for Version 0.18.0 (pending)</h2> * Remove Sx macro <code>defunconst</code>. Use <code>defun</code> instead. (breaking: webui) * Update Sx prelude: make macros more robust / more general. This might break your code in the future. (minor: webui) * Add computed zettel “Zettelstore Memory” with zettel identifier <code>00000000000008</code>. It shows some statistics about memory usage. (minor: webui) * Zettelstore client is now Go package t73f.de/r/zsc. (minor) <a id="0_17"></a> <h2>Changes for Version 0.17.0 (2024-03-04)</h2> * Context search operates only on explicit references. Add the directive <code>FULL</code> to follow zettel tags additionally. (breaking) * Context cost calculation has been changed. Prepare to retrieve different |
︙ | ︙ | |||
784 785 786 787 788 789 790 | syntax will not be supported. The reason is the collision with URLs that also contain the characters <code>//</code>. The ZMK encoding of a zettel may help with the transition (<code>/v/{ZettelID}?_part=zettel&_enc=zmk</code>, on the Info page of each zettel in the WebUI). Additionally, all deprecated uses of <code>//</code> will be rendered with a dashed box within the WebUI. (breaking: Zettelmarkup). | | < | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 | syntax will not be supported. The reason is the collision with URLs that also contain the characters <code>//</code>. The ZMK encoding of a zettel may help with the transition (<code>/v/{ZettelID}?_part=zettel&_enc=zmk</code>, on the Info page of each zettel in the WebUI). Additionally, all deprecated uses of <code>//</code> will be rendered with a dashed box within the WebUI. (breaking: Zettelmarkup). * API client software is now a separate project. (breaking) * Initial support for HTTP security headers (Content-Security-Policy, Permissions-Policy, Referrer-Policy, X-Content-Type-Options, X-Frame-Options). Header values are currently some constant values. (possibly breaking: api, webui) * Remove visual Zettelmarkup (bold, striketrough). Semantic Zettelmarkup (strong, delete) is still allowed and replaces the visual elements |
︙ | ︙ |
Changes to www/index.wiki.
︙ | ︙ | |||
12 13 14 15 16 17 18 | To get an initial impression, take a look at the [https://zettelstore.de/manual/|manual]. It is a live example of the zettelstore software, running in read-only mode. The software, including the manual, is licensed under the [/file?name=LICENSE.txt&ci=trunk|European Union Public License 1.2 (or later)]. | | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | To get an initial impression, take a look at the [https://zettelstore.de/manual/|manual]. It is a live example of the zettelstore software, running in read-only mode. The software, including the manual, is licensed under the [/file?name=LICENSE.txt&ci=trunk|European Union Public License 1.2 (or later)]. * [https://t73f.de/r/zsc|Zettelstore Client] provides client software to access Zettelstore via its API more easily. * [https://zettelstore.de/contrib|Zettelstore Contrib] contains contributed software, which often connects to Zettelstore via its API. Some of the software packages may be experimental. * [https://t73f.de/r/sx|Sx] provides an evaluator for symbolic expressions, which is used for HTML templates and more. [https://mastodon.social/tags/Zettelstore|Stay tuned] … <hr> <h3>Latest Release: 0.17.0 (2024-03-04)</h3> * [./download.wiki|Download] * [./changes.wiki#0_17|Change summary] * [/timeline?p=v0.17.0&bt=v0.16.0&y=ci|Check-ins for version 0.17.0], |
︙ | ︙ |
Changes to zettel/content.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | "bytes" "encoding/base64" "errors" "io" "unicode" "unicode/utf8" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | "bytes" "encoding/base64" "errors" "io" "unicode" "unicode/utf8" "t73f.de/r/zsc/input" ) // Content is just the content of a zettel. type Content struct { data []byte isBinary bool } |
︙ | ︙ |
Changes to zettel/id/id.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | // zettel identifier. package id import ( "strconv" "time" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // zettel identifier. package id import ( "strconv" "time" "t73f.de/r/zsc/api" ) // Zid is the internal identifier of a zettel. Typically, it is a // time stamp of the form "YYYYMMDDHHmmSS" converted to an unsigned integer. // A zettelstore implementation should try to set the last two digits to zero, // e.g. the seconds should be zero, type Zid uint64 |
︙ | ︙ |
Changes to zettel/meta/meta.go.
︙ | ︙ | |||
17 18 19 20 21 22 23 | import ( "regexp" "sort" "strings" "unicode" "unicode/utf8" | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import ( "regexp" "sort" "strings" "unicode" "unicode/utf8" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "t73f.de/r/zsc/maps" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/id" ) type keyUsage int const ( |
︙ | ︙ |
Changes to zettel/meta/meta_test.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package meta import ( "strings" "testing" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package meta import ( "strings" "testing" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" ) const testID = id.Zid(98765432101234) func TestKeyIsValid(t *testing.T) { t.Parallel() |
︙ | ︙ |
Changes to zettel/meta/parse.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package meta import ( "strings" | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //----------------------------------------------------------------------------- package meta import ( "strings" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "t73f.de/r/zsc/maps" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/id" ) // NewFromInput parses the meta data of a zettel. func NewFromInput(zid id.Zid, inp *input.Input) *Meta { if inp.Ch == '-' && inp.PeekN(0) == '-' && inp.PeekN(1) == '-' { |
︙ | ︙ |
Changes to zettel/meta/parse_test.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package meta_test import ( "strings" "testing" | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package meta_test import ( "strings" "testing" "t73f.de/r/zsc/api" "t73f.de/r/zsc/input" "zettelstore.de/z/zettel/meta" ) func parseMetaStr(src string) *meta.Meta { return meta.NewFromInput(testID, input.NewInput([]byte(src))) } |
︙ | ︙ |
Changes to zettel/meta/type.go.
︙ | ︙ | |||
15 16 17 18 19 20 21 | import ( "strconv" "strings" "sync" "time" | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import ( "strconv" "strings" "sync" "time" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" ) // DescriptionType is a description of a specific key type. type DescriptionType struct { Name string IsSet bool |
︙ | ︙ |
Changes to zettel/meta/values.go.
︙ | ︙ | |||
12 13 14 15 16 17 18 | //----------------------------------------------------------------------------- package meta import ( "fmt" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | //----------------------------------------------------------------------------- package meta import ( "fmt" "t73f.de/r/zsc/api" ) // Supported syntax values. const ( SyntaxCSS = api.ValueSyntaxCSS SyntaxDraw = api.ValueSyntaxDraw SyntaxGif = api.ValueSyntaxGif |
︙ | ︙ |
Changes to zettel/meta/write_test.go.
︙ | ︙ | |||
13 14 15 16 17 18 19 | package meta_test import ( "strings" "testing" | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package meta_test import ( "strings" "testing" "t73f.de/r/zsc/api" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) const testID = id.Zid(98765432101234) func newMeta(title string, tags []string, syntax string) *meta.Meta { |
︙ | ︙ |