Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From v0.12.0 To v0.13.0
2023-08-07
| ||
13:56 | Typo on home page ... (check-in: d2fe74163e user: stern tags: trunk) | |
13:53 | Version 0.13.0 ... (check-in: 37fed58a18 user: stern tags: trunk, release, v0.13.0) | |
10:49 | Update changelog ... (check-in: 8da4351a55 user: stern tags: trunk) | |
2023-06-08
| ||
12:13 | Increase version to 0.13.0-dev to begin next development cycle ... (check-in: 761b8bd088 user: t73fde tags: trunk) | |
2023-06-05
| ||
12:12 | Version 0.12.0 ... (check-in: 0a29539266 user: stern tags: trunk, release, v0.12.0) | |
2023-06-04
| ||
12:58 | Fix: empty tags field on edit ... (check-in: 9d331fd7f9 user: t73fde tags: trunk) | |
Changes to README.md.
︙ | |||
19 20 21 22 23 24 25 | 19 20 21 22 23 24 25 26 | - + | 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). |
Changes to VERSION.
| 1 | - + |
|
Changes to ast/block.go.
1 2 3 4 5 6 7 8 9 10 11 12 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - + | //----------------------------------------------------------------------------- // Copyright (c) 2020-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. //----------------------------------------------------------------------------- package ast |
︙ |
Changes to ast/inline.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package ast import ( "unicode/utf8" |
︙ |
Changes to ast/walk_test.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package ast_test import ( "testing" |
︙ |
Added auth/impl/digest.go.
|
Changes to auth/impl/impl.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | - - - + + + | import ( "errors" "hash/fnv" "io" "time" |
︙ | |||
63 64 65 66 67 68 69 | 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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | - + + - - - - + + + + + - - - - + - - - - - - + + - - - - + + + + - + - + + + + + + + + - + - - - - + + - + - + - - + + - - - - - + - - - + + - - - + - - - - - + + + + + + + + + + + | } return h.Sum(nil) } // IsReadonly returns true, if the systems is configured to run in read-only-mode. func (a *myAuth) IsReadonly() bool { return a.readonly } |
︙ |
Changes to auth/policy/box.go.
︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 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 | + + + + - - - - - - - - - + - + - + - + - + - + - + - + | } return zettel.Zettel{}, box.NewErrNotAllowed("GetZettel", user, zid) } func (pp *polBox) GetAllZettel(ctx context.Context, zid id.Zid) ([]zettel.Zettel, error) { return pp.box.GetAllZettel(ctx, zid) } func (pp *polBox) FetchZids(ctx context.Context) (id.Set, error) { return nil, box.NewErrNotAllowed("fetch-zids", server.GetUser(ctx), id.Invalid) } func (pp *polBox) GetMeta(ctx context.Context, zid id.Zid) (*meta.Meta, error) { m, err := pp.box.GetMeta(ctx, zid) if err != nil { return nil, err } user := server.GetUser(ctx) if pp.policy.CanRead(user, m) { return m, nil } return nil, box.NewErrNotAllowed("GetMeta", user, zid) } |
︙ |
Changes to auth/policy/default.go.
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - + | //----------------------------------------------------------------------------- // Copyright (c) 2020-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. //----------------------------------------------------------------------------- package policy import ( |
︙ |
Changes to auth/policy/owner.go.
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - + | //----------------------------------------------------------------------------- // Copyright (c) 2020-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. //----------------------------------------------------------------------------- package policy import ( |
︙ |
Changes to auth/policy/policy_test.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + | package policy import ( "fmt" "testing" |
︙ |
Changes to box/box.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - + | import ( "context" "errors" "fmt" "io" "time" |
︙ | |||
37 38 39 40 41 42 43 | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | - - - | // CreateZettel creates a new zettel. // Returns the new zettel id (and an error indication). CreateZettel(ctx context.Context, zettel zettel.Zettel) (id.Zid, error) // GetZettel retrieves a specific zettel. GetZettel(ctx context.Context, zid id.Zid) (zettel.Zettel, error) |
︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | + + + | // MetaFunc is a function that processes metadata of a zettel. type MetaFunc func(*meta.Meta) // ManagedBox is the interface of managed boxes. type ManagedBox interface { BaseBox // HasZettel returns true, if box conains zettel with given identifier. HasZettel(context.Context, id.Zid) bool // Apply identifier of every zettel to the given function, if predicate returns true. ApplyZid(context.Context, ZidFunc, query.RetrievePredicate) error // Apply metadata of every zettel to the given function, if predicate returns true. ApplyMeta(context.Context, MetaFunc, query.RetrievePredicate) error |
︙ | |||
128 129 130 131 132 133 134 135 136 | 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 | + + + + - + - - - | // Box is to be used outside the box package and its descendants. type Box interface { BaseBox // FetchZids returns the set of all zettel identifer managed by the box. FetchZids(ctx context.Context) (id.Set, error) // GetMeta returns the metadata of the zettel with the given identifier. GetMeta(context.Context, id.Zid) (*meta.Meta, error) // SelectMeta returns a list of metadata that comply to the given selection criteria. // If `metaSeq` is `nil`, the box assumes metadata of all available zettel. |
︙ |
Changes to box/compbox/compbox.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - + | // Package compbox provides zettel that have computed content. package compbox import ( "context" "net/url" |
︙ | |||
78 79 80 81 82 83 84 | 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 | - + - + - - + + - - - - - + - - - - - - + | } func (cb *compBox) GetZettel(_ context.Context, zid id.Zid) (zettel.Zettel, error) { if gen, ok := myZettel[zid]; ok && gen.meta != nil { if m := gen.meta(zid); m != nil { updateMeta(m) if genContent := gen.content; genContent != nil { |
︙ |
Changes to box/compbox/config.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package compbox import ( "bytes" |
︙ |
Changes to box/compbox/keys.go.
︙ | |||
10 11 12 13 14 15 16 | 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 | - + - + | package compbox import ( "bytes" "fmt" |
Changes to box/compbox/log.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package compbox import ( "bytes" |
︙ |
Changes to box/compbox/manager.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + | package compbox import ( "bytes" "fmt" |
︙ |
Changes to box/compbox/parser.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - + | import ( "bytes" "fmt" "sort" "strings" |
︙ |
Changes to box/compbox/version.go.
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - + | //----------------------------------------------------------------------------- // Copyright (c) 2020-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. //----------------------------------------------------------------------------- package compbox import ( |
︙ |
Changes to box/constbox/base.sxn.
︙ | |||
32 33 34 35 36 37 38 | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | - + | (a (@ (href ,list-tags-url)) "List Tags") ,@(if (bound? 'refresh-url) `((a (@ (href ,refresh-url)) "Refresh"))) )) ,@(if new-zettel-links `((div (@ (class "zs-dropdown")) (button "New") (nav (@ (class "zs-dropdown-content")) |
︙ |
Changes to box/constbox/constbox.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - + | package constbox import ( "context" _ "embed" // Allow to embed file content "net/url" |
︙ | |||
69 70 71 72 73 74 75 | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | - - + + - - - - - + | cb.log.Trace().Msg("GetZettel") return zettel.Zettel{Meta: meta.NewWithData(zid, z.header), Content: z.content}, nil } cb.log.Trace().Err(box.ErrNotFound).Msg("GetZettel") return zettel.Zettel{}, box.ErrNotFound } |
︙ | |||
219 220 221 222 223 224 225 | 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 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 | - + - + - + - + - + + + + + + + + + + | zettel.NewContent(contentZettelSxn)}, id.InfoTemplateZid: { constHeader{ api.KeyTitle: "Zettelstore Info HTML Template", api.KeyRole: api.ValueRoleConfiguration, api.KeySyntax: meta.SyntaxSxn, api.KeyCreated: "20200804111624", |
︙ | |||
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | + + + | //go:embed listzettel.sxn var contentListZettelSxn []byte //go:embed error.sxn var contentErrorSxn []byte //go:embed wuicode.sxn var contentTemplateCodeSxn []byte //go:embed base.css var contentBaseCSS []byte //go:embed emoji_spin.gif var contentEmoji []byte //go:embed newtoc.zettel var contentNewTOCZettel []byte //go:embed home.zettel var contentHomeZettel []byte |
Changes to box/constbox/delete.sxn.
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 | - + - + - + | `(article (header (h1 "Delete Zettel " ,zid)) (p "Do you really want to delete this zettel?") ,@(if shadowed-box `((div (@ (class "zs-info")) (h2 "Information") (p "If you delete this zettel, the previously shadowed zettel from overlayed box " ,shadowed-box " becomes available.") )) ) ,@(if incoming `((div (@ (class "zs-warning")) (h2 "Warning!") (p "If you delete this zettel, incoming references from the following zettel will become invalid.") |
Changes to box/constbox/dependencies.zettel.
︙ | |||
97 98 99 100 101 102 103 | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | - - - - - - - - - - - - - | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ``` |
︙ | |||
139 140 141 142 143 144 145 | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | - + - - + + - - | 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. ``` |
Changes to box/constbox/form.sxn.
1 2 3 4 5 6 7 8 9 10 11 | 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 | - - + - - - - - + - - - | `(article (header (h1 ,heading)) (form (@ (action ,form-action-url) (method "POST") (enctype "multipart/form-data")) (div (label (@ (for "zs-title")) "Title " (a (@ (title "Main heading of this zettel.")) (@H "ⓘ"))) (input (@ (class "zs-input") (type "text") (id "zs-title") (name "title") (placeholder "Title..") (value ,meta-title) (autofocus)))) (div (label (@ (for "zs-role")) "Role " (a (@ (title "One word, without spaces, to set the main role of this zettel.")) (@H "ⓘ"))) (input (@ (class "zs-input") (type "text") (id "zs-role") (name "role") (placeholder "role..") (value ,meta-role) ,@(if role-data '((list "zs-role-data"))) )) |
︙ |
Changes to box/constbox/info.sxn.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 | + - + - + - - - - - + - - - - - + - - - - - + - + - + | `(article (header (h1 "Information for Zettel " ,zid) (p (a (@ (href ,web-url)) "Web") (@H " · ") (a (@ (href ,context-url)) "Context") ,@(if (bound? 'edit-url) `((@H " · ") (a (@ (href ,edit-url)) "Edit"))) ,@(if (bound? 'copy-url) `((@H " · ") (a (@ (href ,copy-url)) "Copy"))) ,@(if (bound? 'version-url) `((@H " · ") (a (@ (href ,version-url)) "Version"))) ,@(if (bound? 'child-url) `((@H " · ") (a (@ (href ,child-url)) "Child"))) ,@(if (bound? 'folge-url) `((@H " · ") (a (@ (href ,folge-url)) "Folge"))) ,@(if (bound? 'rename-url) `((@H " · ") (a (@ (href ,rename-url)) "Rename"))) ,@(if (bound? 'delete-url) `((@H " · ") (a (@ (href ,delete-url)) "Delete"))) ) ) (h2 "Interpreted Metadata") |
Changes to box/constbox/listzettel.sxn.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | + + + + + - + - - - - + + + - + + | `(article (header (h1 ,heading)) (form (@ (action ,search-url)) (input (@ (class "zs-input") (type "text") (placeholder "Search..") (name ,query-key-query) (value ,query-value)))) ,@content ,@endnotes (form (@ (action ,(if (bound? 'create-url) create-url))) "Other encodings: " (a (@ (href ,data-url)) "data") ", " (a (@ (href ,plain-url)) "plain") |
Changes to box/constbox/login.sxn.
1 | 1 2 3 4 5 6 7 8 9 | - + | `(article |
︙ |
Changes to box/constbox/rename.sxn.
1 2 3 4 5 6 7 | 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 | - + - + - + - - + + - + | `(article (header (h1 "Rename Zettel " ,zid)) (p "Do you really want to rename this zettel?") ,@(if incoming `((div (@ (class "zs-warning")) (h2 "Warning!") (p "If you rename this zettel, incoming references from the following zettel will become invalid.") |
Added box/constbox/wuicode.sxn.
|
Changes to box/constbox/zettel.sxn.
1 2 3 4 5 6 7 | 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 | - + + + + + - + - - - - + + + + | `(article (header (h1 ,heading) (div (@ (class "zs-meta")) ,@(if (bound? 'edit-url) `((a (@ (href ,edit-url)) "Edit") (@H " · "))) ,zid (@H " · ") (a (@ (href ,info-url)) "Info") (@H " · ") |
Changes to box/dirbox/dirbox.go.
︙ | |||
256 257 258 259 260 261 262 | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | - + - - - - - - + - - - - - - - - | return zettel.Zettel{}, err } zettel := zettel.Zettel{Meta: m, Content: zettel.NewContent(c)} dp.log.Trace().Zid(zid).Msg("GetZettel") return zettel, nil } |
︙ | |||
349 350 351 352 353 354 355 | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | - + | return box.ErrNotFound } if dp.readonly { return box.ErrReadOnly } // Check whether zettel with new ID already exists in this box. |
︙ |
Changes to box/filebox/filebox.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - + | import ( "errors" "net/url" "path/filepath" "strings" |
︙ |
Changes to box/filebox/zipbox.go.
︙ | |||
136 137 138 139 140 141 142 | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | - - + + - - - - - - - - - - - | } CleanupMeta(m, zid, entry.ContentExt, inMeta, entry.UselessFiles) zb.log.Trace().Zid(zid).Msg("GetZettel") return zettel.Zettel{Meta: m, Content: zettel.NewContent(src)}, nil } |
︙ |
Changes to box/manager/box.go.
︙ | |||
90 91 92 93 94 95 96 | 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 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + - + - - + - - + - - - - + | mgr.Enrich(ctx, z.Meta, i+1) result = append(result, z) } } return result, nil } |
︙ |
Changes to box/manager/enrich.go.
︙ | |||
10 11 12 13 14 15 16 | 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 | - + + - + + | package manager import ( "context" "strconv" |
︙ |
Changes to box/manager/indexer.go.
︙ | |||
159 160 161 162 163 164 165 | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | - + | func (mgr *Manager) idxUpdateZettel(ctx context.Context, zettel zettel.Zettel) { var cData collectData cData.initialize() collectZettelIndexData(parser.ParseZettel(ctx, zettel, "", mgr.rtConfig), &cData) m := zettel.Meta |
︙ | |||
196 197 198 199 200 201 202 | 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 232 233 234 235 236 237 238 | - + - + - + | } } } } func (mgr *Manager) idxProcessData(ctx context.Context, zi *store.ZettelIndex, cData *collectData) { for ref := range cData.refs { |
Changes to box/manager/manager.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - + | import ( "context" "io" "net/url" "sync" "time" |
︙ |
Changes to box/manager/memstore/memstore.go.
︙ | |||
15 16 17 18 19 20 21 | 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 | - - + + + - + - - - - - - - + + + + + + + + - - - - - - - - - - - - + + + + + + + + - - - - + + + + + + + + + + + + + - + - + | "context" "fmt" "io" "sort" "strings" "sync" |
︙ | |||
96 97 98 99 100 101 102 | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | - + | updated = true } if len(zi.forward) > 0 { m.Set(api.KeyForward, zi.forward.String()) back = remRefs(back, zi.forward) updated = true } |
︙ | |||
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 | - + - + | continue } result.AddSlice(refs) } return result } |
︙ | |||
258 259 260 261 262 263 264 265 266 267 268 | 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 317 318 319 320 321 322 323 324 325 326 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 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - + + + - - + + - - + + - + - - + + - + - + - | } } } return back } func (ms *memStore) UpdateReferences(_ context.Context, zidx *store.ZettelIndex) id.Set { m := ms.makeMeta(zidx) ms.mx.Lock() defer ms.mx.Unlock() zi, ziExist := ms.idx[zidx.Zid] if !ziExist || zi == nil { |
︙ | |||
372 373 374 375 376 377 378 | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | - + - + - - + + - + - + | continue } srefs[word] = refs2 } return next.Words() } |
︙ | |||
441 442 443 444 445 446 447 | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | - + - + - + - - - + + + | return toCheck } func (ms *memStore) removeInverseMeta(zid id.Zid, key string, forward id.Slice) { // Must only be called if ms.mx is write-locked! for _, ref := range forward { bzi, ok := ms.idx[ref] |
︙ | |||
479 480 481 482 483 484 485 | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 | - + + + | ms.words[word] = refs2 } } func (ms *memStore) ReadStats(st *store.Stats) { ms.mx.RLock() st.Zettel = len(ms.idx) |
︙ | |||
514 515 516 517 518 519 520 | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | - + | fmt.Fprintln(w, "=====", id) zi := ms.idx[id] if len(zi.dead) > 0 { fmt.Fprintln(w, "* Dead:", zi.dead) } dumpZids(w, "* Forward:", zi.forward) dumpZids(w, "* Backward:", zi.backward) |
︙ |
Changes to box/manager/store/store.go.
︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | + + + | Urls uint64 } // Store all relevant zettel data. There may be multiple implementations, i.e. // memory-based, file-based, based on SQLite, ... type Store interface { query.Searcher // GetMeta returns the metadata of the zettel with the given identifier. GetMeta(context.Context, id.Zid) (*meta.Meta, error) // Entrich metadata with data from store. Enrich(ctx context.Context, m *meta.Meta) // UpdateReferences for a specific zettel. // Returns set of zettel identifier that must also be checked for changes. UpdateReferences(context.Context, *ZettelIndex) id.Set |
︙ |
Changes to box/manager/store/zettel.go.
1 2 3 4 5 6 7 8 9 10 11 12 | 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 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 | + - + + + - - - - - - + + + + + + + - + - - - - + + + + + - + - - + + - + - + - - + + + - + - - + - - - - + + + - - + + | //----------------------------------------------------------------------------- // Copyright (c) 2021-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. //----------------------------------------------------------------------------- package store import ( |
Changes to box/membox/membox.go.
︙ | |||
19 20 21 22 23 24 25 | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | - | "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" |
︙ | |||
126 127 128 129 130 131 132 | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | - + - + - - + - - - | return zettel.Zettel{}, box.ErrNotFound } z.Meta = z.Meta.Clone() mb.log.Trace().Msg("GetZettel") return z, nil } |
︙ |
Changes to box/notify/entry.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package notify import ( "path/filepath" |
︙ |
Changes to cmd/cmd_file.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - + | import ( "context" "flag" "fmt" "io" "os" |
︙ |
Changes to cmd/cmd_password.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - + | import ( "flag" "fmt" "os" "golang.org/x/term" |
︙ |
Changes to cmd/cmd_run.go.
︙ | |||
52 53 54 55 56 57 58 | 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 | + - + - + - - - + + + - - + - + - + - - + + - + - - - - - + + | protectedBoxManager, authPolicy := authManager.BoxWithPolicy(boxManager, rtConfig) kern := kernel.Main webLog := kern.GetLogger(kernel.WebService) var getUser getUserImpl logAuth := kern.GetLogger(kernel.AuthService) logUc := kern.GetLogger(kernel.CoreService).WithUser(&getUser) ucGetUser := usecase.NewGetUser(authManager, boxManager) |
︙ |
Changes to cmd/command.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package cmd import ( "flag" |
︙ |
Changes to cmd/main.go.
︙ | |||
18 19 20 21 22 23 24 | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | - + | "net/url" "os" "runtime/debug" "strconv" "strings" "time" |
︙ | |||
84 85 86 87 88 89 90 | 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 | - + - + - - + + - - + + - + - + - - + + | }) RegisterCommand(Command{ Name: "password", Func: cmdPassword, }) } |
︙ | |||
140 141 142 143 144 145 146 | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | - + | cfg.Set(keyDebug, flg.Value.String()) case "r": cfg.Set(keyReadOnly, flg.Value.String()) case "v": cfg.Set(keyVerbose, flg.Value.String()) } }) |
︙ | |||
247 248 249 250 251 252 253 | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | - + | return 1 } fs := command.GetFlags() if err := fs.Parse(args); err != nil { fmt.Fprintf(os.Stderr, "%s: unable to parse flags: %v %v\n", name, args, err) return 1 } |
︙ | |||
286 287 288 289 290 291 292 | 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 | - + - + | return nil }, ) if command.Simple { kern.SetConfig(kernel.ConfigService, kernel.ConfigSimpleMode, "true") } |
︙ |
Changes to docs/manual/00001002000000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + + + + + | id: 00001002000000 title: Design goals for the Zettelstore role: manual tags: #design #goal #manual #zettelstore syntax: zmk created: 20210126175322 |
︙ | |||
31 32 33 34 35 36 37 | 35 36 37 38 39 40 41 42 43 | + + | ; Simple service : The purpose of Zettelstore is to safely store your zettel and to provide some initial relations between them. : External software can be written to deeply analyze your zettel and the structures they form. ; Security by default : Without any customization, Zettelstore provides its services in a safe and secure manner and does not expose you (or other users) to security risks. : If you know what use are doing, Zettelstore allows you to relax some security-related preferences. However, even in this case, the more secure way is chosen. : The Zettelstore software uses a minimal design and uses other software dependencies only is essential needed. : There will be no plugin mechanism, which allows external software to control the inner workings of the Zettelstore software. |
Changes to docs/manual/00001005090000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - + | id: 00001005090000 title: List of predefined zettel role: manual tags: #manual #reference #zettelstore syntax: zmk created: 20210126175322 |
︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | + + | | [[00000000010200]] | Zettelstore Login Form HTML Template | Layout of the login form, when authentication is [[enabled|00001010040100]] | [[00000000010300]] | Zettelstore List Zettel HTML Template | Used when displaying a list of zettel | [[00000000010401]] | Zettelstore Detail HTML Template | Layout for the HTML detail view of one zettel | [[00000000010402]] | Zettelstore Info HTML Template | Layout for the information view of a specific zettel | [[00000000010403]] | Zettelstore Form HTML Template | Form that is used to create a new or to change an existing zettel that contains text | [[00000000010404]] | Zettelstore Rename Form HTML Template | View that is displayed to change the [[zettel identifier|00001006050000]] | [[00000000010405]] | Zettelstore Delete HTML Template | View to confirm the deletion of a zettel | [[00000000010700]] | Zettelstore Error HTML Template | View to show an error message | [[00000000019100]] | Zettelstore Sxn Code for Templates | Some helper functions to build the templates | [[00000000020001]] | Zettelstore Base CSS | System-defined CSS file that is included by the [[Base HTML Template|00000000010100]] | [[00000000025001]] | Zettelstore User CSS | User-defined CSS file that is included by the [[Base HTML Template|00000000010100]] | [[00000000029000]] | Zettelstore Role to CSS Map | [[Maps|00001017000000#role-css]] [[role|00001006020000#role]] to a zettel identifier that is included by the [[Base HTML Template|00000000010100]] as an CSS file | [[00000000040001]] | Generic Emoji | Image that is shown if [[original image reference|00001007040322]] is invalid | [[00000000090000]] | New Menu | Contains items that should contain in the zettel template menu | [[00000000090001]] | New Zettel | Template for a new zettel with role ""[[zettel|00001006020100]]"" | [[00000000090002]] | New User | Template for a new [[user zettel|00001010040200]] | [[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. |
Changes to docs/manual/00001006020000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - + | id: 00001006020000 title: Supported Metadata Keys role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk created: 20210126175322 |
︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | + + | When a zettel is expires, Zettelstore does nothing. It is up to you to define required actions. ''expire'' is just a documentation. You could define a query and execute it regularly, for example [[query:expire? ORDER expire]]. Alternatively, a Zettelstore client software could define some actions when it detects expired zettel. ; [!folge|''folge''] : Is a property that contains identifier of all zettel that reference this zettel through the [[''precursor''|#precursor]] value. ; [!folge-role|''folge-role''] : Specifies a suggested [[''role''|#role]] the zettel should use in the future, if zettel currently has a preliminary role. ; [!forward|''forward''] : Property that contains all references that identify another zettel within the content of the zettel. ; [!id|''id''] : Contains the [[zettel identifier|00001006050000]], as given by the Zettelstore. It cannot be set manually, because it is a computed value. ; [!lang|''lang''] : Language for the zettel. |
︙ |
Changes to docs/manual/00001006030000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - + | id: 00001006030000 title: Supported Key Types role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk created: 20210126175322 |
︙ | |||
22 23 24 25 26 27 28 | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | - + | | ''-zid'' | [[Identifier|00001006032000]] | ''-zids'' | [[IdentifierSet|00001006032500]] | any other suffix | [[EString|00001006031500]] The name of the metadata key is bound to the key type Every key type has an associated validation rule to check values of the given type. |
︙ |
Changes to docs/manual/00001006032000.zettel.
1 2 3 4 5 6 | 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 | - + + - + + + + + + + + + + | id: 00001006032000 title: Identifier Key Type role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk created: 20210212135017 |
Changes to docs/manual/00001006033000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + + + + + - + + + | id: 00001006033000 title: Number Key Type role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk created: 20210212135017 |
Changes to docs/manual/00001006034500.zettel.
1 2 3 4 5 6 | 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 | - + + + + + + - + + + | id: 00001006034500 title: Timestamp Key Type role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk created: 20210212135017 |
Changes to docs/manual/00001007700000.zettel.
1 | 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 | - + - + - + - + - - + - - + - - - - - - + - - + - - - - - - - - + - - - - + + - - - - - - - - - - - - - - - - + + + + - + - - - - - - - - - - - - - | id: 00001007700000 |
Added docs/manual/00001007701000.zettel.
|
Changes to docs/manual/00001007702000.zettel.
1 2 3 4 5 6 | 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 | - + + + + + | id: 00001007702000 title: Search term role: manual tags: #manual #search #zettelstore syntax: zmk created: 20220805150154 |
︙ |
Changes to docs/manual/00001007705000.zettel.
1 2 3 4 5 6 | 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 | - + - - - - - + + + + + + + - + + - + - - - - + + + + + + + + | id: 00001007705000 title: Search operator role: manual tags: #manual #search #zettelstore syntax: zmk created: 20220805150154 |
Added docs/manual/00001007710000.zettel.
|
Added docs/manual/00001007720000.zettel.
|
Added docs/manual/00001007720300.zettel.
|
Added docs/manual/00001007720600.zettel.
|
Added docs/manual/00001007720900.zettel.
|
Added docs/manual/00001007721200.zettel.
|
Added docs/manual/00001007770000.zettel.
|
Changes to docs/manual/00001007780000.zettel.
1 2 3 4 5 6 | 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 | - + - - + + + + + + + + + + + + - + | id: 00001007780000 title: Formal syntax of query expressions role: manual tags: #manual #reference #search #zettelstore syntax: zmk created: 20220810144539 |
Changes to docs/manual/00001007790000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | - + - + | id: 00001007790000 title: Useful query expressions role: manual tags: #example #manual #search #zettelstore syntax: zmk created: 20220810144539 |
Changes to docs/manual/00001008000000.zettel.
︙ | |||
45 46 47 48 49 50 51 | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | - - + + | : 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''] |
︙ |
Changes to docs/manual/00001012000000.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - + | id: 00001012000000 title: API role: manual tags: #api #manual #zettelstore syntax: zmk created: 20210126175322 |
︙ | |||
27 28 29 30 31 32 33 | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | - - | === Working with zettel * [[Create a new zettel|00001012053200]] * [[Retrieve metadata and content of an existing zettel|00001012053300]] * [[Retrieve metadata of an existing zettel|00001012053400]] * [[Retrieve evaluated metadata and content of an existing zettel in various encodings|00001012053500]] * [[Retrieve parsed metadata and content of an existing zettel in various encodings|00001012053600]] |
Changes to docs/manual/00001012051200.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - + | id: 00001012051200 title: API: List all zettel role: manual tags: #api #manual #zettelstore syntax: zmk created: 20210126175322 |
︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | ... ``` The list is **not** sorted, even in the these examples where it appears to be sorted. If you want to have it ordered, you must specify it with the help of a [[query expression|00001007700000]] / [[search term|00001007702000]]. See [[Query the list of all zettel|00001012051400]] how to do it. === Data output Alternatively, you may retrieve the zettel list as a parseable object / a [[symbolic expression|00001012930500]] by providing the query parameter ''enc=data'': ```sh # curl 'http://127.0.0.1:23123/z?enc=data' (meta-list (query "") (human "") (list (zettel (id "00001012921200") (meta (title "API: Encoding of Zettel Access Rights") (role "manual") (tags "#api #manual #reference #zettelstore") (syntax "zmk") (back "00001012051200 00001012051400 00001012053300 00001012053400 00001012053900 00001012054000") (backward "00001012051200 00001012051400 00001012053300 00001012053400 00001012053900 00001012054000") (box-number "1") (created "00010101000000") (forward "00001003000000 00001006020400 00001010000000 00001010040100 00001010040200 00001010070200 00001010070300") (modified "20220201171959") (published "20220201171959")) (rights 62)) (zettel (id "00001007030100") ... ``` Pretty-printed, this results in: ``` (meta-list (query "") (human "") (list (zettel (id "00001012921200") (meta (title "API: Encoding of Zettel Access Rights") (role "manual") (tags "#api #manual #reference #zettelstore") (syntax "zmk") (back "00001012051200 00001012051400 00001012053300 00001012053400 00001012053900 00001012054000") (backward "00001012051200 00001012051400 00001012053300 00001012053400 00001012053900 00001012054000") (box-number "1") (created "00010101000000") (forward "00001003000000 00001006020400 00001010000000 00001010040100 00001010040200 00001010070200 00001010070300") (modified "20220201171959") (published "20220201171959")) (rights 62)) (zettel (id "00001007030100") ``` * The result is a list, starting with the symbol ''meta-list''. * Then, some key/value pairs are following, also nested. * Keys ''query'' and ''human'' will be explained [[later in this manual|00001012051400]]. * ''list'' starts a list of zettel. * ''zettel'' itself start, well, a zettel. * ''id'' denotes the zettel identifier, encoded as a string. * Nested in ''meta'' are the metadata, each as a key/value pair. * ''rights'' specifies the [[access rights|00001012921200]] the user has for this zettel. === JSON output (deprecated) Alternatively, you may retrieve the list of all zettel as a JSON object by specifying the encoding with the query parameter ''enc=json'': ```sh # curl 'http://127.0.0.1:23123/z?enc=json' {"query":"","human":"","list":[{"id":"00001012051200","meta":{"back":"00001012000000","backward":"00001012000000 00001012920000","box-number":"1","created":"20210126175322","forward":"00001006020000 00001006050000 00001007700000 00001010040100 00001012050200 00001012051400 00001012920000 00001012921000 00001014000000","modified":"20221219150626","published":"20221219150626","role":"manual","syntax":"zmk","tags":"#api #manual #zettelstore","title":"API: List all zettel"},"rights":62},{"id":"00001012050600","meta":{"back":"00001012000000 00001012080500","backward":"00001012000000 00001012080500","box-number":"1","created":"00010101000000","forward":"00001012050200 00001012921000","modified":"20220218130020","published":"20220218130020","role":"manual","syntax":"zmk","tags":"#api #manual #zettelstore","title":"API: Provide an access token"},"rights":62},{"id":"00001012050400","meta":{"back":"00001010040700 00001012000000","backward":"00001010040700 00001012000000 00001012920000 00001012921000","box-number":"1","created":"00010101000000","forward":"00001010040100 00001012050200 00001012920000 00001012921000","modified":"20220107215751","published":"20220107215751","role":"manual","syntax":"zmk","tags":"#api #manual #zettelstore","title":"API: Renew an access token"},"rights":62},{"id":"00001012050200","meta":{"back":"00001012000000 00001012050400 00001012050600 00001012051200 00001012051400 00001012053300 00001012053400 00001012053500 00001012053600 00001012080200","backward":"00001010040700 00001012000000 00001012050400 00001012050600 00001012051200 00001012051400 00001012053300 00001012053400 00001012053500 00001012053600 00001012080200 00001012920000 00001012921000","box-number":"1","created":"00010101000000","forward":"00001004010000 00001010040100 00001010040200 00001010040700 00001012920000 00001012921000","modified":"20220107215844","published":"20220107215844","role":"manual","syntax":"zmk","tags":"#api #manual #zettelstore","title":"API: Authenticate a client"},"rights":62}, ...]} ``` |
︙ |
Changes to docs/manual/00001012051400.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - + + | id: 00001012051400 title: API: Query the list of all zettel role: manual tags: #api #manual #zettelstore syntax: zmk created: 20220912111111 |
︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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 | + + + + + + + + + + + + + + + + + + + + + - - - + | # curl 'http://127.0.0.1:23123/z?q=title%3AAPI+ORDER+REVERSE+id+OFFSET+1' 00001012921000 API: JSON structure of an access token 00001012920500 Formats available by the API 00001012920000 Endpoints used by the API ... ``` If you want to retrieve a data document, as a [[symbolic expression|00001012930500]]: ```sh # curl 'http://127.0.0.1:23123/z?q=title%3AAPI+ORDER+REVERSE+id+OFFSET+1&enc=data' (meta-list (query "title:API ORDER REVERSE id OFFSET 1") (human "title HAS API ORDER REVERSE id OFFSET 1") (list (zettel (id 1012921000) (meta (title "API: Structure of an access token") (role "manual") (tags "#api #manual #reference #zettelstore") (syntax "zmk") (back "00001012050600 00001012051200") (backward "00001012050200 00001012050400 00001012050600 00001012051200") (box-number "1") (created "20210126175322") (forward "00001012050200 00001012050400 00001012930000") (modified "20230412155303") (published "20230412155303")) (rights 62)) (zettel (id 1012920500) (meta (title "Encodings available via the API") (role "manual") (tags "#api #manual #reference #zettelstore") (syntax "zmk") (back "00001006000000 00001008010000 00001008010500 00001012053500 00001012053600") (backward "00001006000000 00001008010000 00001008010500 00001012053500 00001012053600") (box-number "1") (created "20210126175322") (forward "00001012000000 00001012920510 00001012920513 00001012920516 00001012920519 00001012920522 00001012920525") (modified "20230403123653") (published "20230403123653")) (rights 62)) (zettel (id 1012920000) (meta (title "Endpoints used by the API") ... ``` The data object contains a key ''"meta-list"'' to signal that it contains a list of metadata values (and some more). It contains the keys ''"query"'' and ''"human"'' with a string value. Both will contain a textual description of the underlying query if you select only some zettel with a [[query expression|00001007700000]]. Without a selection, the values are the empty string. ''"query"'' returns the normalized query expression itself, while ''"human"'' is the normalized query expression to be read by humans. where its value is a list of zettel JSON objects. The symbol ''list'' starts the list of zettel data. Data of a zettel is indicated by the symbol ''zettel'', followed by ''(id ID)'' that describes the zettel identifier as a numeric value. Leading zeroes are removed. Metadata starts with the symbol ''meta'', and each metadatum itself is a list of metadata key / metadata value. Metadata keys are encoded as a symbol, metadata values as a string. ''"rights"'' encodes the [[access rights|00001012921200]] for the given zettel. If you want to retrieve a JSON document: ```sh # curl 'http://127.0.0.1:23123/z?q=title%3AAPI+ORDER+REVERSE+id+OFFSET+1&enc=json' {"query":"title:API ORDER REVERSE id OFFSET 1","human":"title HAS API ORDER REVERSE id OFFSET 1","list":[{"id":"00001012921200","meta":{"back":"00001012051200 00001012051400 00001012053300 00001012053400 00001012053800 00001012053900 00001012054000","backward":"00001012051200 00001012051400 00001012053300 00001012053400 00001012053800 00001012053900 00001012054000","box-number":"1","created":"00010101000000","forward":"00001003000000 00001006020400 00001010000000 00001010040100 00001010040200 00001010070200 00001010070300","modified":"20220201171959","published":"20220201171959","role":"manual","syntax":"zmk","tags":"#api #manual #reference #zettelstore","title":"API: Encoding of Zettel Access Rights"},"rights":62},{"id":"00001012921000","meta":{"back":"00001012050600 00001012051200","backward":"00001012050200 00001012050400 00001012050600 00001012051200","box-number":"1","created":"00010101000000","forward":"00001012050200 00001012050400","published":"00010101000000","role":"manual","syntax":"zmk","tags":"#api #manual #reference #zettelstore","title":"API: JSON structure of an access token"},"rights":62}, ...] ``` The JSON object contains a key ''"list"'' where its value is a list of zettel JSON objects. These zettel JSON objects themselves contains the keys ''"id"'' (value is a string containing the [[zettel identifier|00001006050000]]), ''"meta"'' (value as a JSON object), and ''"rights"'' (encodes the [[access rights|00001012921200]] for the given zettel). The value of key ''"meta"'' effectively contains all metadata of the identified zettel, where metadata keys are encoded as JSON object keys and metadata values encoded as JSON strings. Additionally, the JSON object contains the keys ''"query"'' and ''"human"'' with a string value. |
︙ | |||
65 66 67 68 69 70 71 72 73 74 | 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 | + + + + + + + + + + + + + + + + + + + + + + + + - + - - + | The first word, separated by a horizontal tab (U+0009) contains the role name. The rest of the line consists of zettel identifier, where the corresponding zettel have this role. Zettel identifier are separated by a space character (U+0020). Please note that the list is **not** sorted by the role name, so the same request might result in a different order. If you want a sorted list, you could sort it on the command line (``curl 'http://127.0.0.1:23123/z?q=|role' | sort``) or within the software that made the call to the Zettelstore. Of course, this list can also be returned as a data object: ```sh # curl 'http://127.0.0.1:23123/z?q=|role&enc=data' (aggregate "role" (query "| role") (human "| role") (list ("zettel" 10000000000 90001) ("configuration" 6 100 1000000100 20001 90 25001 92 4 40001 1 90000 5 90002) ("manual" 1008050000 1007031110 1008000000 1012920513 1005000000 1012931800 1010040700 1012931000 1012053600 1006050000 1012050200 1012000000 1012070500 1012920522 1006032500 1006020100 1007906000 1007030300 1012051400 1007040350 1007040324 1007706000 1012931900 1006030500 1004050200 1012054400 1007700000 1004050000 1006020000 1007030400 1012080100 1012920510 1007790000 1010070400 1005090000 1004011400 1006033000 1012930500 1001000000 1007010000 1006020400 1007040300 1010070300 1008010000 1003305000 1006030000 1006034000 1012054200 1012080200 1004010000 1003300000 1006032000 1003310000 1004059700 1007031000 1003600000 1004000000 1007030700 1007000000 1006055000 1007050200 1006036000 1012050600 1006000000 1012053900 1012920500 1004050400 1007031100 1007040340 1007020000 1017000000 1012053200 1007030600 1007040320 1003315000 1012054000 1014000000 1007030800 1010000000 1007903000 1010070200 1004051200 1007040330 1004051100 1004051000 1007050100 1012080500 1012053400 1006035500 1012054600 1004100000 1010040200 1012920000 1012920525 1004051400 1006031500 1012921200 1008010500 1012921000 1018000000 1012051200 1010040100 1012931200 1012920516 1007040310 1007780000 1007030200 1004101000 1012920800 1007030100 1007040200 1012053500 1007040000 1007040322 1007031300 1007031140 1012931600 1012931400 1004059900 1003000000 1006036500 1004020200 1010040400 1006033500 1000000000 1012053300 1007990000 1010090100 1007900000 1007030500 1004011600 1012930000 1007030900 1004020000 1007030000 1010070600 1007040100 1007800000 1012050400 1006010000 1007705000 1007702000 1007050000 1002000000 1007031200 1006035000 1006031000 1006034500 1004011200 1007031400 1012920519))) ``` The data object starts with the symbol ''aggregate'' to signal a different format compared to ''meta-list'' above. Then a string follows, which specifies the key on which the aggregate was performed. ''query'' and ''human'' have the same meaning as above. The ''symbol'' list starts the result list of aggregates. Each aggregate starts with a string of the aggregate value, in this case the role value, followed by a list of zettel identifier, denoting zettel which have the given role value. Similar, to list all tags used in the Zettelstore, send a HTTP GET request to the endpoint ''/z?q=|tags''. If successful, the output is a data object: ```sh # curl 'http://127.0.0.1:23123/z?q=|tags&enc=data' (aggregate "tags" (query "| tags") (human "| tags") (list ("#zettel" 1006034500 1006034000 1006031000 1006020400 1006033500 1006036500 1006032500 1006020100 1006031500 1006030500 1006035500 1006033000 1006020000 1006036000 1006030000 1006032000 1006035000) ("#reference" 1006034500 1006034000 1007800000 1012920500 1006031000 1012931000 1006020400 1012930000 1006033500 1012920513 1007050100 1012920800 1007780000 1012921000 1012920510 1007990000 1006036500 1006032500 1006020100 1012931400 1012931800 1012920516 1012931600 1012920525 1012931200 1006031500 1012931900 1012920000 1005090000 1012920522 1006030500 1007050200 1012921200 1006035500 1012920519 1006033000 1006020000 1006036000 1006030000 1006032000 1012930500 1006035000) ("#graphic" 1008050000) ("#search" 1007700000 1007705000 1007790000 1007780000 1007702000 1007706000 1007031140) ("#installation" 1003315000 1003310000 1003000000 1003305000 1003300000 1003600000) ("#zettelmarkup" 1007900000 1007030700 1007031300 1007030600 1007800000 1007000000 1007031400 1007040100 1007030300 1007031200 1007040350 1007030400 1007030900 1007050100 1007040000 1007030500 1007903000 1007040200 1007040330 1007990000 1007040320 1007050000 1007040310 1007031100 1007040340 1007020000 1007031110 1007031140 1007040324 1007030800 1007031000 1007030000 1007010000 1007906000 1007050200 1007030100 1007030200 1007040300 1007040322) ("#design" 1005000000 1006000000 1002000000 1006050000 1006055000) ("#markdown" 1008010000 1008010500) ("#goal" 1002000000) ("#syntax" 1006010000) ... ``` If you want only those tags that occur at least 100 times, use the endpoint ''/z?q=|MIN100+tags''. You see from this that actions are separated by space characters. Of course, this list can also be returned as a JSON object: ```sh |
︙ |
Changes to docs/manual/00001012053200.zettel.
1 2 3 4 5 6 | 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 | - + + + + + + + + | id: 00001012053200 title: API: Create a new zettel role: manual tags: #api #manual #zettelstore syntax: zmk created: 20210713150005 |
︙ |
Changes to docs/manual/00001012053300.zettel.
1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - + | id: 00001012053300 title: API: Retrieve metadata and content of an existing zettel role: manual tags: #api #manual #zettelstore syntax: zmk created: 20211004093206 |
︙ | |||
34 35 36 37 38 39 40 | 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 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + | The [[endpoint|00001012920000]] to work with metadata and content of a specific zettel is ''/z/{ID}'', where ''{ID}'' is a placeholder for the [[zettel identifier|00001006050000]]. For example, to retrieve some data about this zettel you are currently viewing, just send a HTTP GET request to the endpoint ... ```` === Data output Alternatively, you may retrieve the zettel as a parseable object / a [[symbolic expression|00001012930500]] by providing the query parameter ''enc=data'': ```sh # curl 'http://127.0.0.1:23123/z/00001012053300?enc=data&part=zettel' (zettel (meta (back "00001006000000 00001012000000 00001012053200 00001012054400") (backward "00001006000000 00001012000000 00001012053200 00001012054400 00001012920000") (box-number "1") (created "20211004093206") (forward "00001006020000 00001006050000 00001010040100 00001012050200 00001012053400 00001012920000 00001012920800 00001012921200 00001012930500") (modified "20230703174152") (published "20230703174152") (role "manual") (syntax "zmk") (tags "#api #manual #zettelstore") (title "API: Retrieve metadata and content of an existing zettel")) (rights 62) (encoding "") (content "The [[endpoint|00001012920000]] to work with metadata and content of a specific zettel is ''/z/{ID}'', where ''{ID}'' is a placeholder for the [[zettel identifier|00001006050000]].\n\nFor example, ... ``` If you print the result a little bit nicer, you will see its structure: ``` (zettel (meta (back "00001006000000 00001012000000 00001012053200 00001012054400") (backward "00001006000000 00001012000000 00001012053200 00001012054400 00001012920000") (box-number "1") (created "20211004093206") (forward "00001006020000 00001006050000 00001010040100 00001012050200 00001012053400 00001012920000 00001012920800 00001012921200 00001012930500") (modified "20230703174152") (published "20230703174152") (role "manual") (syntax "zmk") (tags "#api #manual #zettelstore") (title "API: Retrieve metadata and content of an existing zettel")) (rights 62) (encoding "") (content "The [[endpoint|00001012920000]] to work with metadata and content of a specific zettel is ''/z/{ID}'', where ''{ID}'' is a placeholder for the [[zettel identifier|00001006050000]].\n\nFor example, ... ``` * The result is a list, starting with the symbol ''zettel''. * Then, some key/value pairs are following, also nested. * Nested in ''meta'' are the metadata, each as a key/value pair. * ''rights'' specifies the [[access rights|00001012921200]] the user has for this zettel. * ''"encoding"'' states how the content is encoded. Currently, only two values are allowed: the empty string (''""'') that specifies an empty encoding, and the string ''"base64"'' that specifies the [[standard Base64 encoding|https://www.rfc-editor.org/rfc/rfc4648.txt]]. * The zettel contents is stored as a value of the key ''content''. Typically, text content is not encoded, and binary content is encoded via Base64. |
︙ | |||
75 76 77 78 79 80 81 | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | - | ; ''"meta"'' : References an embedded JSON object with only string values. The name/value pairs of this objects are interpreted as the metadata of the new zettel. Please consider the [[list of supported metadata keys|00001006020000]] (and their value types). ; ''"encoding"'' : States how the content is encoded. Currently, only two values are allowed: the empty string (''""'') that specifies an empty encoding, and the string ''"base64"'' that specifies the [[standard Base64 encoding|https://www.rfc-editor.org/rfc/rfc4648.txt]]. |
︙ |
Changes to docs/manual/00001012053400.zettel.
1 2 3 4 5 6 | 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 61 62 63 | - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + | id: 00001012053400 title: API: Retrieve metadata of an existing zettel role: manual tags: #api #manual #zettelstore syntax: zmk created: 20210726174524 |
︙ |
Deleted docs/manual/00001012053900.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001012054000.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to docs/manual/00001012054200.zettel.
1 2 3 4 5 6 | 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 | - + + + + + + + + + | id: 00001012054200 title: API: Update a zettel role: manual tags: #api #manual #zettelstore syntax: zmk created: 20210713150005 |
︙ |
Changes to docs/manual/00001012070500.zettel.
1 2 3 4 5 | 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 | + - + - + - + - - - + + + - + + - + | id: 00001012070500 title: Retrieve administrative data role: manual tags: #api #manual #zettelstore syntax: zmk created: 00010101000000 |
Changes to docs/manual/00001012920000.zettel.
1 2 3 4 5 6 | 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 | - + - - - - + + | id: 00001012920000 title: Endpoints used by the API role: manual tags: #api #manual #reference #zettelstore syntax: zmk created: 20210126175322 |
Changes to docs/manual/00001012930500.zettel.
1 2 3 4 5 6 | 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 |
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | - - - + + + | ~~~draw +---+---+ +---+---+ +---+---+ | V | N +-->| V | N +--> -->| V | | +-+-+---+ +-+-+---+ +-+-+---+ | | | v v v |
︙ | |||
67 68 69 70 71 72 73 | 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 |
Changes to docs/readmezip.txt.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 | - + - | https://zettelstore.de/manual/. It is a live example of the zettelstore software, running in read-only mode. You can download it separately and it is possible to make it directly available for your local Zettelstore. The software, including the manual, is licensed under the European Union Public License 1.2 (or later). See the separate file LICENSE.txt. |
Changes to encoder/encoder.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - + | package encoder import ( "errors" "fmt" "io" |
︙ |
Changes to encoder/encoder_blob_test.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package encoder_test import ( "testing" |
︙ |
Changes to encoder/encoder_test.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - - + + | package encoder_test import ( "fmt" "strings" "testing" |
︙ | |||
107 108 109 110 111 112 113 | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | - + | t.Helper() encdr := encoder.Create(encoderSz) exp, err := pe.encode(encdr) if err != nil { t.Error(err) return } |
︙ |
Changes to encoder/htmlenc/htmlenc.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - - - - + + + + | // Package htmlenc encodes the abstract syntax tree into HTML5 via zettelstore-client. package htmlenc import ( "io" "strings" |
︙ | |||
52 53 54 55 56 57 58 | 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 | - + - + - + - + - + - + - + - + | func (he *Encoder) WriteZettel(w io.Writer, zn *ast.ZettelNode, evalMeta encoder.EvalMetaFunc) (int, error) { hm, err := he.th.Transform(he.tx.GetMeta(zn.InhMeta, evalMeta)) if err != nil { return 0, err } var isTitle ast.InlineSlice |
︙ | |||
144 145 146 147 148 149 150 | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | - + | return 0, err } // WriteInlines writes an inline slice to the writer func (he *Encoder) WriteInlines(w io.Writer, is *ast.InlineSlice) (int, error) { hobj, err := he.th.Transform(he.tx.GetSz(is)) if err == nil { |
Changes to encoder/mdenc/mdenc.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + | // Package mdenc encodes the abstract syntax tree back into Markdown. package mdenc import ( "io" |
︙ |
Changes to encoder/shtmlenc/shtmlenc.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - - - + + + | // Package shtmlenc encodes the abstract syntax tree into a s-expr which represents HTML. package shtmlenc import ( "io" |
︙ | |||
48 49 50 51 52 53 54 | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | - + | if err != nil { return 0, err } contentSHTML, err := enc.th.Transform(enc.tx.GetSz(&zn.Ast)) if err != nil { return 0, err } |
︙ |
Changes to encoder/szenc/szenc.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - - + + | // Package szenc encodes the abstract syntax tree into a s-expr for zettel. package szenc import ( "io" |
︙ | |||
36 37 38 39 40 41 42 | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | - + | trans *Transformer } // WriteZettel writes the encoded zettel to the writer. func (enc *Encoder) WriteZettel(w io.Writer, zn *ast.ZettelNode, evalMeta encoder.EvalMetaFunc) (int, error) { content := enc.trans.GetSz(&zn.Ast) meta := enc.trans.GetMeta(zn.InhMeta, evalMeta) |
︙ |
Changes to encoder/szenc/transform.go.
︙ | |||
11 12 13 14 15 16 17 | 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 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 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 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 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 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 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 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | - - - + + + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + + + + + + + + + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - - - + + + - + - + - + - + - + - - + + - + - + - + - + - - + + - + - + - + - + - + - - + + - + - + - + - - + + - + - + - - + + - + - + - + - + - + - + - + - + - - + + - + - - + + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + | package szenc import ( "encoding/base64" "fmt" "strings" |
Changes to encoder/textenc/textenc.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + | // Package textenc encodes the abstract syntax tree into its text. package textenc import ( "io" |
︙ |
Changes to encoder/zmkenc/zmkenc.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - - + + | package zmkenc import ( "fmt" "io" "strings" |
︙ |
Changes to encoding/atom/atom.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - + | // Package atom provides an Atom encoding. package atom import ( "bytes" "time" |
︙ |
Changes to encoding/encoding.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + | // Package encoding provides helper functions for encodings. package encoding import ( "time" |
︙ |
Changes to encoding/rss/rss.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - + | package rss import ( "bytes" "context" "time" |
︙ |
Changes to evaluator/evaluator.go.
︙ | |||
15 16 17 18 19 20 21 | 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 | - - + + - - + | "context" "errors" "fmt" "path" "strconv" "strings" |
︙ | |||
251 252 253 254 255 256 257 | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | - + | e.transcludeCount += cost.ec } return &zn.Ast } func (e *evaluator) evalQueryTransclusion(expr string) ast.BlockNode { q := query.Parse(expr) |
︙ | |||
341 342 343 344 345 346 347 | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | - + | } ref := ln.Ref if ref == nil || ref.State != ast.RefStateZettel { return ln } zid := mustParseZid(ref) |
︙ |
Changes to evaluator/list.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | - - + + | "bytes" "context" "math" "sort" "strconv" "strings" |
︙ |
Changes to go.mod.
1 2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - + - - - - - - - - + + + + + + - + | module zettelstore.de/z |
Changes to go.sum.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | - - - - - - - - - - + + + + - - - - - - - - + + + + + + + + + + |
|
Changes to kernel/impl/cfg.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - + | "context" "errors" "fmt" "strconv" "strings" "sync" |
︙ | |||
143 144 145 146 147 148 149 | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | - + + | func (cs *configService) setBox(mgr box.Manager) { mgr.RegisterObserver(cs.observe) cs.observe(box.UpdateInfo{Box: mgr, Reason: box.OnZettel, Zid: id.ConfigurationZid}) } func (cs *configService) doUpdate(p box.BaseBox) error { |
︙ |
Changes to kernel/impl/cmd.go.
︙ | |||
15 16 17 18 19 20 21 | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | - + | "io" "os" "runtime/metrics" "sort" "strconv" "strings" |
︙ |
Changes to kernel/impl/config.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - + | "errors" "fmt" "sort" "strconv" "strings" "sync" |
︙ |
Changes to kernel/impl/core.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - + | "fmt" "net" "os" "runtime" "sync" "time" |
︙ |
Changes to kernel/impl/impl.go.
︙ | |||
125 126 127 128 129 130 131 | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | - + | func (kern *myKernel) Setup(progname, version string, versionTime time.Time) { kern.SetConfig(kernel.CoreService, kernel.CoreProgname, progname) kern.SetConfig(kernel.CoreService, kernel.CoreVersion, version) kern.SetConfig(kernel.CoreService, kernel.CoreVTime, versionTime.Local().Format(id.ZidLayout)) } |
︙ | |||
156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | + + + + + | kern.core.GetCurConfig(kernel.CoreProgname), kern.core.GetCurConfig(kernel.CoreVersion), kern.core.GetCurConfig(kernel.CoreGoVersion), kern.core.GetCurConfig(kernel.CoreGoOS), kern.core.GetCurConfig(kernel.CoreGoArch), )) logger.Mandatory().Msg("Licensed under the latest version of the EUPL (European Union Public License)") if configFilename != "" { logger.Mandatory().Str("filename", configFilename).Msg("Configuration file found") } else { logger.Mandatory().Msg("No configuration file found / used") } if kern.core.GetCurConfig(kernel.CoreDebug).(bool) { logger.Warn().Msg("----------------------------------------") logger.Warn().Msg("DEBUG MODE, DO NO USE THIS IN PRODUCTION") logger.Warn().Msg("----------------------------------------") } if kern.auth.GetCurConfig(kernel.AuthReadonly).(bool) { logger.Info().Msg("Read-only mode") |
︙ |
Changes to kernel/kernel.go.
︙ | |||
27 28 29 30 31 32 33 | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - + | // Kernel is the main internal service. type Kernel interface { // Setup sets the most basic data of a software: its name, its version, // and when the version was created. Setup(progname, version string, versionTime time.Time) // Start the service. |
︙ |
Changes to logger/message.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - + | import ( "context" "net/http" "strconv" "sync" |
︙ |
Changes to parser/draw/draw.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - + | // 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" |
︙ |
Changes to parser/markdown/markdown.go.
︙ | |||
17 18 19 20 21 22 23 | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | - + | "strconv" "strings" gm "github.com/yuin/goldmark" gmAst "github.com/yuin/goldmark/ast" gmText "github.com/yuin/goldmark/text" |
︙ |
Changes to parser/parser.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - + | package parser import ( "context" "fmt" "strings" |
︙ |
Changes to parser/plain/plain.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | + - - + + - - + | // Package plain provides a parser for plain text data. package plain import ( "bytes" "strings" "zettelstore.de/client.fossil/attrs" |
︙ | |||
132 133 134 135 136 137 138 | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | - + | return "" } // TODO: check proper end </svg> return svgSrc } func parseSxnBlocks(inp *input.Input, _ *meta.Meta, syntax string) ast.BlockSlice { |
︙ |
Changes to parser/zettelmark/inline.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - + | package zettelmark import ( "bytes" "fmt" "strings" |
︙ |
Changes to parser/zettelmark/zettelmark.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - + | // Package zettelmark provides a parser for zettelmarkup. package zettelmark import ( "strings" "unicode" |
︙ |
Changes to parser/zettelmark/zettelmark_test.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - + | package zettelmark_test import ( "fmt" "strings" "testing" |
︙ |
Changes to query/compiled.go.
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | - - - + + + | hasQuery bool seed int pick int order []sortOrder offset int // <= 0: no offset limit int // <= 0: no limit |
︙ | |||
47 48 49 50 51 52 53 | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | - - + + - + - - + + - + | // RetrievePredicate returns true, if the given Zid is contained in the (full-text) search. type RetrievePredicate func(id.Zid) bool func (c *Compiled) isDeterministic() bool { return c.seed > 0 } // Result returns a result of the compiled search, that is achievable without iterating through a box. func (c *Compiled) Result() []*meta.Meta { |
︙ |
Changes to query/context.go.
︙ | |||
9 10 11 12 13 14 15 | 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 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 129 130 131 132 133 134 | - + + + + + + + + + - + - - - + + + - + + - + - - - + + - - - + + + + + + + + + + - - - - + + + + + + - + - - - + + + - + - - + - - - - - - - + + + + + + - + - - - - - - - - + - - - - - - - + + + + + + + + + + + + + + + + + + | //----------------------------------------------------------------------------- package query import ( "context" |
︙ | |||
149 150 151 152 153 154 155 | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | - - + - - - - + - - - + + - - | return 3 } func (zc *contextQueue) addID(ctx context.Context, newCost int, value string) { if zc.costMaxed(newCost) { return } |
︙ | |||
194 195 196 197 198 199 200 | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | + + + - + | // We have not found a task, therefore the new task is the first one task.next = zc.first zc.first.prev = task zc.first = task } func (zc *contextQueue) costMaxed(newCost int) bool { // If len(zc.seen) <= 1, the initial zettel is processed. In this case allow all // other zettel that are directly reachable, without taking the cost into account. // Of course, the limit ist still relevant. |
︙ | |||
228 229 230 231 232 233 234 | 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 | - + - - + - | return baseCost * numReferences / 8 } func (zc *contextQueue) addSameTag(ctx context.Context, tag string, baseCost int) { tagMetas, found := zc.tagCost[tag] if !found { q := Parse(api.KeyTags + api.SearchOperatorHas + tag + " ORDER REVERSE " + api.KeyID) |
︙ | |||
279 280 281 282 283 284 285 | 292 293 294 295 296 297 298 299 300 | - + | return m, task.cost } return nil, -1 } func (zc *contextQueue) hasLimit() bool { limit := zc.limit |
Changes to query/parser.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package query import ( "strconv" |
︙ | |||
52 53 54 55 56 57 58 | 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 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 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 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 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 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | - - - - - - - - - + + + + + + + + + - - - + - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - - - - + - - - - + - - - - - - - - - - - + + + + + + + + + + - - - + + - - + + + - + - - + + - - + + - - + + - - + + + - + + + - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + | ps.skipSpace() return true } return false } const ( |
︙ | |||
346 347 348 349 350 351 352 | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | - + + | allowKey := !hasOp for !ps.isSpace() && !isActionSep(inp.Ch) && !ps.mustStop() { if allowKey { switch inp.Ch { case searchOperatorNotChar, existOperatorChar, searchOperatorEqualChar, searchOperatorHasChar, |
︙ | |||
420 421 422 423 424 425 426 427 428 429 430 431 432 433 | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | + + + + + + | op = cmpSuffix case searchOperatorPrefixChar: inp.Next() op = cmpPrefix case searchOperatorMatchChar: inp.Next() op = cmpMatch case searchOperatorLessChar: inp.Next() op = cmpLess case searchOperatorGreaterChar: inp.Next() op = cmpGreater default: if negate { return cmpNoMatch, true } return cmpUnknown, false } if negate { |
︙ |
Changes to query/parser_test.go.
︙ | |||
18 19 20 21 22 23 24 | 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 | + + + + + + + + - - - + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + - + - - + + - - + + + + - - + + + + | func TestParser(t *testing.T) { t.Parallel() testcases := []struct { spec string exp string }{ {"1", "1"}, // Just a number will transform to search for that numer in all zettel {"1 IDENT", "00000000000001 IDENT"}, {"IDENT", "IDENT"}, {"1 ITEMS", "00000000000001 ITEMS"}, {"ITEMS", "ITEMS"}, |
︙ |
Changes to query/print.go.
︙ | |||
11 12 13 14 15 16 17 | 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 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 | - - + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - + + + + + - - - + - - + - - + + + - + - + - - - - - + + + + + + + + + + - - - - - - + - - - - - - - + + - + - - + | package query import ( "io" "strconv" "strings" |
︙ | |||
153 154 155 156 157 158 159 | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | - - + + + + + | } // PrintHuman the query to a writer in a human readable form. func (q *Query) PrintHuman(w io.Writer) { if q == nil { return } |
︙ | |||
193 194 195 196 197 198 199 | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | - + - - + + - + | } env.writeString("ANY") env.printHumanSelectExprValues(term.search) env.space = true } } |
︙ | |||
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | 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 293 294 | + + + + + + + + - + - + - + - + - + - + - - - + | pe.writeString(" SUFFIX ") case cmpNoSuffix: pe.writeString(" NOT SUFFIX ") case cmpMatch: pe.writeString(" MATCH ") case cmpNoMatch: pe.writeString(" NOT MATCH ") case cmpLess: pe.writeString(" LESS ") case cmpNoLess: pe.writeString(" NOT LESS ") case cmpGreater: pe.writeString(" GREATER ") case cmpNoGreater: pe.writeString(" NOT GREATER ") default: pe.writeString(" MaTcH ") } if val.value == "" { pe.writeString("NOTHING") } else { pe.writeString(val.value) } } } |
Changes to query/query.go.
︙ | |||
36 37 38 39 40 41 42 | 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 | - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | // Select all zettel that contains the given string. // The string must be normalized through Unicode NKFD, trimmed and not empty. SearchContains(s string) id.Set } // Query specifies a mechanism for querying zettel. type Query struct { |
︙ | |||
109 110 111 112 113 114 115 | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | - - - - + + + + + + + - | // Clone the query value. func (q *Query) Clone() *Query { if q == nil { return nil } c := new(Query) |
︙ | |||
162 163 164 165 166 167 168 169 170 171 | 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 232 233 234 235 236 237 238 | + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + | cmpHasNot cmpPrefix cmpNoPrefix cmpSuffix cmpNoSuffix cmpMatch cmpNoMatch cmpLess cmpNoLess cmpGreater cmpNoGreater ) var negateMap = map[compareOp]compareOp{ |
︙ | |||
239 240 241 242 243 244 245 | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | - - - - - - - - - - - - - - - - - - | q = createIfNeeded(q) if q.seed <= 0 { q.seed = int(rand.Intn(10000) + 1) } return q } |
︙ | |||
278 279 280 281 282 283 284 | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | - + | // EnrichNeeded returns true, if the query references a metadata key that // is calculated via metadata enrichments. func (q *Query) EnrichNeeded() bool { if q == nil { return false } |
︙ | |||
305 306 307 308 309 310 311 | 324 325 326 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 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | - - - - - - - + - + - - - - - - - - + - - - - + - - - - - - - - - + + + + + + + + + - + - + - + - + - + - - + + | if meta.IsProperty(o.key) { return true } } return false } |
︙ |
Changes to query/retrieve.go.
︙ | |||
24 25 26 27 28 29 30 | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | - - - - - + + + + + + + | s string op compareOp } type searchFunc func(string) id.Set type searchCallMap map[searchOp]searchFunc var cmpPred = map[compareOp]func(string, string) bool{ |
︙ | |||
158 159 160 161 162 163 164 | 160 161 162 163 164 165 166 167 168 169 170 171 172 | - + | switch op { case cmpEqual: return searcher.SearchEqual case cmpPrefix: return searcher.SearchPrefix case cmpSuffix: return searcher.SearchSuffix |
Changes to query/select.go.
︙ | |||
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 | 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 61 62 63 64 65 66 67 68 69 70 71 | + - - - + + + + + + + + + + + + + + + + + | // under this license. //----------------------------------------------------------------------------- package query import ( "fmt" "strconv" "strings" "unicode/utf8" "zettelstore.de/z/encoder/textenc" "zettelstore.de/z/parser" "zettelstore.de/z/strfun" "zettelstore.de/z/zettel/meta" ) type matchValueFunc func(value string) bool func matchValueNever(string) bool { return false } type matchSpec struct { key string match matchValueFunc } // compileMeta calculates a selection func based on the given select criteria. func (ct *conjTerms) compileMeta() MetaMatchFunc { |
︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 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 | + + - + + + + + + + + + + + + + | switch meta.Type(key) { case meta.TypeCredential: return matchValueNever case meta.TypeID, meta.TypeTimestamp: // ID and timestamp use the same layout return createMatchIDFunc(values, addSearch) case meta.TypeIDSet: return createMatchIDSetFunc(values, addSearch) case meta.TypeNumber: return createMatchNumberFunc(values, addSearch) case meta.TypeTagSet: return createMatchTagSetFunc(values, addSearch) case meta.TypeWord: return createMatchWordFunc(values, addSearch) case meta.TypeWordSet: return createMatchWordSetFunc(values, addSearch) case meta.TypeZettelmarkup: return createMatchZmkFunc(values, addSearch) } return createMatchStringFunc(values, addSearch) } func createMatchIDFunc(values []expValue, addSearch addSearchFunc) matchValueFunc { |
︙ | |||
312 313 314 315 316 317 318 319 320 321 322 323 324 325 | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | result = append(result, valueElems) } } return result } type stringPredicate func(string) bool func valuesToIDPredicates(values []expValue, addSearch addSearchFunc) []stringPredicate { result := make([]stringPredicate, len(values)) for i, v := range values { value := v.value if len(value) > 14 { value = value[:14] } switch op := disambiguatedIDOp(v.op); op { case cmpLess, cmpNoLess, cmpGreater, cmpNoGreater: if isDigits(value) { // Never add the strValue to search. // Append enough zeroes to make it comparable as string. // (an ID and a timestamp always have 14 digits) strValue := value + "00000000000000"[:14-len(value)] result[i] = createIDCompareFunc(strValue, op) continue } fallthrough default: // Otherwise compare as a word. if !op.isNegated() { addSearch(v) // addSearch only for positive selections } result[i] = createWordCompareFunc(value, op) } } return result } func isDigits(s string) bool { for i := 0; i < len(s); i++ { if ch := s[i]; ch < '0' || '9' < ch { return false } } return true } func disambiguatedIDOp(cmpOp compareOp) compareOp { return disambiguateWordOp(cmpOp) } func createIDCompareFunc(cmpVal string, cmpOp compareOp) stringPredicate { return createWordCompareFunc(cmpVal, cmpOp) } func valuesToNumberPredicates(values []expValue, addSearch addSearchFunc) []stringPredicate { result := make([]stringPredicate, len(values)) for i, v := range values { switch op := disambiguatedNumberOp(v.op); op { case cmpEqual, cmpNotEqual, cmpLess, cmpNoLess, cmpGreater, cmpNoGreater: iValue, err := strconv.ParseInt(v.value, 10, 64) if err == nil { // Never add the strValue to search. result[i] = createNumberCompareFunc(iValue, op) continue } fallthrough default: // In all other cases, a number is treated like a word. if !op.isNegated() { addSearch(v) // addSearch only for positive selections } result[i] = createWordCompareFunc(v.value, op) } } return result } func disambiguatedNumberOp(cmpOp compareOp) compareOp { return disambiguateWordOp(cmpOp) } func createNumberCompareFunc(cmpVal int64, cmpOp compareOp) stringPredicate { var cmpFunc func(int64) bool switch cmpOp { case cmpEqual: cmpFunc = func(iMetaVal int64) bool { return iMetaVal == cmpVal } case cmpNotEqual: cmpFunc = func(iMetaVal int64) bool { return iMetaVal != cmpVal } case cmpLess: cmpFunc = func(iMetaVal int64) bool { return iMetaVal < cmpVal } case cmpNoLess: cmpFunc = func(iMetaVal int64) bool { return iMetaVal >= cmpVal } case cmpGreater: cmpFunc = func(iMetaVal int64) bool { return iMetaVal > cmpVal } case cmpNoGreater: cmpFunc = func(iMetaVal int64) bool { return iMetaVal <= cmpVal } default: panic(fmt.Sprintf("Unknown compare operation %d with value %q", cmpOp, cmpVal)) } return func(metaVal string) bool { iMetaVal, err := strconv.ParseInt(metaVal, 10, 64) if err != nil { return false } return cmpFunc(iMetaVal) } } func valuesToStringPredicates(values []expValue, addSearch addSearchFunc) []stringPredicate { result := make([]stringPredicate, len(values)) for i, v := range values { op := disambiguatedStringOp(v.op) if !op.isNegated() { addSearch(v) // addSearch only for positive selections |
︙ | |||
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | + + + + + + + + - + - + - + - + - + - + + + - - - + + + + + - + + + | return func(metaVal string) bool { return strings.HasSuffix(metaVal, cmpVal) } case cmpNoSuffix: return func(metaVal string) bool { return !strings.HasSuffix(metaVal, cmpVal) } case cmpMatch: return func(metaVal string) bool { return strings.Contains(metaVal, cmpVal) } case cmpNoMatch: return func(metaVal string) bool { return !strings.Contains(metaVal, cmpVal) } case cmpLess: return func(metaVal string) bool { return metaVal < cmpVal } case cmpNoLess: return func(metaVal string) bool { return metaVal >= cmpVal } case cmpGreater: return func(metaVal string) bool { return metaVal > cmpVal } case cmpNoGreater: return func(metaVal string) bool { return metaVal <= cmpVal } case cmpHas, cmpHasNot: panic(fmt.Sprintf("operator %d not disambiguated with value %q", cmpOp, cmpVal)) default: panic(fmt.Sprintf("Unknown compare operation %d with value %q", cmpOp, cmpVal)) } } type stringSetPredicate func(value []string) bool func valuesToWordSetPredicates(values [][]expValue, addSearch addSearchFunc) [][]stringSetPredicate { result := make([][]stringSetPredicate, len(values)) for i, val := range values { elemPreds := make([]stringSetPredicate, len(val)) for j, v := range val { opVal := v.value // loop variable is used in closure --> save needed value switch op := disambiguateWordOp(v.op); op { case cmpEqual: addSearch(v) // addSearch only for positive selections |
︙ |
Changes to query/select_test.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | - + - + | package query_test import ( "context" "testing" |
︙ |
Changes to query/sorter.go.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | //----------------------------------------------------------------------------- package query import ( "strconv" |
︙ |
Added query/specs.go.
|
Added query/unlinked.go.
|
Changes to strfun/strfun.go.
︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | + | //----------------------------------------------------------------------------- // Package strfun provides some string functions. package strfun import ( "strings" "unicode" "unicode/utf8" ) // Length returns the number of runes in the given string. func Length(s string) int { return utf8.RuneCountInString(s) } |
︙ | |||
47 48 49 50 51 52 53 | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | + + + + + + + + | // SplitLines splits the given string into a list of lines. func SplitLines(s string) []string { return strings.FieldsFunc(s, func(r rune) bool { return r == '\n' || r == '\r' }) } // MakeWords produces a list of words, i.e. string that were separated by // control character, space characters, or separator characters. func MakeWords(text string) []string { return strings.FieldsFunc(text, func(r rune) bool { return unicode.In(r, unicode.C, unicode.P, unicode.Z) }) } |
Changes to tests/client/client_test.go.
︙ | |||
16 17 18 19 20 21 22 | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | - - + + | "flag" "fmt" "net/http" "net/url" "strconv" "testing" |
︙ | |||
45 46 47 48 49 50 51 | 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 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 | - - - - + + + + - + - + - + - + - + - + - + - + - + + + + - - + + - + | } } } func TestListZettel(t *testing.T) { const ( |
︙ | |||
192 193 194 195 196 197 198 | 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 | - - - - - - - - - - + - + - - - - - + - - + + | } if len(content) == 0 { t.Errorf("Empty content for evaluated encoding %v", enc) } } } |
︙ | |||
280 281 282 283 284 285 286 | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | - + - - - - - + | // checkListZid(t, l, 0, allUserZid) // } func TestGetUnlinkedReferences(t *testing.T) { t.Parallel() c := getClient() c.SetAuth("owner", "owner") |
︙ | |||
335 336 337 338 339 340 341 | 321 322 323 324 325 326 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 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | - + - - + + - - + + - - - + + + - + - - + + - + - + | } } func TestListTags(t *testing.T) { t.Parallel() c := getClient() c.SetAuth("owner", "owner") |
︙ |
Changes to tests/client/crud_test.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - - + + | package client_test import ( "context" "strings" "testing" |
︙ | |||
55 56 57 58 59 60 61 | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | - + - + | t.Error("Cannot rename", zid, ":", err) newZid = zid } doDelete(t, c, newZid) } |
︙ | |||
84 85 86 87 88 89 90 | 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 | - + - + - + | newZid = zid } c.SetAuth("owner", "owner") doDelete(t, c, newZid) } |
︙ | |||
148 149 150 151 152 153 154 | 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 173 174 175 176 177 178 179 180 181 182 183 | - + - + - + - + | if string(zt) != newZettel { t.Errorf("Expected zettel %q, got %q", newZettel, zt) } // Must delete to clean up for next tests doDelete(t, c, api.ZidDefaultHome) } |
︙ |
Changes to tests/client/embed_test.go.
︙ | |||
11 12 13 14 15 16 17 | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - + | package client_test import ( "context" "strings" "testing" |
︙ | |||
73 74 75 76 77 78 79 | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | - + | } func TestZettelTransclusionNoPrivilegeEscalation(t *testing.T) { t.Parallel() c := getClient() c.SetAuth("reader", "reader") |
︙ |
Changes to tests/markdown_test.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - + | "bytes" "encoding/json" "fmt" "os" "strings" "testing" |
︙ |
Changes to tests/regression_test.go.
︙ | |||
17 18 19 20 21 22 23 | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | - + | "io" "net/url" "os" "path/filepath" "strings" "testing" |
︙ |
Changes to tools/build.go.
︙ | |||
24 25 26 27 28 29 30 | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | - + + | "path/filepath" "strings" "time" "zettelstore.de/z/strfun" ) |
︙ | |||
135 136 137 138 139 140 141 142 143 | 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 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 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 | + + + - + - + - + - + - + - + | return err } } return checkFossilExtra() } func checkGoTest(pkg string, testParams ...string) error { var env []string env = append(env, envDirectProxy...) env = append(env, envGoVCS...) args := []string{"test", pkg} args = append(args, testParams...) |
︙ | |||
279 280 281 282 283 284 285 | 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 | - + + | func startZettelstore(info *zsInfo) error { info.adminAddress = ":2323" name, arg := "go", []string{ "run", "cmd/zettelstore/main.go", "run", "-c", "./testdata/testbox/19700101000000.zettel", "-a", info.adminAddress[1:]} logCommand("FORK", nil, name, arg) |
︙ | |||
317 318 319 320 321 322 323 | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | - + + | return false } conn.Close() return true } func cmdBuild() error { |
︙ | |||
423 424 425 426 427 428 429 | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | + - + | {"amd64", "darwin", nil, "zettelstore"}, {"arm64", "darwin", nil, "zettelstore"}, {"amd64", "windows", nil, "zettelstore.exe"}, } for _, rel := range releases { env := append([]string{}, rel.env...) env = append(env, "GOARCH="+rel.arch, "GOOS="+rel.os) env = append(env, envDirectProxy...) |
︙ |
Changes to usecase/authenticate.go.
︙ | |||
12 13 14 15 16 17 18 | 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 | - + - - - - - - - - - + - + - - + | import ( "context" "math/rand" "net/http" "time" |
︙ |
Changes to usecase/create_zettel.go.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - + | package usecase import ( "context" "time" |
︙ | |||
70 71 72 73 74 75 76 | 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 | - + - - + + + + + + + + + + + + - - - + + + + + + + | // PrepareFolge the zettel for further modification. func (*CreateZettel) PrepareFolge(origZettel zettel.Zettel) zettel.Zettel { origMeta := origZettel.Meta m := meta.New(id.Invalid) if title, found := origMeta.Get(api.KeyTitle); found { m.Set(api.KeyTitle, prependTitle(title, "Folge", "Folge of ")) } |
︙ |
Changes to usecase/evaluate.go.
︙ | |||
21 22 23 24 25 26 27 | 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 | - - - + + + - - + - - - + + + - - + - + - - - + + + + - + - - - - - - + - - - + + + | "zettelstore.de/z/zettel" "zettelstore.de/z/zettel/id" "zettelstore.de/z/zettel/meta" ) // Evaluate is the data for this use case. type Evaluate struct { |
Deleted usecase/get_all_meta.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Added usecase/get_all_zettel.go.
|
Deleted usecase/get_meta.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to usecase/get_user.go.
︙ | |||
9 10 11 12 13 14 15 | 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 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 | - + + - - + + - - - + + + - + - + - + + | //----------------------------------------------------------------------------- package usecase import ( "context" |
Changes to usecase/lists.go.
︙ | |||
9 10 11 12 13 14 15 | 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | - + - - - - - - + - - - - + - - - - - - - - - - - - - - - + - + - - + - + | //----------------------------------------------------------------------------- package usecase import ( "context" |
Deleted usecase/order.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Added usecase/query.go.