Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From version-0.0.10 To version-0.0.9
2021-02-26
| ||
11:53 | Increase version to 0.0.11-dev to begin next development cycle ... (check-in: d69e61d8eb user: stern tags: trunk) | |
11:14 | Version 0.0.10 ... (check-in: 5d9e4fc19e user: stern tags: trunk, release, version-0.0.10) | |
10:36 | WebUI: make meta line a little bit darker for better visibility ... (check-in: 09837eae5e user: stern tags: trunk) | |
2021-01-29
| ||
18:44 | Typo ... (check-in: 84effdca96 user: stern tags: trunk) | |
18:16 | Version 0.0.9 ... (check-in: 5d25b46c82 user: stern tags: trunk, release, version-0.0.9) | |
17:34 | Prepare for release. Fix indexer bug. Add index.Store.Write. ... (check-in: 2b8648602f user: stern tags: trunk) | |
Deleted .deepsource.toml.
| - - - - - - - - |
|
Changes to Makefile.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | - + + - + + + + + + + + + + + - + + + + - - + + + + + - + - + + + + + - + |
|
Changes to VERSION.
| 1 | - + |
|
Changes to ast/ast.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
78 79 80 81 82 83 84 | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | - - - - - + + + + + - - - + + | } // RefState indicates the state of the reference. type RefState int // Constants for RefState const ( |
Changes to ast/attr.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
52 53 54 55 56 57 58 | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | - + | for k, v := range a.Attrs { attrs[k] = v } return &Attributes{attrs} } // Set changes the attribute that a given key has now a given value. |
︙ |
Changes to ast/ref.go.
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 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 | - + - + - - - - - - - - - - + + + + - + - - + - - - + - + - + - + - + - - | //----------------------------------------------------------------------------- |
Changes to ast/ref_test.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
51 52 53 54 55 56 57 | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | - | {"http://zettelstore.de/z/ast", false, true, false}, {"12345678901234", true, false, false}, {"12345678901234#local", true, false, false}, {"http://12345678901234", false, true, false}, {"http://zettelstore.de/z/12345678901234", false, true, false}, {"http://zettelstore.de/12345678901234", false, true, false}, {"/12345678901234", false, false, true}, |
︙ |
Changes to auth/cred/cred.go.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | - + - + - + - + | //----------------------------------------------------------------------------- |
Changes to auth/policy/anon.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
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 | + + + + - + - + - + - + - + | type anonPolicy struct { simpleMode bool expertMode func() bool getVisibility func(*meta.Meta) meta.Visibility pre Policy } func (ap *anonPolicy) CanReload(user *meta.Meta) bool { return ap.pre.CanReload(user) } |
Changes to auth/policy/default.go.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | - + + + + + - - - + + + + + + + + + + - - - - + + + + + + + + + | //----------------------------------------------------------------------------- |
︙ |
Changes to auth/policy/owner.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
20 21 22 23 24 25 26 | 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 | + + + + + + + + - + - + - + - + | type ownerPolicy struct { expertMode func() bool isOwner func(id.Zid) bool getVisibility func(*meta.Meta) meta.Visibility pre Policy } func (o *ownerPolicy) CanReload(user *meta.Meta) bool { // No need to call o.pre.CanReload(user), because it will always return true. // Both the default and the readonly policy allow to reload a place. // Only the owner is allowed to reload a place return o.userIsOwner(user) } |
︙ | |||
71 72 73 74 75 76 77 | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | - + | var noChangeUser = []string{ meta.KeyID, meta.KeyRole, meta.KeyUserID, meta.KeyUserRole, } |
︙ | |||
101 102 103 104 105 106 107 | 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 | - + - + | } if runtime.GetUserRole(user) == meta.UserRoleReader { return false } return o.userCanCreate(user, newMeta) } |
︙ |
Changes to auth/policy/place.go.
︙ | |||
53 54 55 56 57 58 59 | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | + - + | return pp.place.Location() } func (pp *polPlace) CanCreateZettel(ctx context.Context) bool { return pp.place.CanCreateZettel(ctx) } func (pp *polPlace) CreateZettel( |
︙ | |||
85 86 87 88 89 90 91 | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | - + | user := session.GetUser(ctx) if pp.policy.CanRead(user, m) { return m, nil } return nil, place.NewErrNotAllowed("GetMeta", user, zid) } |
︙ | |||
160 161 162 163 164 165 166 167 168 169 | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | + + + + + + + | user := session.GetUser(ctx) if pp.policy.CanDelete(user, meta) { return pp.place.DeleteZettel(ctx, zid) } return place.NewErrNotAllowed("Delete", user, zid) } func (pp *polPlace) Reload(ctx context.Context) error { user := session.GetUser(ctx) if pp.policy.CanReload(user) { return pp.place.Reload(ctx) } return place.NewErrNotAllowed("Reload", user, id.Invalid) } func (pp *polPlace) ReadStats(st *place.Stats) { pp.place.ReadStats(st) } |
Changes to auth/policy/policy.go.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | - + + + + - + - + - + - + - + | //----------------------------------------------------------------------------- |
︙ | |||
67 68 69 70 71 72 73 | 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 | + + + + - + - + - + - + - + | return &prePolicy{pol} } type prePolicy struct { post Policy } func (p *prePolicy) CanReload(user *meta.Meta) bool { return p.post.CanReload(user) } |
Changes to auth/policy/policy_test.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | + | } else { expertFunc = noExpertMode } pol := newPolicy(ts.simple, authFunc, ts.readonly, expertFunc, isOwner, getVisibility) name := fmt.Sprintf("simple=%v/readonly=%v/withauth=%v/expert=%v", ts.simple, ts.readonly, ts.withAuth, ts.expert) t.Run(name, func(tt *testing.T) { testReload(tt, pol, ts.simple, ts.withAuth, ts.readonly, ts.expert) testCreate(tt, pol, ts.simple, ts.withAuth, ts.readonly, ts.expert) testRead(tt, pol, ts.simple, ts.withAuth, ts.readonly, ts.expert) testWrite(tt, pol, ts.simple, ts.withAuth, ts.readonly, ts.expert) testRename(tt, pol, ts.simple, ts.withAuth, ts.readonly, ts.expert) testDelete(tt, pol, ts.simple, ts.withAuth, ts.readonly, ts.expert) }) } |
︙ | |||
86 87 88 89 90 91 92 | 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 | + + + + + + + + + + + + + + + + + + + + + - + | case meta.ValueVisibilitySimple: return meta.VisibilitySimple } } return meta.VisibilityLogin } func testReload(t *testing.T, pol Policy, simple bool, withAuth bool, readonly bool, isExpert bool) { t.Helper() testCases := []struct { user *meta.Meta exp bool }{ {newAnon(), !withAuth}, {newReader(), !withAuth}, {newWriter(), !withAuth}, {newOwner(), true}, } for _, tc := range testCases { t.Run("Reload", func(tt *testing.T) { got := pol.CanReload(tc.user) if tc.exp != got { tt.Errorf("exp=%v, but got=%v", tc.exp, got) } }) } } |
︙ | |||
129 130 131 132 133 134 135 | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | - + | if tc.exp != got { tt.Errorf("exp=%v, but got=%v", tc.exp, got) } }) } } |
︙ | |||
214 215 216 217 218 219 220 | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | - + | if tc.exp != got { tt.Errorf("exp=%v, but got=%v", tc.exp, got) } }) } } |
︙ | |||
355 356 357 358 359 360 361 | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | - + | if tc.exp != got { tt.Errorf("exp=%v, but got=%v", tc.exp, got) } }) } } |
︙ | |||
440 441 442 443 444 445 446 | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | - + | if tc.exp != got { tt.Errorf("exp=%v, but got=%v", tc.exp, got) } }) } } |
︙ |
Changes to auth/policy/readonly.go.
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 31 32 33 34 35 36 37 38 39 40 | - + + + + + - - - - - + + + + + + + + + + + + + + + + + + + | //----------------------------------------------------------------------------- |
Changes to auth/token/token.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
48 49 50 51 52 53 54 | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | - + | // GetToken returns a token to be used for authentification. func GetToken(ident *meta.Meta, d time.Duration, kind Kind) ([]byte, error) { if role, ok := ident.Get(meta.KeyRole); !ok || role != meta.ValueRoleUser { return nil, ErrNoUser } subject, ok := ident.Get(meta.KeyUserID) |
︙ | |||
100 101 102 103 104 105 106 | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | - + | } now := time.Now().Round(time.Second) expires := claims.Expires.Time() if expires.Before(now) { return Data{}, ErrTokenExpired } ident := claims.Subject |
︙ |
Changes to cmd/cmd_run.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
79 80 81 82 83 84 85 | 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 | - + + - + + + + - - - - - - - - - - - + - - + - - - + + + - - + + + + + + + + + + + - + + | ucAuthenticate := usecase.NewAuthenticate(up) ucGetMeta := usecase.NewGetMeta(pp) ucGetZettel := usecase.NewGetZettel(pp) ucParseZettel := usecase.NewParseZettel(ucGetZettel) ucListMeta := usecase.NewListMeta(pp) ucListRoles := usecase.NewListRole(pp) ucListTags := usecase.NewListTags(pp) |
Changes to cmd/cmd_run_simple.go.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | - + + - + + + + + + + + + + + + + | //----------------------------------------------------------------------------- |
︙ | |||
45 46 47 48 49 50 51 | 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 | - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | return 0, nil } // runSimple is called, when the user just starts the software via a double click // or via a simple call ``./zettelstore`` on the command line. func runSimple() { dir := "./zettel" |
Changes to cmd/main.go.
︙ | |||
120 121 122 123 124 125 126 | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | - + | case "v": cfg.Set(startup.KeyVerbose, flg.Value.String()) } }) return cfg } |
︙ |
Changes to cmd/zettelstore/main.go.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 | - + - + | package main import ( "zettelstore.de/z/cmd" ) // Version variable. Will be filled by build process. |
Changes to collect/collect.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ |
Changes to collect/collect_test.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ |
Deleted collect/order.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to collect/split.go.
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 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 | - + + - + + - + + + - + + + + + + + + - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - | //----------------------------------------------------------------------------- |
Changes to config/runtime/runtime.go.
︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | + + | // under this license. //----------------------------------------------------------------------------- // Package runtime provides functions to retrieve runtime configuration data. package runtime import ( "strconv" "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" "zettelstore.de/z/place" "zettelstore.de/z/place/stock" ) // --- Configuration zettel -------------------------------------------------- |
︙ | |||
128 129 130 131 132 133 134 | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | - - + + - + - + | if name, ok := config.Get(meta.KeySiteName); ok { return name } } return "Zettelstore" } |
︙ | |||
175 176 177 178 179 180 181 | 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 | - + - - + + + + | // GetMarkerExternal returns the current value of the "marker-external" key. func GetMarkerExternal() string { if config := getConfigurationMeta(); config != nil { if html, ok := config.Get(meta.KeyMarkerExternal); ok { return html } } |
Changes to config/startup/startup.go.
︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | + | h := fnv.New128() if secret, ok := cfg.Get("secret"); ok { io.WriteString(h, secret) } io.WriteString(h, version.Prog) io.WriteString(h, version.Build) io.WriteString(h, version.Hostname) io.WriteString(h, version.GoVersion) io.WriteString(h, version.Os) io.WriteString(h, version.Arch) return h.Sum(nil) } func getDuration( cfg *meta.Meta, key string, defDur, minDur, maxDur time.Duration) time.Duration { |
︙ |
Changes to docs/manual/00000000000100.zettel.
1 2 3 4 5 6 7 8 9 10 11 | 1 2 3 4 5 6 7 8 9 10 11 12 13 | + + | id: 00000000000100 title: Zettelstore Runtime Configuration role: configuration syntax: none default-copyright: (c) 2020-2021 by Detlef Stern <ds@zettelstore.de> default-license: EUPL-1.2-or-later default-visibility: public footer-html: <hr><p><a href="/home/doc/trunk/www/impri.wiki">Imprint / Privacy</a></p> modified: 20210111182407 site-name: Zettelstore Manual start: 00001000000000 visibility: owner |
Added docs/manual/00001000000000.zettel.
|
Changes to docs/manual/00001001000000.zettel.
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 | + | id: 00001001000000 title: Introduction to the Zettelstore role: manual tags: #introduction #manual #zettelstore syntax: zmk modified: 20210126170856 [[Personal knowledge management|https://en.wikipedia.org/wiki/Personal_knowledge_management]] is about collecting, classifying, storing, searching, retrieving, assessing, evaluating, and sharing knowledge as a daily activity. Personal knowledge management is done by most people, not necessarily as part of their main business. It is essential for knowledge workers, like students, researchers, |
︙ |
Changes to docs/manual/00001002000000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001003000000.zettel.
| 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 | - + - + - + |
|
︙ |
Changes to docs/manual/00001004000000.zettel.
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 | + | id: 00001004000000 title: Configuration of Zettelstore role: manual tags: #configuration #manual #zettelstore syntax: zmk modified: 20210125195740 There are two levels to change the behavior and/or the appearance of Zettelstore. The first level is the configuration that is needed to start the services provided by Zettelstore. For example, this includes the URI under which your Zettelstore is accessible. * [[Zettelstore start-up configuration|00001004010000]] The second level is configuring the running Zettelstore. |
︙ |
Changes to docs/manual/00001004010000.zettel.
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 | + | id: 00001004010000 title: Zettelstore start-up configuration role: manual tags: #configuration #manual #zettelstore syntax: zmk modified: 20201226183537 The configuration file, as specified by the ''-c CONFIGFILE'' [[command line option|00001004051000]], allows you to specify some start-up options. These options cannot be stored in a [[configuration zettel|00001004020000]] because either they are needed before Zettelstore can start or because of security reasons. For example, Zettelstore need to know in advance, on which network address is must listen or where zettel are placed. An attacker that is able to change the owner can do anything. Therefore only the owner of the computer on which Zettelstore runs can change this information. |
︙ | |||
37 38 39 40 41 42 43 | 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 | - + - + | If ''true'', a persistent cookie is used. Its lifetime exceeds the lifetime of the authentication token (see option ''token-lifetime-html'') by 30 seconds. Default: ''false'' ; [!place-X-uri]''place-//X//-uri'', where //X// is a number greater or equal to one : Specifies a [[place|00001004011200]] where zettel are stored. |
Changes to docs/manual/00001004011200.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001004011400.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001004020000.zettel.
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 | + | id: 00001004020000 title: Configure the running Zettelstore role: manual tags: #configuration #manual #zettelstore syntax: zmk modified: 20201231131204 You can configure a running Zettelstore by modifying the special zettel with the ID [[00000000000100]]. This zettel is called ""configuration zettel"". The following metadata keys change the appearance / behavior of Zettelstore: ; [!default-copyright]''default-copyright'' : Copyright value to be used when rendering content. |
︙ | |||
44 45 46 47 48 49 50 | 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 | - - - - + + + + | This affects most computed zettel. Default: False. ; [!footer-html]''footer-html'' : Contains some HTML code that will be included into the footer of each Zettelstore web page. It only affects the [[web user interface|00001014000000]]. Zettel content, delivered via the [[API|00001012000000]] as JSON, etc. is not affected. Default: (the empty string). |
︙ |
Changes to docs/manual/00001004050000.zettel.
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 | + | id: 00001004050000 title: Command line parameters role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115555 Zettelstore is not just a web service that provides services of a zettelkasten. It allows to some tasks to be executed at the command line. Typically, the task (""sub-command"") will be given at the command line as the first parameter. If no parameter is given, the Zettelstore is called as ``` |
︙ |
Changes to docs/manual/00001004050200.zettel.
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 | + | id: 00001004050200 title: The ''help'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115646 precursor: 00001004050000 Lists all implemented sub-commands. Example: ``` # zettelstore help |
︙ |
Changes to docs/manual/00001004050400.zettel.
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 | + | id: 00001004050400 title: The ''version'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115659 precursor: 00001004050000 Emits some information about the Zettelstore's version. This allows you to check, whether your installed Zettelstore is The name of the software (""Zettelstore"") and the build version information is given, as well as the compiler version, the name of the computer running the Zettelstore, and an indication about the operating system and the processor architecture of that computer. |
︙ |
Changes to docs/manual/00001004050600.zettel.
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 | + | id: 00001004050600 title: The ''config'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115712 precursor: 00001004050000 Shows the Zettelstore configuration, for debugging purposes. Currently, only the [[start-up configuration|00001004010000]] is shown. This sub-command uses the same command line parameters as [[``zettelstore run``|00001004051000]]. |
︙ |
Changes to docs/manual/00001004051000.zettel.
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 | + | id: 00001004051000 title: The ''run'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115719 precursor: 00001004050000 === ``zettelstore run`` This starts the web service. ``` zettelstore run [-c CONFIGFILE] [-d DIR] [-p PORT] [-r] [-v] |
︙ | |||
37 38 39 40 41 42 43 | 38 39 40 41 42 43 44 45 46 47 | - + | ; ''-r'' : Puts the Zettelstore in read-only mode. No changes are possible via the web interface / via the API. This allows to publish your content without any risks of unauthorized changes. ; ''-v'' : Be more verbose in writing logs. |
Changes to docs/manual/00001004051100.zettel.
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 | + | id: 00001004051100 title: The ''run-simple'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115448 precursor: 00001004050000 === ``zettelstore run-simple`` This sub-command is implicitly called, when an user starts Zettelstore by double-clicking on its GUI icon. It is s simplified variant of the [[''run'' sub-command|00001004051000]]. It allows only to specify a zettel directory. |
︙ |
Changes to docs/manual/00001004051200.zettel.
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 | + | id: 00001004051200 title: The ''file'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115726 precursor: 00001004050000 Reads zettel data from a file (or from standard input / stdin) and renders it to standard output / stdout. This allows Zettelstore to render files manually. ``` zettelstore file [-t FORMAT] [file-1 [file-2]] ``` |
︙ |
Changes to docs/manual/00001004051400.zettel.
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 | + | id: 00001004051400 title: The ''password'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk modified: 20210104115737 precursor: 00001004050000 This sub-command is used to create a hashed password for to be authenticated users. It reads a password from standard input (two times, both must be equal) and writes the hashed password to standard output. The general usage is: |
︙ |
Changes to docs/manual/00001005000000.zettel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 | + - + - + | id: 00001005000000 title: Structure of Zettelstore role: manual tags: #design #manual #zettelstore syntax: zmk modified: 20210125195908 Zettelstore is a software that manages your zettel. Since every zettel must be readable without any special tool, most zettel has to be stored as ordinary files within specific directories. Typically, file names and file content must comply to specific rules so that Zettelstore can manage them. If you add, delete, or change zettel files with other tools, e.g. a text editor, Zettelstore will monitor these actions. Zettelstore provides additional services to the user. Via a builtin web interface you can work with zettel in various ways. For example, you are able to list zettel, to create new zettel, to edit them, or to delete them. You can view zettel details and relations between zettel. In addition, Zettelstore provides an ""application programming interface"" (API) that allows other software to communicate with the Zettelstore. Zettelstore becomes extensible by external software. For example, a more sophisticated web interface could be build, or an application for your mobile device that allows you to send content to your Zettelstore as new zettel. === Where zettel are stored Your zettel are stored as files in a specific directory. If you have not explicitly specified the directory, a default directory will be used. |
︙ | |||
48 49 50 51 52 53 54 | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | - + | It maintains this relationship as long as theses files exists. In case of some textual zettel content you do not want to store the metadata and the zettel content in two different files. Here the ''.zettel'' extension will signal that the metadata and the zettel content will be placed in the same file, separated by an empty line or a line with three dashes (""''-\-\-''"", also known as ""YAML separator""). === Predefined zettel |
︙ |
Changes to docs/manual/00001005090000.zettel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 | + - - + + - - - + + - | id: 00001005090000 title: List of predefined zettel role: manual tags: #manual #reference #zettelstore syntax: zmk modified: 20210126114739 The following table lists all predefined zettel with their purpose. |= Identifier :|= Title | Purpose | [[00000000000001]] | Zettelstore Version | Contains the version string of the running Zettelstore | [[00000000000002]] | Zettelstore Host | Contains the name of the computer running the Zettelstore | [[00000000000003]] | Zettelstore Operating System | Contains the operating system and CPU architecture of the computer running the Zettelstore | [[00000000000006]] | Zettelstore Environment Values | Contains environmental data of Zettelstore executable | [[00000000000008]] | Zettelstore Runtime Values | Contains values that reflect the inner working; see [[here|https://golang.org/pkg/runtime/]] for a technical description of these values | [[00000000000018]] | Zettelstore Indexer | Provides some statistics about the index process | [[00000000000020]] | Zettelstore Place Manager | Contains some statistics about zettel places | [[00000000000090]] | Zettelstore Supported Metadata Keys | Contains all supported metadata keys, their [[types|00001006030000]], and more |
Changes to docs/manual/00001006000000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001006010000.zettel.
| 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 | - - + - - + + - + |
|
︙ |
Changes to docs/manual/00001006020000.zettel.
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 | + | id: 00001006020000 title: Supported Metadata Keys role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk modified: 20210123223645 Although you are free to define your own metadata, by using any key (according to the [[syntax|00001006010000]]), some keys have a special meaning that is enforced by Zettelstore. See the [[computed list of supported metadata keys|00000000000090]] for details. Most keys conform to a [[type|00001006030000]]. ; [!back]''back'' |
︙ | |||
71 72 73 74 75 76 77 | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | - + | If not given, the value ''default-role'' from the [[configuration zettel|00001004020000#default-role]] will be used. ; [!syntax]''syntax'' : Specifies the syntax that should be used for interpreting the zettel. The zettel about [[other markup languages|00001008000000]] defines supported values. If not given, the value ''default-syntax'' from the [[configuration zettel|00001004020000#default-syntax]] will be used. ; [!tags]''tags'' : Contains a space separated list of tags to describe the zettel further. |
︙ | |||
96 97 98 99 100 101 102 | 97 98 99 100 101 102 103 104 105 106 107 108 109 | + + + + + + | See [[User roles|00001010070300]] for more details. ; [!visibility]''visibility'' : When you work with authentication, you can give every zettel a value to decide, who can see the zettel. Its default value can be set with [[''default-visibility''|00001004020000#default-visibility]] of the configuration zettel. See [[visibility rules for zettel|00001010070200]] for more details. --- Not yet supported, but planned: ; [!folge]''folge'' : The IDs of zettel that acts as a [[Folgezettel|https://zettelkasten.de/posts/tags/folgezettel/]]. |
Changes to docs/manual/00001006020100.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | - - + - + + + + - + |
|
︙ |
Changes to docs/manual/00001006020400.zettel.
| 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 | - - + - - + - - + - - + - - + - - + - - + - - + - + - - - + + - - + |
|
Changes to docs/manual/00001006030000.zettel.
1 2 3 4 5 6 7 8 9 | 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: 00001006030000 title: Supported Key Types role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk modified: 20210108184053 Most [[supported metadata keys|00001006020000]] conform to a type. Every metadata key should conform to a type. Every key type is specified by a letter. |
Deleted docs/manual/00001006030500.zettel.
| - - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006031000.zettel.
| - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006031500.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006032000.zettel.
| - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006032500.zettel.
| - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006033000.zettel.
| - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006033500.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006034000.zettel.
| - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006034500.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006035000.zettel.
| - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006035500.zettel.
| - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006036000.zettel.
| - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001006036500.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to docs/manual/00001006050000.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | - - + - - + - - + - - + - + - |
|
Changes to docs/manual/00001007000000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001007010000.zettel.
| 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 | - - - - + + + - + - - + + - + - + - + - - - + + + - + - + |
|
Changes to docs/manual/00001007020000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001007030000.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | - - + |
|
︙ | |||
23 24 25 26 27 28 29 | 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 | - - + + - + - + - + | * [[Headings|00001007030300]] allow to structure the content of a zettel. * The [[horizontal rule|00001007030400]] signals a thematic break === Line-range blocks This kind of blocks encompass at least two lines. To be useful, they encompass more lines. |
Changes to docs/manual/00001007030100.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - - + - + |
|
︙ |
Changes to docs/manual/00001007030200.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - - + - |
|
︙ |
Changes to docs/manual/00001007030300.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - - + |
|
︙ |
Changes to docs/manual/00001007030400.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001007030500.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - - + - + - + |
|
︙ |
Changes to docs/manual/00001007030600.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - - - + + - + |
|
︙ |
Changes to docs/manual/00001007030700.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - - - + + - + |
|
︙ |
Changes to docs/manual/00001007030800.zettel.
| 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 | - - - + + - + |
|
︙ |
Changes to docs/manual/00001007030900.zettel.
| 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 | - - - + + - + |
|
︙ |
Changes to docs/manual/00001007031000.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - - - + + |
|
︙ |
Changes to docs/manual/00001007040000.zettel.
| 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 | - - + - - + + - + - + |
|
︙ |
Changes to docs/manual/00001007040100.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - - + - + |
|
︙ |
Changes to docs/manual/00001007040200.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001007040300.zettel.
| 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 | - - + - + - - + |
|
︙ | |||
61 62 63 64 65 66 67 | 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 | - + - + - + | %%Example: %%``{{External link|00000000030001}}{title=External width=30}`` is rendered as ::{{External link|00000000030001}}{title=External width=30}::{=example}. === Footnotes |
Changes to docs/manual/00001007050000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001007050100.zettel.
| 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 | - - + |
|
Changes to docs/manual/00001007050200.zettel.
| 1 2 3 4 5 6 | - |
|
Changes to docs/manual/00001007060000.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | - - + |
|
︙ |
Changes to docs/manual/00001008000000.zettel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 | + - + | id: 00001008000000 title: Other Markup Languages role: manual tags: #manual #zettelstore syntax: zmk modified: 20210111182215 [[Zettelmarkup|00001007000000]] is not the only markup language you can use to define your content. Zettelstore is quite agnostic with respect to markup languages. Of course, Zettelmarkup plays an important role. However, with the exception of zettel titles, you can use any (markup) language that is supported: * Markdown * Images: GIF, PNG, JPEG, SVG * CSS * HTML template data * Plain text, not further interpreted The [[metadata key|00001006020000#syntax]] ""''syntax''"" specifies which language should be used. |
︙ |
Changes to docs/manual/00001008010000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001010000000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001010040100.zettel.
| 1 2 3 4 5 6 7 8 | - - + |
|
Changes to docs/manual/00001010040200.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001010040400.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001010040700.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - - + - + - + - + |
|
Changes to docs/manual/00001010070200.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 | - + |
|
︙ | |||
20 21 22 23 24 25 26 | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - + - + | This is for zettel with sensitive content, e.g. the [[configuration zettel|00001004020000]] or the various zettel that contains the templates for rendering zettel in HTML. ; [!expert]""expert"" : Only the owner of the Zettelstore can access the zettel, if runtime configuration [[''expert-mode''|00001004020000#expert-mode]] is set to a boolean true value. This is for zettel with sensitive content that might irritate the owner. Computed zettel with internal runtime information are examples for such a zettel. ; [!simple-expert]""simple-expert"" |
Changes to docs/manual/00001010070300.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001010070400.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001010070600.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ | |||
43 44 45 46 47 48 49 | 42 43 44 45 46 47 48 49 50 51 52 | + + + + | * Rename a zettel ** Reject the access. Only the owner of the Zettelstore is currently allowed to give a new identifier for a zettel. * Delete a zettel ** Reject the access. Only the owner of the Zettelstore is allowed to delete a zettel. This may change in the future. * Reload internal values ** Reject the access. Only the owner of the Zettelstore is allowed to perform a reload operation. This may change in the future. |
Changes to docs/manual/00001010090100.zettel.
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 | + | id: 00001010090100 title: External server to encrypt message transport role: manual tags: #configuration #encryption #manual #security #zettelstore syntax: zmk modified: 20210125195546 Since Zettelstore does not encrypt the messages it exchanges with its clients, you may need some additional software to enable encryption. === Public-key encryption To enable encryption, you probably use some kind of encryption keys. In most cases, you need to deploy a ""public-key encryption"" process, where your side publish a public encryption key that only works with a corresponding private decryption key. Technically, this is not trivial. |
︙ | |||
62 63 64 65 66 67 68 | 63 64 65 66 67 68 69 70 71 | - + | reverse_proxy localhost:23123 } } ``` This will forwards requests with the prefix ""/manual"" to the running Zettelstore. All other requests will be handled by Caddy itself. |
Changes to docs/manual/00001012000000.zettel.
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 | + | id: 00001012000000 title: API role: manual tags: #api #manual #zettelstore syntax: zmk modified: 20210112113014 The API (short for ""**A**pplication **P**rogramming **I**nterface"") is the primary way to communicate with a running Zettelstore. Most integration with other systems and services is done through the API. The [[web user interface|00001014000000]] is just an alternative, secondary way of interacting with a Zettelstore. === Background The API is HTTP-based and uses JSON as its main encoding format for exchanging messages between a Zettelstore and its client software. |
︙ | |||
28 29 30 31 32 33 34 | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | - - + + - - | === Zettel lists * [[List metadata of all zettel|00001012051200]] * [[List all zettel, but in different encoding formats|00001012051400]] * [[List all zettel, but include different parts of a zettel|00001012051600]] * [[Shape the list of zettel metadata with filter options|00001012051800]] * [[Sort the list of zettel metadata|00001012052000]] |
Changes to docs/manual/00001012050200.zettel.
1 2 3 4 5 6 7 8 9 10 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | + - + | id: 00001012050200 title: API: Authenticate a client role: manual tags: #api #manual #zettelstore syntax: zmk modified: 20210111190943 Authentication for future API calls is done by sending a [[user identification|00001010040200]] and a password to the Zettelstore to obtain an [[access token|00001010040700]]. This token has to be used for other API calls. It is valid for a relatively short amount of time, as configured with the key ''token-timeout-api'' of the [[start-up configuration|00001004010000]] (typically 10 minutes). |
︙ |
Changes to docs/manual/00001012050400.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | - - + - + |
|
︙ |
Changes to docs/manual/00001012050600.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012051200.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | - - + - + |
|
︙ |
Changes to docs/manual/00001012051400.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012051600.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012051800.zettel.
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 | + - + | id: 00001012051800 title: API: Shape the list of zettel metadata with filter options role: manual tags: #api #manual #zettelstore syntax: zmk modified: 20210112114019 In most cases, it is not essential to list //all// zettel. Typically, you are interested only in a subset of the zettel maintained by your Zettelstore. This is done by adding some query parameters to the general ''GET /z'' request. === Filter |
︙ | |||
37 38 39 40 41 42 43 | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | - + | === Limit and offset By using the query parameter ""''_limit''"", which must have an integer value, you specifying an upper limit of list elements: ```sh # curl 'http://192.168.17.7:23121/z?title=API&_part=id&_sort=id&_limit=2' {"list":[{"id":"00001012000000","url":"/z/00001012000000"},{"id":"00001012050200","url":"/z/00001012050200"}]} ``` |
Changes to docs/manual/00001012052000.zettel.
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 | + | id: 00001012052000 title: API: Sort the list of zettel metadata role: manual tags: #api #manual #zettelstore syntax: zmk modified: 20210112113839 If not specified, the list of zettel is sorted descending by the value of the zettel identifier. The highest zettel identifier, which is a number, comes first. You change that with the ""''_sort''"" query parameter. Alternatively, you can also use the ""''_order''"" query parameter. It is an alias. |
︙ |
Deleted docs/manual/00001012052200.zettel.
| - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001012052400.zettel.
| - - - - - - - - - - - - - - - - - - |
|
Changes to docs/manual/00001012053400.zettel.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | - - + - + |
|
︙ |
Changes to docs/manual/00001012053600.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Deleted docs/manual/00001012053800.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted docs/manual/00001012054000.zettel.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to docs/manual/00001012920000.zettel.
| 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 | - - + - + - - - - - + |
|
Changes to docs/manual/00001012920500.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920501.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ | |||
16 17 18 19 20 21 22 | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | - - - - + + + + | * ''"encoding"'' and ''"content"'': the actual content of the zettel. See below for details. ''"id"'' and ''"url"'' are always sent to the client. It depends on the value of the required [[zettel part|00001012920800]], whether ''"meta"'' or ''"content"'' or both are sent. For an example, take a look at the JSON encoding of this page, which is available via the ""Info"" sub-page of this zettel: |
︙ |
Changes to docs/manual/00001012920503.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920510.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920513.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920516.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920519.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920522.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012920800.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001012921000.zettel.
| 1 2 3 4 5 6 7 | - |
|
︙ |
Changes to docs/manual/00001014000000.zettel.
| 1 2 3 4 5 6 7 | - |
|
Deleted docs/manual/00010000000000.zettel.
| - - - - - - - - - - - - - - - - - - - - - |
|
Changes to domain/id/id.go.
︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 | + - + - - - - - + + - - - - - - - - - - + + + + + + + + - - - + + - - - + - - - - - + + - + | //----------------------------------------------------------------------------- // Package id provides domain specific types, constants, and functions about // zettel identifier. package id import ( "sort" "strconv" "time" ) // Zid is the internal identifier of a zettel. Typically, it is a // time stamp of the form "YYYYMMDDHHmmSS" converted to an unsigned integer. // A zettelstore implementation should try to set the last two digits to zero, // e.g. the seconds should be zero, type Zid uint64 |
︙ | |||
108 109 110 111 112 113 114 | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | + + + + + + + + + + + | } res, err := Parse(s) if err != nil { panic(err) } return res } // Sort a slice of Zids. func Sort(zids []Zid) { sort.Sort(zidSlice(zids)) } type zidSlice []Zid func (zs zidSlice) Len() int { return len(zs) } func (zs zidSlice) Less(i, j int) bool { return zs[i] < zs[j] } func (zs zidSlice) Swap(i, j int) { zs[i], zs[j] = zs[j], zs[i] } |
Changes to domain/id/id_test.go.
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 | - + + + + | //----------------------------------------------------------------------------- |
︙ |
Deleted domain/id/set.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted domain/id/slice.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted domain/id/slice_test.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to domain/meta/meta.go.
︙ | |||
72 73 74 75 76 77 78 | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | - - - - - - - - | func IsComputed(name string) bool { if kd, ok := registeredKeys[name]; ok { return kd.IsComputed() } return false } |
︙ | |||
126 127 128 129 130 131 132 | 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 | - + + + | KeyDefaultTitle = registerKey("default-title", TypeZettelmarkup, usageUser, "") KeyDefaultVisibility = registerKey("default-visibility", TypeWord, usageUser, "") KeyDuplicates = registerKey("duplicates", TypeBool, usageUser, "") KeyExpertMode = registerKey("expert-mode", TypeBool, usageUser, "") KeyFolge = registerKey("folge", TypeIDSet, usageProperty, "") KeyFooterHTML = registerKey("footer-html", TypeString, usageUser, "") KeyForward = registerKey("forward", TypeIDSet, usageProperty, "") |
︙ | |||
239 240 241 242 243 244 245 | 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 | - + - + | } value, ok := m.pairs[key] return value, ok } // GetDefault retrieves the string value of the given key. If no value was // stored, the given default value is returned. |
︙ |
Changes to domain/meta/parse.go.
︙ | |||
177 178 179 180 181 182 183 184 185 186 187 | 177 178 179 180 181 182 183 184 185 186 187 188 189 | + + | _, err := id.Parse(s) return err == nil }) case TypeTimestamp: if _, ok := TimeValue(v); ok { m.Set(key, v) } case TypeEmpty: fallthrough default: addData(m, key, v) } } |
Changes to domain/meta/type.go.
︙ | |||
8 9 10 11 12 13 14 | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - | // under this license. //----------------------------------------------------------------------------- // Package meta provides the domain specific type 'meta'. package meta import ( |
︙ | |||
76 77 78 79 80 81 82 | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | - - - - - - - - | for i, val := range values { values[i] = trimValue(val) } m.pairs[key] = strings.Join(values, " ") } } |
︙ | |||
139 140 141 142 143 144 145 | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | - - - - - - - - - - - - - - - - - - - - - - - | value, ok := m.Get(key) if !ok { return nil, false } return ListFromValue(value), true } |
Changes to encoder/encoder.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
31 32 33 34 35 36 37 | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | - - - - - + + + + + | WriteContent(io.Writer, *ast.ZettelNode) (int, error) WriteBlocks(io.Writer, ast.BlockSlice) (int, error) WriteInlines(io.Writer, ast.InlineSlice) (int, error) } // Some errors to signal when encoder methods are not implemented. var ( |
︙ |
Changes to encoder/htmlenc/block.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
19 20 21 22 23 24 25 | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | - + | "zettelstore.de/z/ast" ) // VisitPara emits HTML code for a paragraph: <p>...</p> func (v *visitor) VisitPara(pn *ast.ParaNode) { v.b.WriteString("<p>") v.acceptInlineSlice(pn.Inlines) |
︙ | |||
192 193 194 195 196 197 198 | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | - + - + | } else { v.b.WriteString("<p>") inPara = true } v.acceptInlineSlice(pn.Inlines) } else { if inPara { |
︙ | |||
333 334 335 336 337 338 339 | 333 334 335 336 337 338 339 | - - - - | v.b.WriteString("\" title=\"") v.writeQuotedEscaped(bn.Title) v.b.WriteString("\">\n") default: v.b.WriteStrings("<p class=\"error\">Unable to display BLOB with syntax '", bn.Syntax, "'.</p>\n") } } |
Changes to encoder/htmlenc/htmlenc.go.
︙ | |||
52 53 54 55 56 57 58 | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | + - + | switch opt.Key { case "newwindow": he.newWindow = opt.Value case "xhtml": he.xhtml = opt.Value } case *encoder.StringsOption: switch opt.Key { |
︙ |
Changes to encoder/htmlenc/inline.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | - + | func (v *visitor) VisitText(tn *ast.TextNode) { v.writeHTMLEscaped(tn.Text) } // VisitTag writes tag content. func (v *visitor) VisitTag(tn *ast.TagNode) { // TODO: erst mal als span. Link wäre gut, muss man vermutlich via Callback lösen. |
︙ | |||
64 65 66 67 68 69 70 | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | - + - + | return } } v.lang.push(ln.Attrs) defer v.lang.pop() switch ln.Ref.State { |
︙ |
Changes to encoder/htmlenc/visitor.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
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 | - - - - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + | var mapMetaKey = map[string]string{ meta.KeyCopyright: "copyright", meta.KeyLicense: "license", } func (v *visitor) acceptMeta(m *meta.Meta, withTitle bool) { for i, pair := range m.Pairs(true) { |
︙ |
Changes to encoder/jsonenc/djsonenc.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
320 321 322 323 324 325 326 | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | - - - - + + + + - - - - + + + | } else { v.writeNodeStart("Soft") } v.b.WriteByte('}') } var mapRefState = map[ast.RefState]string{ |
︙ | |||
578 579 580 581 582 583 584 | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | + - + + + + + + + + + - - - - - - - - - - - - - | first = false } else { v.b.WriteString(",\"") } v.b.Write(Escape(p.Key)) v.b.WriteString("\":") if m.Type(p.Key).IsSet { v.b.WriteByte('[') |
Changes to encoder/jsonenc/jsonenc.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
27 28 29 30 31 32 33 | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - + | }) } // jsonEncoder is just a stub. It is not implemented. The real implementation // is in file web/adapter/json.go type jsonEncoder struct{} |
︙ |
Changes to encoder/nativeenc/nativeenc.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
131 132 133 134 135 136 137 | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | - + - + | first = false } v.level-- v.b.WriteByte(']') } } |
︙ | |||
378 379 380 381 382 383 384 | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | - - - - + + + + - - - - + + + | v.b.WriteString("Break") } else { v.b.WriteString("Space") } } var mapRefState = map[ast.RefState]string{ |
︙ |
Changes to encoder/rawenc/rawenc.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | - + | encoder.Register("raw", encoder.Info{ Create: func() encoder.Encoder { return &rawEncoder{} }, }) } type rawEncoder struct{} |
︙ |
Changes to encoder/textenc/textenc.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | - + | encoder.Register("text", encoder.Info{ Create: func() encoder.Encoder { return &textEncoder{} }, }) } type textEncoder struct{} |
︙ |
Changes to encoder/zmkenc/zmkenc.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
25 26 27 28 29 30 31 | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | - + | encoder.Register("zmk", encoder.Info{ Create: func() encoder.Encoder { return &zmkEncoder{} }, }) } type zmkEncoder struct{} |
︙ |
Changes to go.mod.
1 2 3 4 5 6 7 | 1 2 3 4 5 6 7 8 9 10 11 | - + | module zettelstore.de/z go 1.15 require ( github.com/fsnotify/fsnotify v1.4.9 github.com/pascaldekloe/jwt v1.10.0 |
Changes to go.sum.
1 2 3 4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 | - - + + | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/pascaldekloe/jwt v1.10.0 h1:ktcIUV4TPvh404R5dIBEnPCsSwj0sqi3/0+XafE5gJs= github.com/pascaldekloe/jwt v1.10.0/go.mod h1:TKhllgThT7TOP5rGr2zMLKEDZRAgJfBbtKyVeRsNB9A= |
︙ |
Changes to index/index.go.
︙ | |||
45 46 47 48 49 50 51 | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | - + | _, ok := ctx.Value(ctxNoEnrichKey).(*ctxNoEnrichType) return ok } // Port contains all the used functions to access zettel to be indexed. type Port interface { RegisterObserver(func(place.ChangeInfo)) |
︙ | |||
87 88 89 90 91 92 93 | 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 | - - + - - + - + | // Store all relevant zettel data. There may be multiple implementations, i.e. // memory-based, file-based, based on SQLite, ... type Store interface { Enricher // UpdateReferences for a specific zettel. |
Changes to index/indexer/anteroom.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 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 | - - - - - - - - - - + - - + + - + - - - - - + + + + + - - - - - - - + - + - - - - + + + + - - + + - + - + - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - - - - - - - - + + + + + + + - - - - - - - + + + + + - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + | import ( "sync" "zettelstore.de/z/domain/id" ) |
Changes to index/indexer/anteroom_test.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 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 | - - - - + + + + - - + + - - + + - + - - - + + + - + - - - + + + - - - - - + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - - + + + - - - - + + + + - - - + + + - + - - - + + + | "testing" "zettelstore.de/z/domain/id" ) func TestSimple(t *testing.T) { ar := newAnterooms(2) |
Changes to index/indexer/indexer.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 | - + - + | } func (idx *indexer) observer(ci place.ChangeInfo) { switch ci.Reason { case place.OnReload: idx.ar.Reset() case place.OnUpdate: |
︙ | |||
107 108 109 110 111 112 113 | 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 | - + - + + - - - - - + + + + + + + + + + - - - - - + + + + + + + + + - - + - - - - + - + - - - - - - - - - - + - - - + - + - - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + | st.DurLastIndex = idx.durLastIndex idx.mx.RUnlock() idx.store.ReadStats(&st.Store) } type indexerPort interface { getMetaPort |
︙ | |||
220 221 222 223 224 225 226 | 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 | - + - + - + + - + - + + - + - + - - - - - - - | } } } zn := parser.ParseZettel(zettel, "") refs := collect.References(zn) updateReferences(ctx, refs.Links, p, zi) updateReferences(ctx, refs.Images, p, zi) |
Changes to index/memstore/memstore.go.
︙ | |||
19 20 21 22 23 24 25 | 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 | - - + + - - - + + + - + - - + + - - + - - - + + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - + - + - - - - - + - - + - - - - + - - - + - - - + - - - - - - + + + + - - - - + + - - - - - - - - - - - + - - + - - + + + + + + - - + - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + - + - + - - + + - - - + - - - - - - - - - - + + + + + + + + + + - - - + - + - + - - - - + - - - - + - - - + | "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" "zettelstore.de/z/index" ) type metaRefs struct { |
Changes to index/memstore/refs.go.
︙ | |||
8 9 10 11 12 13 14 15 16 17 | 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 | + + + + + + + + + + + + + - + | // under this license. //----------------------------------------------------------------------------- // Package memstore stored the index in main memory. package memstore import ( "bytes" "zettelstore.de/z/domain/id" ) func refsToString(refs []id.Zid) string { var buf bytes.Buffer for i, dref := range refs { if i > 0 { buf.WriteByte(' ') } buf.Write(dref.Bytes()) } return buf.String() } |
︙ | |||
37 38 39 40 41 42 43 | 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 | - + - + - + - + | } if opos < len(refsO) { remRefs = append(remRefs, refsO[opos:]...) } return newRefs, remRefs } |
︙ | |||
78 79 80 81 82 83 84 | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | - - - - - - - + + + + + + + + + | } if rpos < len(refs) { result = append(result, refs[rpos:]...) } return result } |
Changes to index/memstore/refs_test.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 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 | + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + - - + + - - - - - - + + + + + + - + - + - + - - - - - - + + + + + + - + - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - - - + + + + + - + | import ( "testing" "zettelstore.de/z/domain/id" ) func numsToRefs(nums []uint) []id.Zid { if nums == nil { return nil } refs := make([]id.Zid, 0, len(nums)) for _, n := range nums { refs = append(refs, id.Zid(n)) } return refs } |
Changes to index/zettel.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 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 | - - - - + + + + - - - + + + - + - - + + - - + + - + - + - + + + + + + + + + + + + + | import ( "zettelstore.de/z/domain/id" ) // ZettelIndex contains all index data of a zettel. type ZettelIndex struct { |
Changes to input/input.go.
︙ | |||
85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | + | inp.Next() } inp.Ch = '\n' inp.Next() case '\n': inp.Next() } return } // SetPos allows to reset the read position. func (inp *Input) SetPos(pos int) { inp.readPos = pos inp.Next() } |
︙ |
Changes to parser/cleanup.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
112 113 114 115 116 117 118 | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | - + | if mn == nil { return } if !cv.doMark { cv.hasMark = true return } |
︙ |
Changes to parser/markdown/markdown.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
280 281 282 283 284 285 286 | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | - + | result = append(result, &ast.BreakNode{Hard: false}) } return result } // splitText transform the text into a sequence of TextNode and SpaceNode func splitText(text string) ast.InlineSlice { |
︙ | |||
315 316 317 318 319 320 321 | 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 | - + + + + + + + + + + + + + + - + - + + - + - - - - - - - - - - | panic(fmt.Sprintf("Unexpected state %v", state)) } return result } // cleanText removes backslashes from TextNodes and expands entities func cleanText(text string, cleanBS bool) string { |
︙ | |||
364 365 366 367 368 369 370 | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | - + + - + | Attrs: nil, //TODO Text: cleanCodeSpan(string(node.Text(p.source))), }, } } func cleanCodeSpan(text string) string { |
︙ |
Changes to parser/parser.go.
︙ | |||
79 80 81 82 83 84 85 | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | - + | return ParseInlines(input.NewInput(title), meta.ValueSyntaxZmk) } // ParseZettel parses the zettel based on the syntax. func ParseZettel(zettel domain.Zettel, syntax string) *ast.ZettelNode { m := zettel.Meta inhMeta := runtime.AddDefaultValues(zettel.Meta) |
︙ |
Changes to parser/plain/plain.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
55 56 57 58 59 60 61 | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | + - + | } } func readLines(inp *input.Input) (lines []string) { for { inp.EatEOL() posL := inp.Pos switch inp.Ch { |
︙ |
Changes to parser/zettelmark/block.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
367 368 369 370 371 372 373 | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | - + + + | if parentPos < 0 { return cp.lists[0], true } if prevItems := cp.lists[parentPos].Items; len(prevItems) > 0 { lastItem := len(prevItems) - 1 prevItems[lastItem] = append(prevItems[lastItem], cp.lists[childPos]) } else { |
︙ | |||
450 451 452 453 454 455 456 | 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 477 478 479 480 481 482 483 484 485 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 514 515 516 517 518 519 | - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + | inp.Next() if inp.Ch != ' ' { break } cnt++ } if cp.lists != nil { |
︙ |
Changes to parser/zettelmark/inline.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
59 60 61 62 63 64 65 | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | - + + | case '^': in, success = cp.parseFootnote() case '!': in, success = cp.parseMark() } case '{': inp.Next() |
︙ |
Changes to parser/zettelmark/node.go.
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 31 32 33 34 35 36 37 38 39 40 41 | - + - + + + + + + + | //----------------------------------------------------------------------------- |
Changes to parser/zettelmark/post-processor.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
37 38 39 40 41 42 43 | 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 | - + - + | // VisitPara post-processes a paragraph. func (pp *postProcessor) VisitPara(pn *ast.ParaNode) { if pn != nil { pn.Inlines = pp.processInlineSlice(pn.Inlines) } } |
︙ | |||
89 90 91 92 93 94 95 | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | - + + + | } if len(tn.Rows) > 0 && isHeaderRow(tn.Rows[0]) { tn.Header = tn.Rows[0] tn.Rows = tn.Rows[1:] for pos, cell := range tn.Header { if inlines := cell.Inlines; len(inlines) > 0 { if textNode, ok := inlines[0].(*ast.TextNode); ok { |
︙ | |||
435 436 437 438 439 440 441 | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | + - + | ins[toPos] = nil // Kill node to enable garbage collection } return toPos } func (pp *postProcessor) processInlineSliceInplace(ins ast.InlineSlice) { for _, in := range ins { switch n := in.(type) { |
Changes to parser/zettelmark/zettelmark.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
135 136 137 138 139 140 141 | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | - + | updateAttrs(attrs, key, inp.Src[posV:inp.Pos]) return true } inp.Next() } } |
︙ |
Changes to parser/zettelmark/zettelmark_test.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
874 875 876 877 878 879 880 | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 | - + | for _, k := range keys { tv.b.WriteByte(' ') tv.b.WriteString(k) v := a.Attrs[k] if len(v) > 0 { tv.b.WriteByte('=') |
Changes to place/constplace/constdata.go.
︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 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 | + - + - + + - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + + + - + + - + - + + - + - + - - + - - + - + - - + + - + + - + - + + - + - + - + | // under this license. //----------------------------------------------------------------------------- // Package constplace stores zettel inside the executable. package constplace import ( "zettelstore.de/z/domain" "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" ) const ( syntaxTemplate = "mustache" ) var constZettelMap = map[id.Zid]constZettel{ |
︙ | |||
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 | - + - - - - - - - - + - - - - - - - - - - - - - - - - - + | {{#Matrix}} <tr> {{#Elements}}{{#HasURL}}<td><a href="{{{URL}}}">{{Text}}</td>{{/HasURL}}{{^HasURL}}<th>{{Text}}</th>{{/HasURL}} {{/Elements}} </tr> {{/Matrix}} </table> |
︙ | |||
302 303 304 305 306 307 308 | 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 | - + + + - + | <div> <label for="syntax">Syntax</label> <input class="zs-input" type="text" id="syntax" name="syntax" placeholder="syntax.." value="{{MetaSyntax}}"> </div> <div> {{#IsTextContent}} <label for="content">Content</label> |
︙ | |||
338 339 340 341 342 343 344 | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | - + | {{#MetaPairs}} <dt>{{Key}}:</dt><dd>{{Value}}</dd> {{/MetaPairs}} </dl> </article>`, }, |
︙ | |||
362 363 364 365 366 367 368 | 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 | - + - - - + - - - + + - + - - - + - - - + + - + | <form method="POST"> <input class="zs-button" type="submit" value="Delete"> </form> </article> {{end}}`, }, |
︙ | |||
653 654 655 656 657 658 659 | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | - + - + | border: 1px solid hsl(210, 5%, 70%); border-radius: .25rem; padding: .1rem .2rem; font-size: 75%; } .zs-meta { font-size:.75rem; |
︙ | |||
682 683 684 685 686 687 688 | 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | - - + - - - - - - + + - - - - - + - - - + + + + - + + - + - + + - + - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } |
Changes to place/constplace/constplace.go.
︙ | |||
73 74 75 76 77 78 79 | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | - - + + | func (cp *constPlace) GetMeta(ctx context.Context, zid id.Zid) (*meta.Meta, error) { if z, ok := cp.zettel[zid]; ok { return makeMeta(zid, z.header), nil } return nil, place.ErrNotFound } |
︙ | |||
121 122 123 124 125 126 127 128 129 130 131 132 | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | + + | func (cp *constPlace) DeleteZettel(ctx context.Context, zid id.Zid) error { if _, ok := cp.zettel[zid]; ok { return place.ErrReadOnly } return place.ErrNotFound } func (cp *constPlace) Reload(ctx context.Context) error { return nil } func (cp *constPlace) ReadStats(st *place.Stats) { st.ReadOnly = true st.Zettel = len(cp.zettel) } |
Changes to place/dirplace/directory/service.go.
︙ | |||
48 49 50 51 52 53 54 | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | - + | func updateEntry(de *Entry, ev *fileEvent) { if ev.ext == "meta" { de.MetaSpec = MetaSpecFile de.MetaPath = ev.path return } |
︙ | |||
111 112 113 114 115 116 117 | 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 | + + + - + + + + + + - + + + - - - - - - - - - - - - - - - - - - | close(ready) ready = nil } srv.notifyChange(place.OnReload, id.Invalid) case fileStatusError: log.Println("DIRPLACE", "ERROR", ev.err) case fileStatusUpdate: if newMap != nil { dirMapUpdate(newMap, ev) } else { |
︙ |
Changes to place/dirplace/directory/watch.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
19 20 21 22 23 24 25 | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | - + | "time" "github.com/fsnotify/fsnotify" "zettelstore.de/z/domain/id" ) |
︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 | 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 | + + + + + + + + + - + | return res == sendReload } case _, ok := <-tick: return ok } } } pause := func() bool { for { select { case _, ok := <-tick: return ok } } } for { if !reloadFiles() { return } if watcher == nil { |
︙ | |||
219 220 221 222 223 224 225 | 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 | - + - - - - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + | func addEvent(events []*fileEvent, ev *fileEvent) []*fileEvent { switch ev.status { case fileStatusNone: return events case fileStatusReloadStart: events = events[0:0] case fileStatusUpdate, fileStatusDelete: |
︙ |
Changes to place/dirplace/dirplace.go.
︙ | |||
177 178 179 180 181 182 183 | 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 | - + - + - + - | if err != nil { return nil, err } dp.cleanupMeta(ctx, m) return m, nil } |
︙ | |||
310 311 312 313 314 315 316 | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | - + + + + | oldMeta.Zid = newZid newZettel := domain.Zettel{Meta: oldMeta, Content: domain.NewContent(oldContent)} if err := setZettel(dp, &newEntry, newZettel); err != nil { // "Rollback" rename. No error checking... dp.dirSrv.RenameEntry(&newEntry, &curEntry) return err } |
︙ | |||
334 335 336 337 338 339 340 341 342 343 344 345 346 347 | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | + + + + + + + + + + | if !entry.IsValid() { return nil } dp.dirSrv.DeleteEntry(zid) err := deleteZettel(dp, &entry, zid) return err } func (dp *dirPlace) Reload(ctx context.Context) error { // Brute force: stop everything, then start everything. // Could be done better in the future... err := dp.Stop(ctx) if err == nil { err = dp.Start(ctx) } return err } func (dp *dirPlace) ReadStats(st *place.Stats) { st.ReadOnly = dp.readonly st.Zettel = dp.dirSrv.NumEntries() } func (dp *dirPlace) cleanupMeta(ctx context.Context, m *meta.Meta) { |
︙ |
Changes to place/dirplace/service.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
33 34 35 36 37 38 39 | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | - - + + | } // COMMAND: getMeta ---------------------------------------- // // Retrieves the meta data from a zettel. func getMeta(dp *dirPlace, entry *directory.Entry, zid id.Zid) (*meta.Meta, error) { |
︙ | |||
96 97 98 99 100 101 102 | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | - - + - | var m *meta.Meta var content string var err error switch cmd.entry.MetaSpec { case directory.MetaSpecFile: m, err = parseMetaFile(cmd.entry.Zid, cmd.entry.MetaPath) |
︙ | |||
131 132 133 134 135 136 137 138 139 140 | 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 | + + + + + + + + - + + + + + + + + + + + + + + + + + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | entry *directory.Entry zettel domain.Zettel rc chan<- resSetZettel } type resSetZettel = error func (cmd *fileSetZettel) run() { var f *os.File var err error switch cmd.entry.MetaSpec { case directory.MetaSpecFile: f, err = openFileWrite(cmd.entry.MetaPath) if err == nil { err = writeFileZid(f, cmd.zettel.Meta.Zid) if err == nil { _, err = cmd.zettel.Meta.Write(f, true) if err1 := f.Close(); err == nil { |
︙ | |||
253 254 255 256 257 258 259 | 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 | + - + - + | } func cleanupMeta(m *meta.Meta, entry *directory.Entry) { if title, ok := m.Get(meta.KeyTitle); !ok || title == "" { m.Set(meta.KeyTitle, entry.Zid.String()) } switch entry.MetaSpec { |
︙ |
Changes to place/filter.go.
︙ | |||
29 30 31 32 33 34 35 | 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 | + - + - + + + + + + + + + + + + + + + + | // FilterFunc is a predicate to check if given meta must be selected. type FilterFunc func(*meta.Meta) bool func selectAll(m *meta.Meta) bool { return true } type matchFunc func(value string) bool func matchAlways(value string) bool { return true } |
︙ | |||
69 70 71 72 73 74 75 | 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 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - + - - - - - - - - - - - - - + + + + + + + + + + + + - - + - - - - + + + - - - - - - - - - - - - - + + + + + + + + + - - + - - - - - - - - - - - + + + + + + + + + + - - + - - - - - - - - - - - - - - + + + + + + + + + + + + + - | return addSelectFunc(filter, searchMeta) } return addSelectFunc(filter, func(meta *meta.Meta) bool { return searchAll(meta) || searchMeta(meta) }) } |
︙ | |||
267 268 269 270 271 272 273 274 275 276 277 278 279 280 | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | + + + + + + + + + | func sliceToLower(sl []string) []string { result := make([]string, 0, len(sl)) for _, s := range sl { result = append(result, strings.ToLower(s)) } return result } func isEmptySlice(sl []string) bool { for _, s := range sl { if len(s) > 0 { return false } } return true } func preprocessSet(set []string) [][]string { result := make([][]string, 0, len(set)) for _, elem := range set { splitElems := strings.Split(elem, ",") valueElems := make([]string, 0, len(splitElems)) for _, se := range splitElems { |
︙ |
Changes to place/manager/manager.go.
︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | + | return result } // Manager is a coordinating place. type Manager struct { mx sync.RWMutex started bool placeURIs []url.URL subplaces []place.Place filter index.MetaFilter observers []func(place.ChangeInfo) mxObserver sync.RWMutex done chan struct{} infos chan place.ChangeInfo } |
︙ | |||
188 189 190 191 192 193 194 | 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 | - + - - - - + - - - - - - - - - - + + + + + + + + + | func (mgr *Manager) Start(ctx context.Context) error { mgr.mx.Lock() if mgr.started { mgr.mx.Unlock() return place.ErrStarted } for i := len(mgr.subplaces) - 1; i >= 0; i-- { |
︙ | |||
283 284 285 286 287 288 289 | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | - + | return m, err } } return nil, place.ErrNotFound } // FetchZids returns the set of all zettel identifer managed by the place. |
︙ | |||
417 418 419 420 421 422 423 424 425 426 427 428 429 430 | 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 | + + + + + + + + + + + + + + + + + + | for _, p := range mgr.subplaces { if err := p.DeleteZettel(ctx, zid); err != place.ErrNotFound && err != place.ErrReadOnly { return err } } return place.ErrNotFound } // Reload clears all caches, reloads all internal data to reflect changes // that were possibly undetected. func (mgr *Manager) Reload(ctx context.Context) error { mgr.mx.RLock() defer mgr.mx.RUnlock() if !mgr.started { return place.ErrStopped } var err error for _, p := range mgr.subplaces { if err1 := p.Reload(ctx); err1 != nil && err == nil { err = err1 } } mgr.infos <- place.ChangeInfo{Reason: place.OnReload, Zid: id.Invalid} return err } // ReadStats populates st with place statistics func (mgr *Manager) ReadStats(st *place.Stats) { subStats := make([]place.Stats, len(mgr.subplaces)) for i, p := range mgr.subplaces { p.ReadStats(&subStats[i]) } |
︙ |
Changes to place/memplace/memplace.go.
︙ | |||
107 108 109 110 111 112 113 | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | - + - + | mp.mx.RUnlock() if !ok { return nil, place.ErrNotFound } return zettel.Meta.Clone(), nil } |
︙ | |||
194 195 196 197 198 199 200 201 202 203 204 205 206 207 | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | + + | return place.ErrNotFound } delete(mp.zettel, zid) mp.mx.Unlock() mp.notifyChanged(place.OnDelete, zid) return nil } func (mp *memPlace) Reload(ctx context.Context) error { return nil } func (mp *memPlace) ReadStats(st *place.Stats) { st.ReadOnly = false mp.mx.RLock() st.Zettel = len(mp.zettel) mp.mx.RUnlock() } |
Changes to place/place.go.
︙ | |||
37 38 39 40 41 42 43 | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | - + | // GetZettel retrieves a specific zettel. GetZettel(ctx context.Context, zid id.Zid) (domain.Zettel, error) // GetMeta retrieves just the meta data of a specific zettel. GetMeta(ctx context.Context, zid id.Zid) (*meta.Meta, error) // FetchZids returns the set of all zettel identifer managed by the place. |
︙ | |||
60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | + + + + | RenameZettel(ctx context.Context, curZid, newZid id.Zid) error // CanDeleteZettel returns true, if place could possibly delete the given zettel. CanDeleteZettel(ctx context.Context, zid id.Zid) bool // DeleteZettel removes the zettel from the place. DeleteZettel(ctx context.Context, zid id.Zid) error // Reload clears all caches, reloads all internal data to reflect changes // that were possibly undetected. Reload(ctx context.Context) error // ReadStats populates st with place statistics ReadStats(st *Stats) } // Stats records statistics about the place. type Stats struct { |
︙ | |||
134 135 136 137 138 139 140 | 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 | - + - + - + - + - + - + - + - + - + | } } func (err *ErrNotAllowed) Error() string { if err.User == nil { if err.Zid.IsValid() { return fmt.Sprintf( |
︙ |
Changes to place/progplace/progplace.go.
︙ | |||
118 119 120 121 122 123 124 | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | - - + + | return m, nil } } } return nil, place.ErrNotFound } |
︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | + + | func (pp *progPlace) DeleteZettel(ctx context.Context, zid id.Zid) error { if _, ok := pp.zettel[zid]; ok { return place.ErrReadOnly } return place.ErrNotFound } func (pp *progPlace) Reload(ctx context.Context) error { return nil } func (pp *progPlace) ReadStats(st *place.Stats) { st.ReadOnly = true st.Zettel = len(pp.zettel) } func updateMeta(m *meta.Meta) { |
︙ |
Changes to place/sorter.go.
︙ | |||
42 43 44 45 46 47 48 | 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 | - + - + - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - + - - - - - - - - - - - - - - + + + + + + + + + + + + + - | func(i, j int) bool { return metaList[i].Zid > metaList[j].Zid }) return metaList } if s.Order == "" { |
︙ |
Deleted strfun/strfun.go.
| - - - - - - - - - - - - - - - - - - - - - - - |
|
Deleted strfun/strfun_test.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to template/mustache.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
225 226 227 228 229 230 231 | 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 | - - - - - + + + - + | } type tagReadingResult struct { tag string standalone bool } |
︙ | |||
325 326 327 328 329 330 331 332 333 334 335 336 337 338 | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | + | section.nodes = append(section.nodes, &textNode{[]byte(padding)}) } tag := tagResult.tag switch tag[0] { case '!': //ignore comment break case '#', '^': name := strings.TrimSpace(tag[1:]) sn := §ionNode{name, tag[0] == '^', tmpl.curline, []node{}} err := tmpl.parseSection(sn) if err != nil { return err } |
︙ | |||
400 401 402 403 404 405 406 407 408 409 410 411 412 413 | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | + | tmpl.nodes = append(tmpl.nodes, &textNode{[]byte(padding)}) } tag := tagResult.tag switch tag[0] { case '!': //ignore comment break case '#', '^': name := strings.TrimSpace(tag[1:]) sn := §ionNode{name, tag[0] == '^', tmpl.curline, []node{}} err := tmpl.parseSection(sn) if err != nil { return err } |
︙ | |||
495 496 497 498 499 500 501 | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | - + - + | continue Outer default: continue Outer } } } if errMissing { |
︙ |
Changes to template/mustache_test.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
271 272 273 274 275 276 277 | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | - + | } // Now set "error on missing varaible" and confirm we get errors. for _, test := range missing { output, err := renderString(test.tmpl, true, test.context) if err == nil { t.Errorf("%q expected missing variable error but got %q", test.tmpl, output) |
︙ | |||
463 464 465 466 467 468 469 470 471 472 473 474 475 476 | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | + + + | t.Errorf("expected %d tags, got 0", len(expected[i].Tags)) return } case template.Section, template.InvertedSection: compareTags(t, tag.Tags(), expected[i].Tags) case template.Partial: compareTags(t, tag.Tags(), expected[i].Tags) case template.Invalid: t.Errorf("invalid tag type: %s", tagString(tag.Type())) return default: t.Errorf("invalid tag type: %s", tagString(tag.Type())) return } } } |
︙ |
Changes to template/spec_test.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
28 29 30 31 32 33 34 | 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 | - + - + - + | "sort" "testing" "zettelstore.de/z/template" ) var enabledTests = map[string]map[string]bool{ |
︙ | |||
89 90 91 92 93 94 95 | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | - + | "Interpolation - Standalone": true, "Triple Mustache - Standalone": true, "Ampersand - Standalone": true, "Interpolation With Padding": true, "Triple Mustache With Padding": true, "Ampersand With Padding": true, }, |
︙ | |||
112 113 114 115 116 117 118 | 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 | - + - + | "Padding": true, "Dotted Names - Broken Chains": true, "Surrounding Whitespace": true, "Standalone Line Endings": true, "Standalone Without Previous Line": true, "Standalone Without Newline": true, }, |
︙ |
Changes to testdata/content/link/20200215204700.zettel.
1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 | - - - | title: Simple Test [[Home|https://zettelstore.de/z]] [[https://zettelstore.de]] [[Config|00000000000100]] [[00000000000100]] [[Frag|#frag]] [[#frag]] |
Changes to tests/markdown_test.go.
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 | - + - | //----------------------------------------------------------------------------- |
︙ | |||
63 64 65 66 67 68 69 | 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 | - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - + + - - - - - - - + + + + + + + - - - - - + + + + + | "[foo<http://example.com/?search=](uri)>\n", // 522 "[foo<http://example.com/?search=][ref]>\n\n[ref]: /uri\n", // 534 "<http://foo.bar.baz/test?q=hello&id=22&boolean>\n", // 591 } var reHeadingID = regexp.MustCompile(` id="[^"]*"`) |
Changes to tests/regression_test.go.
︙ | |||
83 84 85 86 87 88 89 | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | - | } defer f.Close() src, err := ioutil.ReadAll(f) return string(src), err } func checkFileContent(t *testing.T, filename string, gotContent string) { |
︙ | |||
125 126 127 128 129 130 131 | 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 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + | sb.Reset() if gotFirst != gotSecond { t.Errorf("\n1st: %q\n2nd: %q", gotFirst, gotSecond) } } |
Changes to tests/result/content/link/20200215204700.djson.
| 1 | - + |
|
Changes to tests/result/content/link/20200215204700.html.
1 2 3 4 5 | 1 2 3 4 5 6 | - + - - - | <p><a href="https://zettelstore.de/z" class="zs-external">Home</a> <a href="https://zettelstore.de" class="zs-external">https://zettelstore.de</a> <a href="00000000000100">Config</a> <a href="00000000000100">00000000000100</a> <a href="#frag">Frag</a> |
Changes to tests/result/content/link/20200215204700.native.
| 1 | - + |
|
Changes to tests/result/content/link/20200215204700.text.
| 1 | - + |
|
Deleted tools/build.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Added tools/version.go.
|
Changes to usecase/authenticate.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
40 41 42 43 44 45 46 | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | - + | return Authenticate{ port: port, ucGetUser: NewGetUser(port), } } // Run executes the use case. |
︙ |
Deleted usecase/context.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to usecase/copy_zettel.go.
1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + - | //----------------------------------------------------------------------------- |
︙ | |||
32 33 34 35 36 37 38 | 31 32 33 34 35 36 37 38 39 | - - + | if len(title) > 0 { title = "Copy of " + title } else { title = "Copy" } m.Set(meta.KeyTitle, title) } |
Changes to usecase/create_zettel.go.
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 | - + - | //----------------------------------------------------------------------------- |
︙ | |||
51 52 53 54 55 56 57 | 50 51 52 53 54 55 56 57 58 | - | m.Set(meta.KeyRole, runtime.GetDefaultRole()) } if syntax, ok := m.Get(meta.KeySyntax); !ok || syntax == "" { m.Set(meta.KeySyntax, runtime.GetDefaultSyntax()) } m.YamlSep = runtime.GetYAMLHeader() |
Changes to usecase/get_user.go.
︙ | |||
57 58 59 60 61 62 63 | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | - - + + | return nil, nil } return identMeta, nil } // Owner was not found or has another ident. Try via list search. filter := place.Filter{ Expr: map[string][]string{ |
︙ |
Changes to usecase/list_tags.go.
︙ | |||
45 46 47 48 49 50 51 | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | - | if err != nil { return nil, err } result := make(TagData) for _, m := range metas { if tl, ok := m.GetList(meta.KeyTags); ok && len(tl) > 0 { for _, t := range tl { |
︙ |
Changes to usecase/new_zettel.go.
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 31 32 33 34 35 36 37 38 39 40 | - + - + + - - - - - - - + + + + + + + - - + + | //----------------------------------------------------------------------------- |
Deleted usecase/order.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Added usecase/reload.go.
|
Changes to usecase/rename_zettel.go.
︙ | |||
47 48 49 50 51 52 53 | 47 48 49 50 51 52 53 54 55 56 57 58 | - - - - | // Run executes the use case. func (uc RenameZettel) Run(ctx context.Context, curZid, newZid id.Zid) error { noEnrichCtx := index.NoEnrichContext(ctx) if _, err := uc.port.GetMeta(noEnrichCtx, curZid); err != nil { return err } |
Changes to usecase/update_zettel.go.
︙ | |||
14 15 16 17 18 19 20 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - | import ( "context" "zettelstore.de/z/domain" "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" "zettelstore.de/z/index" |
︙ | |||
52 53 54 55 56 57 58 | 51 52 53 54 55 56 57 58 59 60 61 | - + | } m.SetNow(meta.KeyModified) m.YamlSep = oldZettel.Meta.YamlSep if m.Zid == id.ConfigurationZid { m.Set(meta.KeySyntax, meta.ValueSyntaxNone) } if !hasContent { |
Changes to web/adapter/api/get_links.go.
︙ | |||
95 96 97 98 99 100 101 | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | - + - + | outData.Images.External = stringRefs(extRefs) } } if kind&kindCite != 0 { outData.Cites = stringCites(summary.Cites) } |
︙ | |||
199 200 201 202 203 204 205 | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | + + + - + | } func validKindMatter(kind kindType, matter matterType) bool { if kind == 0 { return false } if kind&kindLink != 0 { if matter == 0 { return false } |
Deleted web/adapter/api/get_order.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to web/adapter/api/get_role_list.go.
︙ | |||
29 30 31 32 33 34 35 | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | - + | adapter.ReportUsecaseError(w, err) return } format := adapter.GetFormat(r, r.URL.Query(), encoder.GetDefaultFormat()) switch format { case "json": |
︙ |
Changes to web/adapter/api/get_tags_list.go.
︙ | |||
32 33 34 35 36 37 38 | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | - + | adapter.ReportUsecaseError(w, err) return } format := adapter.GetFormat(r, r.URL.Query(), encoder.GetDefaultFormat()) switch format { case "json": |
︙ |
Changes to web/adapter/api/get_zettel.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 | - - - - - + - + | "fmt" "net/http" "zettelstore.de/z/config/runtime" "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" "zettelstore.de/z/encoder" |
︙ | |||
71 72 73 74 75 76 77 | 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 | - + - + - + - + | } imageAdapter := encoder.AdaptImageOption{Adapter: adapter.MakeImageAdapter()} switch part { case partZettel: inhMeta := false if format != "raw" { |
︙ |
Deleted web/adapter/api/get_zettel_context.go.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to web/adapter/api/get_zettel_list.go.
︙ | |||
42 43 44 45 46 47 48 | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | - + | } metaList, err := listMeta.Run(ctx1, filter, sorter) if err != nil { adapter.ReportUsecaseError(w, err) return } |
︙ |
Changes to web/adapter/api/json.go.
︙ | |||
40 41 42 43 44 45 46 | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | - - - - - - | Content interface{} `json:"content"` } type jsonMeta struct { ID string `json:"id"` URL string `json:"url"` Meta map[string]string `json:"meta"` } |
︙ | |||
89 90 91 92 93 94 95 | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | + + - + | Content: content, } case partID: outData = idData default: panic(part) } enc := json.NewEncoder(w) enc.SetEscapeHTML(false) |
︙ | |||
288 289 290 291 292 293 294 | 284 285 286 287 288 289 290 | - - - - - - - - - - - - - - - - - - - - - - | if enc == nil { return adapter.ErrNoSuchFormat } _, err := enc.WriteMeta(w, m) return err } |
Changes to web/adapter/api/login.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | - + | "zettelstore.de/z/web/session" ) // MakePostLoginHandlerAPI creates a new HTTP handler to authenticate the given user via API. func MakePostLoginHandlerAPI(auth usecase.Authenticate) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if !startup.WithAuth() { |
︙ | |||
49 50 51 52 53 54 55 | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | - + | } if token == nil { w.Header().Set("WWW-Authenticate", `Bearer realm="Default"`) http.Error(w, "Authentication failed", http.StatusUnauthorized) return } |
︙ | |||
95 96 97 98 99 100 101 | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | - + - + | adapter.BadRequest(w, "Not authenticated") return } totalLifetime := auth.Expires.Sub(auth.Issued) currentLifetime := auth.Now.Sub(auth.Issued) // If we are in the first quarter of the tokens lifetime, return the token if currentLifetime*4 < totalLifetime { |
Added web/adapter/api/reload.go.
|
Changes to web/adapter/api/request.go.
︙ | |||
28 29 30 31 32 33 34 | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | - + | "meta": partMeta, "content": partContent, "zettel": partZettel, } func getPart(q url.Values, defPart partType) partType { p := q.Get("_part") |
︙ |
Changes to web/adapter/encoding.go.
︙ | |||
13 14 15 16 17 18 19 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - | import ( "context" "errors" "strings" "zettelstore.de/z/ast" |
︙ | |||
48 49 50 51 52 53 54 | 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 | - + - - - - - - - - - - - + - + - + | ctx context.Context, key byte, getMeta usecase.GetMeta, part, format string, ) func(*ast.LinkNode) ast.InlineNode { return func(origLink *ast.LinkNode) ast.InlineNode { origRef := origLink.Ref |
Added web/adapter/reload.go.
|
Changes to web/adapter/request.go.
︙ | |||
17 18 19 20 21 22 23 | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | - - - - - - - - - - - - - - - + | "strconv" "strings" "zettelstore.de/z/domain/meta" "zettelstore.de/z/place" ) |
︙ | |||
105 106 107 108 109 110 111 | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | - + - + | sorter.Limit = limit } } case negateQKey: filter = place.EnsureFilter(filter) filter.Negate = true case sQKey: |
︙ |
Changes to web/adapter/urlbuilder.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
32 33 34 35 36 37 38 | 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 | - - + + - - + + + + - - + + + + - - + + - + | // NewURLBuilder creates a new URLBuilder. func NewURLBuilder(key byte) *URLBuilder { return &URLBuilder{key: key} } // Clone an URLBuilder func (ub *URLBuilder) Clone() *URLBuilder { |
︙ |
Changes to web/adapter/webui/create_zettel.go.
︙ | |||
110 111 112 113 114 115 116 | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | + - + | } func renderZettelForm( w http.ResponseWriter, r *http.Request, te *TemplateEngine, zettel domain.Zettel, title string, |
︙ |
Changes to web/adapter/webui/get_info.go.
︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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 | + + + + + + + + | "net/http" "strings" "zettelstore.de/z/ast" "zettelstore.de/z/collect" "zettelstore.de/z/config/runtime" "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" "zettelstore.de/z/encoder" "zettelstore.de/z/usecase" "zettelstore.de/z/web/adapter" "zettelstore.de/z/web/session" ) type metaDataInfo struct { Key string Value string } type zettelReference struct { Zid id.Zid Title string HasURL bool URL string } type matrixElement struct { Text string HasURL bool URL string } type matrixLine struct { |
︙ | |||
108 109 110 111 112 113 114 | 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 | - + + - - + + - - - - - - - + + + + + + + + + - + - + - + | user := session.GetUser(ctx) var base baseData te.makeBaseData(ctx, langOption.Value, textTitle, user, &base) canCopy := base.CanCreate && !zn.Zettel.Content.IsBinary() te.renderTemplate(ctx, w, id.InfoTemplateZid, &base, struct { Zid string WebURL string |
Changes to web/adapter/webui/get_zettel.go.
︙ | |||
105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | + + | InfoURL string RoleText string RoleURL string HasTags bool Tags []simpleLink CanCopy bool CopyURL string CanNew bool NewURL string CanFolge bool FolgeURL string FolgeRefs string PrecursorRefs string HasExtURL bool ExtURL string ExtNewWindow string |
︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | + + | InfoURL: adapter.NewURLBuilder('i').SetZid(zid).String(), RoleText: roleText, RoleURL: adapter.NewURLBuilder('h').AppendQuery("role", roleText).String(), HasTags: len(tags) > 0, Tags: tags, CanCopy: canCopy, CopyURL: adapter.NewURLBuilder('c').SetZid(zid).String(), CanNew: canCopy && roleText == meta.ValueRoleNewTemplate, NewURL: adapter.NewURLBuilder('n').SetZid(zid).String(), CanFolge: base.CanCreate && !zn.Zettel.Content.IsBinary(), FolgeURL: adapter.NewURLBuilder('f').SetZid(zid).String(), FolgeRefs: formatMetaKey(zn.InhMeta, meta.KeyFolge, getTitle), PrecursorRefs: formatMetaKey(zn.InhMeta, meta.KeyPrecursor, getTitle), ExtURL: extURL, HasExtURL: hasExtURL, ExtNewWindow: htmlAttrNewWindow(newWindow && hasExtURL), |
︙ | |||
173 174 175 176 177 178 179 180 | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | + + + + - - - + + + | } return content.String(), nil } func buildTagInfos(m *meta.Meta) []simpleLink { var tagInfos []simpleLink if tags, ok := m.GetList(meta.KeyTags); ok { tagInfos = make([]simpleLink, 0, len(tags)) ub := adapter.NewURLBuilder('h') for _, t := range tags { // Cast to template.HTML is ok, because "t" is a tag name // and contains only legal characters by construction. |
︙ |
Changes to web/adapter/webui/home.go.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | - + - - - - - + + - - - - - + + + - - - - - - - - - + - - - + - + | //----------------------------------------------------------------------------- |
Changes to web/adapter/webui/htmlmeta.go.
︙ | |||
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 | - - - + - + | writeWord(w, key, m.GetDefault(key, "???w")) case meta.TypeWordSet: if l, ok := m.GetList(key); ok { writeWordSet(w, key, l) } case meta.TypeZettelmarkup: writeZettelmarkup(w, m.GetDefault(key, "???z"), option) |
︙ | |||
131 132 133 134 135 136 137 | 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 | - - - - - + - + - + - + | strfun.HTMLEscape(w, val, false) } func writeString(w io.Writer, val string) { strfun.HTMLEscape(w, val, false) } |
︙ |
Changes to web/adapter/webui/lists.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 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 | - + + + + + + + + - - - + + + + + + + + + - + - - - - + | import ( "context" "net/http" "net/url" "sort" "strconv" |
︙ | |||
191 192 193 194 195 196 197 | 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 | - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | filter, sorter := adapter.GetFilterSorter(query, true) if filter == nil || len(filter.Expr) == 0 { http.Redirect(w, r, adapter.NewURLBuilder('h').String(), http.StatusFound) return } ctx := r.Context() |
︙ | |||
319 320 321 322 323 324 325 | 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 | - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + - + - - - + + + | adapter.InternalServerError(w, "Build HTML meta list", err) return } var base baseData te.makeBaseData(ctx, runtime.GetDefaultLang(), runtime.GetSiteName(), user, &base) te.renderTemplate(ctx, w, id.ListTemplateZid, &base, struct { Title string |
Added web/adapter/webui/reload.go.
|
Changes to web/adapter/webui/rename_zettel.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
64 65 66 67 68 69 70 | 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 | - + - - + + + - + | func MakePostRenameZettelHandler(renameZettel usecase.RenameZettel) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { curZid, err := id.Parse(r.URL.Path[1:]) if err != nil { http.NotFound(w, r) return } |
Changes to web/adapter/webui/template.go.
︙ | |||
15 16 17 18 19 20 21 | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | - | "bytes" "context" "net/http" "sync" "zettelstore.de/z/auth/policy" "zettelstore.de/z/auth/token" |
︙ | |||
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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 | + - - + + + - + | stylesheetURL string homeURL string listZettelURL string listRolesURL string listTagsURL string withAuth bool loginURL string reloadURL string searchURL string } // NewTemplateEngine creates a new TemplateEngine. func NewTemplateEngine(mgr place.Manager, pol policy.Policy) *TemplateEngine { te := &TemplateEngine{ place: mgr, policy: pol, stylesheetURL: adapter.NewURLBuilder('z').SetZid( id.BaseCSSZid).AppendQuery("_format", "raw").AppendQuery( "_part", "content").String(), homeURL: adapter.NewURLBuilder('/').String(), listZettelURL: adapter.NewURLBuilder('h').String(), |
︙ | |||
114 115 116 117 118 119 120 | 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 | - + + - + + - - - - - - - - + + + + + + + + - + | func (te *TemplateEngine) canWrite( ctx context.Context, user *meta.Meta, zettel domain.Zettel) bool { return te.policy.CanWrite(user, zettel.Meta, zettel.Meta) && te.place.CanUpdateZettel(ctx, zettel) } |
︙ | |||
191 192 193 194 195 196 197 198 | 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 | + + + + + - - + - - + - - + + + + + + + + + + + + + - + - - - - + + - - - - - - - - - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + | userLogoutURL = adapter.NewURLBuilder('a').SetZid(user.Zid).String() } data.Lang = lang data.StylesheetURL = te.stylesheetURL data.Title = title data.HomeURL = te.homeURL data.ListZettelURL = te.listZettelURL data.ListRolesURL = te.listRolesURL data.ListTagsURL = te.listTagsURL data.CanCreate = canCreate data.NewZettelLinks = newZettelLinks data.WithAuth = te.withAuth |
︙ | |||
275 276 277 278 279 280 281 | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | - - + + + - - - - + + + - | t, err := te.getTemplate(ctx, templateID) if err != nil { adapter.InternalServerError(w, "Unable to get template", err) return } if user := session.GetUser(ctx); user != nil { htmlLifetime, _ := startup.TokenLifetime() |
Changes to web/router/router.go.
1 | 1 2 3 4 5 6 7 8 9 | - + | //----------------------------------------------------------------------------- |
︙ | |||
90 91 92 93 94 95 96 | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | - + | } func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { match := rt.reURL.FindStringSubmatch(r.URL.Path) if len(match) == 3 { key := match[1][0] index := indexZettel |
︙ |
Deleted www/build.md.
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
Changes to www/changes.wiki.
1 2 | 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 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + | <title>Change Log</title> |
︙ | |||
86 87 88 89 90 91 92 | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | - - + + - + | Zettelstore will still work. * (minor) Login will take at least 500 milliseconds to mitigate login attacks. This affects both the API and the WebUI. * (minor) Add a sort option “_random” to produce a zettel list in random order. <tt>_order</tt> / <tt>order</tt> are now an aliases for the query parameters <tt>_sort</tt> / <tt>sort</tt>. <h3>WebUI</h3> |
︙ | |||
152 153 154 155 156 157 158 | 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 | - + - + | <h3>WebUI</h3> * (minor) Remove list of tags in “List Zettel” and search results. There was some feedback that the additional tags were not helpful. * (minor) Move zettel field "role" above "tags" and move "syntax" more to "content". * (minor) Rename zettel operation “clone” to “copy”. * (major) All predefined HTML templates have now a visibility value “expert”. If you want to see them as an non-expert owner, you must temporary enable <tt>expert-mode</tt> and change the <tt>visibility</tt> metadata value. |
︙ | |||
219 220 221 222 223 224 225 | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | - | The WebUI menu item “New” changed to a drop-down list with all those zettel, ordered by their identifier. All metadata keys with the prefix <tt>new-</tt> will be translated to a new or updated keys/value without that prefix. You can use this mechanism to specify a role for the new zettel, or a different title. The title of the template zettel is used in the drop-down list. The initial template zettel “New Zettel” has now a different zettel identifier (now: <tt>00000000091001</tt>, was: <tt>00000000040001</tt>). <b>Please update it, if you changed that zettel.</b> |
︙ |
Changes to www/download.wiki.
1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + - + - - - - + + + + - - - + + | <title>Download</title> <h1>Download of Zettelstore Software</h1> <h2>Foreword</h2> * Zettelstore is free/libre open source software, licensed under EUPL-1.2-or-later. * The software is provided as-is. * There is no guarantee that it will not damage your system. * However, it is in use by the main developer since March 2020 without any damage. * It may be useful for you. It is useful for me. |
Changes to www/impri.wiki.
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 | + - + + + - - + + + - + + | <title>Imprint & Privacy</title> <h1>Imprint</h1> <p> Detlef Stern<br> Max-Planck-Str. 39<br> 74081 Heilbronn<br> |
Changes to www/index.wiki.
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 | - + - + - + - + - - - - - + - - - - - - - - - + | <title>Home</title> <b>Zettelstore</b> is a software that collects and relates your notes (“zettel”) to represent and enhance your knowledge. It helps with many tasks of personal knowledge management by explicitly supporting the |
Changes to www/plan.wiki.
| 1 2 3 4 5 6 7 8 | - + |
|
︙ | |||
21 22 23 24 25 26 27 | 21 22 23 24 25 26 27 28 29 30 | - + | * The horizontal tab character (<tt>U+0009</tt>) is not supported. * Missing support for citation keys. * … <h3>Planned improvements</h3> * Support for mathematical content is missing, e.g. <code>$$F(x) &= \\int^a_b \\frac{1}{3}x^3$$</code>. |