Index: VERSION ================================================================== --- VERSION +++ VERSION @@ -1,1 +1,1 @@ -0.5.1 +0.4 Index: ast/ast.go ================================================================== --- ast/ast.go +++ ast/ast.go @@ -62,10 +62,17 @@ // InlineNode is the interface that all inline nodes must implement. type InlineNode interface { Node inlineNode() } + +// InlineEmbedNode is a node that specifies some embeddings in inline mode. +// It is abstract, b/c there are different concrete type implementations. +type InlineEmbedNode interface { + InlineNode + inlineEmbedNode() +} // Reference is a reference to external or internal material. type Reference struct { URL *url.URL Value string Index: ast/block.go ================================================================== --- ast/block.go +++ ast/block.go @@ -8,11 +8,11 @@ // under this license. //----------------------------------------------------------------------------- package ast -import "zettelstore.de/c/attrs" +import "zettelstore.de/c/zjson" // Definition of Block nodes. // BlockSlice is a slice of BlockNodes. type BlockSlice []BlockNode @@ -53,62 +53,62 @@ func (*ParaNode) blockNode() { /* Just a marker */ } func (*ParaNode) itemNode() { /* Just a marker */ } func (*ParaNode) descriptionNode() { /* Just a marker */ } +// NewParaNode creates an empty ParaNode. +func NewParaNode() *ParaNode { return &ParaNode{} } + // CreateParaNode creates a parameter block from inline nodes. -func CreateParaNode(nodes ...InlineNode) *ParaNode { return &ParaNode{Inlines: nodes} } +func CreateParaNode(nodes ...InlineNode) *ParaNode { + return &ParaNode{Inlines: nodes} +} // WalkChildren walks down the inline elements. -func (pn *ParaNode) WalkChildren(v Visitor) { Walk(v, &pn.Inlines) } +func (pn *ParaNode) WalkChildren(v Visitor) { + Walk(v, &pn.Inlines) +} //-------------------------------------------------------------------------- // VerbatimNode contains uninterpreted text type VerbatimNode struct { Kind VerbatimKind - Attrs attrs.Attributes + Attrs zjson.Attributes Content []byte } // VerbatimKind specifies the format that is applied to code inline nodes. -type VerbatimKind int +type VerbatimKind uint8 // Constants for VerbatimCode const ( _ VerbatimKind = iota VerbatimZettel // Zettel content VerbatimProg // Program code - VerbatimEval // Code to be externally interpreted. Syntax is stored in default attribute. VerbatimComment // Block comment VerbatimHTML // Block HTML, e.g. for Markdown - VerbatimMath // Block math mode ) func (*VerbatimNode) blockNode() { /* Just a marker */ } func (*VerbatimNode) itemNode() { /* Just a marker */ } // WalkChildren does nothing. func (*VerbatimNode) WalkChildren(Visitor) { /* No children*/ } -// Supported syntax values for VerbatimEval. -const ( - VerbatimEvalSyntaxDraw = "draw" -) - //-------------------------------------------------------------------------- // RegionNode encapsulates a region of block nodes. type RegionNode struct { Kind RegionKind - Attrs attrs.Attributes + Attrs zjson.Attributes Blocks BlockSlice Inlines InlineSlice // Optional text at the end of the region } // RegionKind specifies the actual region type. -type RegionKind int +type RegionKind uint8 // Values for RegionCode const ( _ RegionKind = iota RegionSpan // Just a span of blocks @@ -128,27 +128,29 @@ //-------------------------------------------------------------------------- // HeadingNode stores the heading text and level. type HeadingNode struct { Level int - Attrs attrs.Attributes + Inlines InlineSlice // Heading text, possibly formatted Slug string // Heading text, normalized Fragment string // Heading text, suitable to be used as an unique URL fragment - Inlines InlineSlice // Heading text, possibly formatted + Attrs zjson.Attributes } func (*HeadingNode) blockNode() { /* Just a marker */ } func (*HeadingNode) itemNode() { /* Just a marker */ } // WalkChildren walks the heading text. -func (hn *HeadingNode) WalkChildren(v Visitor) { Walk(v, &hn.Inlines) } +func (hn *HeadingNode) WalkChildren(v Visitor) { + Walk(v, &hn.Inlines) +} //-------------------------------------------------------------------------- // HRuleNode specifies a horizontal rule. type HRuleNode struct { - Attrs attrs.Attributes + Attrs zjson.Attributes } func (*HRuleNode) blockNode() { /* Just a marker */ } func (*HRuleNode) itemNode() { /* Just a marker */ } @@ -159,11 +161,11 @@ // NestedListNode specifies a nestable list, either ordered or unordered. type NestedListNode struct { Kind NestedListKind Items []ItemSlice - Attrs attrs.Attributes + Attrs zjson.Attributes } // NestedListKind specifies the actual list type. type NestedListKind uint8 Index: ast/inline.go ================================================================== --- ast/inline.go +++ ast/inline.go @@ -11,11 +11,11 @@ package ast import ( "unicode/utf8" - "zettelstore.de/c/attrs" + "zettelstore.de/c/zjson" ) // Definitions of inline nodes. // InlineSlice is a list of BlockNodes. @@ -98,13 +98,13 @@ // -------------------------------------------------------------------------- // LinkNode contains the specified link. type LinkNode struct { - Attrs attrs.Attributes // Optional attributes Ref *Reference - Inlines InlineSlice // The text associated with the link. + Inlines InlineSlice // The text associated with the link. + Attrs zjson.Attributes // Optional attributes } func (*LinkNode) inlineNode() { /* Just a marker */ } // WalkChildren walks to the link text. @@ -116,49 +116,57 @@ // -------------------------------------------------------------------------- // EmbedRefNode contains the specified embedded reference material. type EmbedRefNode struct { - Attrs attrs.Attributes // Optional attributes Ref *Reference // The reference to be embedded. + Inlines InlineSlice // Optional text associated with the image. + Attrs zjson.Attributes // Optional attributes Syntax string // Syntax of referenced material, if known - Inlines InlineSlice // Optional text associated with the image. } -func (*EmbedRefNode) inlineNode() { /* Just a marker */ } +func (*EmbedRefNode) inlineNode() { /* Just a marker */ } +func (*EmbedRefNode) inlineEmbedNode() { /* Just a marker */ } // WalkChildren walks to the text that describes the embedded material. -func (en *EmbedRefNode) WalkChildren(v Visitor) { Walk(v, &en.Inlines) } +func (en *EmbedRefNode) WalkChildren(v Visitor) { + Walk(v, &en.Inlines) +} // -------------------------------------------------------------------------- // EmbedBLOBNode contains the specified embedded BLOB material. type EmbedBLOBNode struct { - Attrs attrs.Attributes // Optional attributes - Syntax string // Syntax of Blob Blob []byte // BLOB data itself. + Syntax string // Syntax of Blob Inlines InlineSlice // Optional text associated with the image. + Attrs zjson.Attributes // Optional attributes } -func (*EmbedBLOBNode) inlineNode() { /* Just a marker */ } +func (*EmbedBLOBNode) inlineNode() { /* Just a marker */ } +func (*EmbedBLOBNode) inlineEmbedNode() { /* Just a marker */ } // WalkChildren walks to the text that describes the embedded material. -func (en *EmbedBLOBNode) WalkChildren(v Visitor) { Walk(v, &en.Inlines) } +func (en *EmbedBLOBNode) WalkChildren(v Visitor) { + Walk(v, &en.Inlines) +} // -------------------------------------------------------------------------- // CiteNode contains the specified citation. type CiteNode struct { - Attrs attrs.Attributes // Optional attributes Key string // The citation key Inlines InlineSlice // Optional text associated with the citation. + Attrs zjson.Attributes // Optional attributes } func (*CiteNode) inlineNode() { /* Just a marker */ } // WalkChildren walks to the cite text. -func (cn *CiteNode) WalkChildren(v Visitor) { Walk(v, &cn.Inlines) } +func (cn *CiteNode) WalkChildren(v Visitor) { + Walk(v, &cn.Inlines) +} // -------------------------------------------------------------------------- // MarkNode contains the specified merked position. // It is a BlockNode too, because although it is typically parsed during inline @@ -181,30 +189,32 @@ // -------------------------------------------------------------------------- // FootnoteNode contains the specified footnote. type FootnoteNode struct { - Attrs attrs.Attributes // Optional attributes Inlines InlineSlice // The footnote text. + Attrs zjson.Attributes // Optional attributes } func (*FootnoteNode) inlineNode() { /* Just a marker */ } // WalkChildren walks to the footnote text. -func (fn *FootnoteNode) WalkChildren(v Visitor) { Walk(v, &fn.Inlines) } +func (fn *FootnoteNode) WalkChildren(v Visitor) { + Walk(v, &fn.Inlines) +} // -------------------------------------------------------------------------- // FormatNode specifies some inline formatting. type FormatNode struct { Kind FormatKind - Attrs attrs.Attributes // Optional attributes. + Attrs zjson.Attributes // Optional attributes. Inlines InlineSlice } // FormatKind specifies the format that is applied to the inline nodes. -type FormatKind int +type FormatKind uint8 // Constants for FormatCode const ( _ FormatKind = iota FormatEmph // Emphasized text. @@ -218,23 +228,25 @@ ) func (*FormatNode) inlineNode() { /* Just a marker */ } // WalkChildren walks to the formatted text. -func (fn *FormatNode) WalkChildren(v Visitor) { Walk(v, &fn.Inlines) } +func (fn *FormatNode) WalkChildren(v Visitor) { + Walk(v, &fn.Inlines) +} // -------------------------------------------------------------------------- // LiteralNode specifies some uninterpreted text. type LiteralNode struct { Kind LiteralKind - Attrs attrs.Attributes // Optional attributes. + Attrs zjson.Attributes // Optional attributes. Content []byte } // LiteralKind specifies the format that is applied to code inline nodes. -type LiteralKind int +type LiteralKind uint8 // Constants for LiteralCode const ( _ LiteralKind = iota LiteralZettel // Zettel content @@ -241,12 +253,11 @@ LiteralProg // Inline program code LiteralInput // Computer input, e.g. Keyboard strokes LiteralOutput // Computer output LiteralComment // Inline comment LiteralHTML // Inline HTML, e.g. for Markdown - LiteralMath // Inline math mode ) func (*LiteralNode) inlineNode() { /* Just a marker */ } // WalkChildren does nothing. func (*LiteralNode) WalkChildren(Visitor) { /* No children*/ } Index: ast/ref.go ================================================================== --- ast/ref.go +++ ast/ref.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2020-2022 Detlef Stern +// Copyright (c) 2020-2021 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- Index: ast/ref_test.go ================================================================== --- ast/ref_test.go +++ ast/ref_test.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2020-2022 Detlef Stern +// Copyright (c) 2020-2021 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- Index: ast/walk.go ================================================================== --- ast/walk.go +++ ast/walk.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2021-2022 Detlef Stern +// Copyright (c) 2021 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- Index: ast/walk_test.go ================================================================== --- ast/walk_test.go +++ ast/walk_test.go @@ -11,11 +11,11 @@ package ast_test import ( "testing" - "zettelstore.de/c/attrs" + "zettelstore.de/c/zjson" "zettelstore.de/z/ast" ) func BenchmarkWalk(b *testing.B) { root := ast.BlockSlice{ @@ -44,11 +44,11 @@ Inlines: ast.CreateInlineSliceFromWords("This", "is", "some", "intermediate", "text."), }, ast.CreateParaNode( &ast.FormatNode{ Kind: ast.FormatEmph, - Attrs: attrs.Attributes(map[string]string{ + Attrs: zjson.Attributes(map[string]string{ "": "class", "color": "green", }), Inlines: ast.CreateInlineSliceFromWords("This", "is", "some", "emphasized", "text."), }, Index: auth/impl/impl.go ================================================================== --- auth/impl/impl.go +++ auth/impl/impl.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2021-2022 Detlef Stern +// Copyright (c) 2021 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- Index: box/constbox/base.css ================================================================== --- box/constbox/base.css +++ box/constbox/base.css @@ -123,10 +123,11 @@ } main form div { margin: .5em 0 0 0 } input { font-family: monospace } input[type="submit"],button,select { font: inherit } label { font-family: sans-serif; font-size:.9rem } + label::after { content:":" } textarea { font-family: monospace; resize: vertical; width: 100%; } @@ -135,17 +136,19 @@ display:block; border:none; border-bottom:1px solid #ccc; width:100%; } - input.zs-primary { float:right } - input.zs-secondary { float:left } + .zs-button { + float:right; + margin: .5em 0 .5em 1em; + } a:not([class]) { text-decoration-skip-ink: auto } a.broken { text-decoration: line-through } img { max-width: 100% } img.right { float: right } - ol.zs-endnotes { + ol.endnotes { padding-top: .5rem; border-top: 1px solid; } kbd { font-family:monospace } code,pre { Index: box/constbox/base.mustache ================================================================== --- box/constbox/base.mustache +++ box/constbox/base.mustache @@ -1,16 +1,12 @@ - - - {{{MetaHeader}}} -{{#CSSRoleURL}}{{/CSSRoleURL}} {{Title}}
{{{Content}}}
-{{#FooterHTML}}{{/FooterHTML}} -{{#DebugMode}}
WARNING: Debug mode is enabled. DO NOT USE IN PRODUCTION!
{{/DebugMode}} - - +{{#FooterHTML}} + +{{/FooterHTML}} Index: box/constbox/constbox.go ================================================================== --- box/constbox/constbox.go +++ box/constbox/constbox.go @@ -293,21 +293,13 @@ api.KeyRole: api.ValueRoleConfiguration, api.KeySyntax: "css", api.KeyVisibility: api.ValueVisibilityPublic, }, domain.NewContent([]byte("/* User-defined CSS */"))}, - id.RoleCSSMapZid: { - constHeader{ - api.KeyTitle: "Zettelstore Role to CSS Map", - api.KeyRole: api.ValueRoleConfiguration, - api.KeySyntax: api.ValueSyntaxNone, - api.KeyVisibility: api.ValueVisibilityExpert, - }, - domain.NewContent(nil)}, id.EmojiZid: { constHeader{ - api.KeyTitle: "Zettelstore Generic Emoji", + api.KeyTitle: "Generic Emoji", api.KeyRole: api.ValueRoleConfiguration, api.KeySyntax: api.ValueSyntaxGif, api.KeyReadOnly: api.ValueTrue, api.KeyVisibility: api.ValueVisibilityPublic, }, Index: box/constbox/delete.mustache ================================================================== --- box/constbox/delete.mustache +++ box/constbox/delete.mustache @@ -35,9 +35,9 @@ {{#MetaPairs}}
{{Key}}:
{{Value}}
{{/MetaPairs}}
- +
{{end}} Index: box/constbox/form.mustache ================================================================== --- box/constbox/form.mustache +++ box/constbox/form.mustache @@ -2,53 +2,37 @@

{{Heading}}

- - -
-
-
- - -{{#HasRoleData}} - -{{#RoleData}} - -{{/HasRoleData}} -
- - -
-
- -
- - -{{#HasSyntaxData}} - -{{#SyntaxData}} - -{{/HasSyntaxData}}
+ + +
{{#IsTextContent}} - - + + {{/IsTextContent}}
-
- - -
+
Index: box/constbox/login.mustache ================================================================== --- box/constbox/login.mustache +++ box/constbox/login.mustache @@ -5,15 +5,15 @@ {{#Retry}}
Wrong user name / password. Try again.
{{/Retry}}
- +
- +
-
+
Index: box/constbox/rename.mustache ================================================================== --- box/constbox/rename.mustache +++ box/constbox/rename.mustache @@ -29,13 +29,13 @@
-
+
{{#MetaPairs}}
{{Key}}:
{{Value}}
{{/MetaPairs}}
Index: box/dirbox/dirbox.go ================================================================== --- box/dirbox/dirbox.go +++ box/dirbox/dirbox.go @@ -17,10 +17,11 @@ "net/url" "os" "path/filepath" "sync" + "zettelstore.de/c/api" "zettelstore.de/z/box" "zettelstore.de/z/box/manager" "zettelstore.de/z/box/notify" "zettelstore.de/z/domain" "zettelstore.de/z/domain/id" @@ -234,10 +235,11 @@ } m, c, err := dp.srvGetMetaContent(ctx, entry, zid) if err != nil { return domain.Zettel{}, err } + dp.cleanupMeta(m) zettel := domain.Zettel{Meta: m, Content: domain.NewContent(c)} dp.log.Trace().Zid(zid).Msg("GetZettel") return zettel, nil } @@ -253,10 +255,11 @@ } m, err := dp.srvGetMeta(ctx, entry, zid) if err != nil { return nil, err } + dp.cleanupMeta(m) return m, nil } func (dp *dirBox) ApplyZid(_ context.Context, handle box.ZidFunc, constraint search.RetrievePredicate) error { entries := dp.dirSrv.GetDirEntries(constraint) @@ -276,10 +279,11 @@ m, err := dp.srvGetMeta(ctx, entry, entry.Zid) if err != nil { dp.log.Trace().Err(err).Msg("ApplyMeta/getMeta") return err } + dp.cleanupMeta(m) dp.cdata.Enricher.Enrich(ctx, m, dp.number) handle(m) } return nil } @@ -395,5 +399,14 @@ func (dp *dirBox) ReadStats(st *box.ManagedBoxStats) { st.ReadOnly = dp.readonly st.Zettel = dp.dirSrv.NumDirEntries() dp.log.Trace().Int("zettel", int64(st.Zettel)).Msg("ReadStats") } + +func (dp *dirBox) cleanupMeta(m *meta.Meta) { + if role, ok := m.Get(api.KeyRole); !ok || role == "" { + m.Set(api.KeyRole, dp.cdata.Config.GetDefaultRole()) + } + if syntax, ok := m.Get(api.KeySyntax); !ok || syntax == "" { + m.Set(api.KeySyntax, dp.cdata.Config.GetDefaultSyntax()) + } +} Index: box/dirbox/service.go ================================================================== --- box/dirbox/service.go +++ box/dirbox/service.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- // Copyright (c) 2020-2022 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- Index: box/filebox/filebox.go ================================================================== --- box/filebox/filebox.go +++ box/filebox/filebox.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- // Copyright (c) 2021-2022 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- @@ -69,16 +69,21 @@ } // CalcDefaultMeta returns metadata with default values for the given entry. func CalcDefaultMeta(zid id.Zid, ext string) *meta.Meta { m := meta.New(zid) + m.Set(api.KeyTitle, zid.String()) m.Set(api.KeySyntax, calculateSyntax(ext)) return m } // CleanupMeta enhances the given metadata. func CleanupMeta(m *meta.Meta, zid id.Zid, ext string, inMeta bool, uselessFiles []string) { + if title, ok := m.Get(api.KeyTitle); !ok || title == "" { + m.Set(api.KeyTitle, zid.String()) + } + if inMeta { if syntax, ok := m.Get(api.KeySyntax); !ok || syntax == "" { dm := CalcDefaultMeta(zid, ext) syntax, ok = dm.Get(api.KeySyntax) if !ok { Index: box/filebox/zipbox.go ================================================================== --- box/filebox/zipbox.go +++ box/filebox/zipbox.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- // Copyright (c) 2021-2022 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- Index: box/manager/manager.go ================================================================== --- box/manager/manager.go +++ box/manager/manager.go @@ -13,14 +13,14 @@ import ( "context" "io" "net/url" + "sort" "sync" "time" - "zettelstore.de/c/maps" "zettelstore.de/z/auth" "zettelstore.de/z/box" "zettelstore.de/z/box/manager/memstore" "zettelstore.de/z/box/manager/store" "zettelstore.de/z/config" @@ -78,11 +78,18 @@ } registry[scheme] = create } // GetSchemes returns all registered scheme, ordered by scheme string. -func GetSchemes() []string { return maps.Keys(registry) } +func GetSchemes() []string { + result := make([]string, 0, len(registry)) + for scheme := range registry { + result = append(result, scheme) + } + sort.Strings(result) + return result +} // Manager is a coordinating box. type Manager struct { mgrLog *logger.Logger mgrMx sync.RWMutex Index: box/manager/memstore/memstore.go ================================================================== --- box/manager/memstore/memstore.go +++ box/manager/memstore/memstore.go @@ -18,11 +18,10 @@ "sort" "strings" "sync" "zettelstore.de/c/api" - "zettelstore.de/c/maps" "zettelstore.de/z/box/manager/store" "zettelstore.de/z/domain/id" "zettelstore.de/z/domain/meta" ) @@ -589,10 +588,15 @@ func dumpStringRefs(w io.Writer, title, preString, postString string, srefs stringRefs) { if len(srefs) == 0 { return } fmt.Fprintln(w, "====", title) - for _, s := range maps.Keys(srefs) { + slice := make([]string, 0, len(srefs)) + for s := range srefs { + slice = append(slice, s) + } + sort.Strings(slice) + for _, s := range slice { fmt.Fprintf(w, "; %s%s%s\n", preString, s, postString) fmt.Fprintln(w, ":", srefs[s]) } } Index: box/notify/directory_test.go ================================================================== --- box/notify/directory_test.go +++ box/notify/directory_test.go @@ -14,10 +14,11 @@ "testing" "zettelstore.de/c/api" "zettelstore.de/z/domain/id" _ "zettelstore.de/z/parser/blob" // Allow to use BLOB parser. + _ "zettelstore.de/z/parser/draw" // Allow to use draw parser. _ "zettelstore.de/z/parser/markdown" // Allow to use markdown parser. _ "zettelstore.de/z/parser/none" // Allow to use none parser. _ "zettelstore.de/z/parser/plain" // Allow to use plain parser. _ "zettelstore.de/z/parser/zettelmark" // Allow to use zettelmark parser. ) @@ -46,11 +47,11 @@ } func TestNewExtIsBetter(t *testing.T) { extVals := []string{ // Main Formats - api.ValueSyntaxZmk, "markdown", "md", + api.ValueSyntaxZmk, api.ValueSyntaxDraw, "markdown", "md", // Other supported text formats "css", "txt", api.ValueSyntaxHTML, api.ValueSyntaxNone, "mustache", api.ValueSyntaxText, "plain", // Supported graphics formats api.ValueSyntaxGif, "png", api.ValueSyntaxSVG, "jpeg", "jpg", // Unsupported syntax values Index: box/notify/entry.go ================================================================== --- box/notify/entry.go +++ box/notify/entry.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- // Copyright (c) 2020-2022 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- @@ -97,11 +97,11 @@ func calcContentExt(syntax string, yamlSep bool, getZettelFileSyntax func() []string) string { if yamlSep { return extZettel } switch syntax { - case api.ValueSyntaxNone, api.ValueSyntaxZmk: + case api.ValueSyntaxDraw, api.ValueSyntaxNone, api.ValueSyntaxZmk: return extZettel } for _, s := range getZettelFileSyntax() { if s == syntax { return extZettel Index: cmd/cmd_file.go ================================================================== --- cmd/cmd_file.go +++ cmd/cmd_file.go @@ -39,11 +39,13 @@ Content: domain.NewContent(inp.Src[inp.Pos:]), }, m.GetDefault(api.KeySyntax, api.ValueSyntaxZmk), nil, ) - encdr := encoder.Create(api.Encoder(enc)) + encdr := encoder.Create(api.Encoder(enc), &encoder.Environment{ + Lang: m.GetDefault(api.KeyLang, api.ValueLangEN), + }) if encdr == nil { fmt.Fprintf(os.Stderr, "Unknown format %q\n", enc) return 2, nil } _, err = encdr.WriteZettel(os.Stdout, z, parser.ParseMetadata) Index: cmd/cmd_run.go ================================================================== --- cmd/cmd_run.go +++ cmd/cmd_run.go @@ -24,11 +24,11 @@ ) // ---------- Subcommand: run ------------------------------------------------ func flgRun(fs *flag.FlagSet) { - fs.String("c", "", "configuration file") + fs.String("c", defConfigfile, "configuration file") fs.Uint("a", 0, "port number kernel service (0=disable)") fs.Uint("p", 23123, "port number web service") fs.String("d", "", "zettel directory") fs.Bool("r", false, "system-wide read-only mode") fs.Bool("v", false, "verbose mode") @@ -65,12 +65,11 @@ ucGetAllMeta := usecase.NewGetAllMeta(protectedBoxManager) ucGetZettel := usecase.NewGetZettel(protectedBoxManager) ucParseZettel := usecase.NewParseZettel(rtConfig, ucGetZettel) ucEvaluate := usecase.NewEvaluate(rtConfig, ucGetZettel, ucGetMeta) ucListMeta := usecase.NewListMeta(protectedBoxManager) - ucListSyntax := usecase.NewListSyntax(protectedBoxManager) - ucListRoles := usecase.NewListRoles(protectedBoxManager) + ucListRoles := usecase.NewListRole(protectedBoxManager) ucListTags := usecase.NewListTags(protectedBoxManager) ucZettelContext := usecase.NewZettelContext(protectedBoxManager, rtConfig) ucDelete := usecase.NewDeleteZettel(ucLog, protectedBoxManager) ucUpdate := usecase.NewUpdateZettel(ucLog, protectedBoxManager) ucRename := usecase.NewRenameZettel(ucLog, protectedBoxManager) @@ -84,16 +83,16 @@ if !authManager.IsReadonly() { webSrv.AddZettelRoute('b', server.MethodGet, wui.MakeGetRenameZettelHandler( ucGetMeta, &ucEvaluate)) webSrv.AddZettelRoute('b', server.MethodPost, wui.MakePostRenameZettelHandler(&ucRename)) webSrv.AddZettelRoute('c', server.MethodGet, wui.MakeGetCreateZettelHandler( - ucGetZettel, &ucCreateZettel, ucListRoles, ucListSyntax)) + ucGetZettel, &ucCreateZettel)) webSrv.AddZettelRoute('c', server.MethodPost, wui.MakePostCreateZettelHandler(&ucCreateZettel)) webSrv.AddZettelRoute('d', server.MethodGet, wui.MakeGetDeleteZettelHandler( ucGetMeta, ucGetAllMeta, &ucEvaluate)) webSrv.AddZettelRoute('d', server.MethodPost, wui.MakePostDeleteZettelHandler(&ucDelete)) - webSrv.AddZettelRoute('e', server.MethodGet, wui.MakeEditGetZettelHandler(ucGetZettel, ucListRoles, ucListSyntax)) + webSrv.AddZettelRoute('e', server.MethodGet, wui.MakeEditGetZettelHandler(ucGetZettel)) webSrv.AddZettelRoute('e', server.MethodPost, wui.MakeEditSetZettelHandler(&ucUpdate)) } webSrv.AddListRoute('g', server.MethodGet, wui.MakeGetGoActionHandler(&ucRefresh)) webSrv.AddListRoute('h', server.MethodGet, wui.MakeListHTMLMetaHandler( ucListMeta, ucListRoles, ucListTags, &ucEvaluate)) @@ -109,15 +108,16 @@ // API webSrv.AddListRoute('a', server.MethodPost, a.MakePostLoginHandler(&ucAuthenticate)) webSrv.AddListRoute('a', server.MethodPut, a.MakeRenewAuthHandler()) webSrv.AddListRoute('j', server.MethodGet, a.MakeListMetaHandler(ucListMeta)) webSrv.AddZettelRoute('j', server.MethodGet, a.MakeGetZettelHandler(ucGetZettel)) - webSrv.AddListRoute('m', server.MethodGet, a.MakeListMapMetaHandler(ucListRoles, ucListTags)) webSrv.AddZettelRoute('m', server.MethodGet, a.MakeGetMetaHandler(ucGetMeta)) webSrv.AddZettelRoute('o', server.MethodGet, a.MakeGetOrderHandler( usecase.NewZettelOrder(protectedBoxManager, ucEvaluate))) webSrv.AddZettelRoute('p', server.MethodGet, a.MakeGetParsedZettelHandler(ucParseZettel)) + webSrv.AddListRoute('r', server.MethodGet, a.MakeListRoleHandler(ucListRoles)) + webSrv.AddListRoute('t', server.MethodGet, a.MakeListTagsHandler(ucListTags)) webSrv.AddZettelRoute('u', server.MethodGet, a.MakeListUnlinkedMetaHandler( ucGetMeta, ucUnlinkedRefs, &ucEvaluate)) webSrv.AddZettelRoute('v', server.MethodGet, a.MakeGetEvalZettelHandler(ucEvaluate)) webSrv.AddListRoute('x', server.MethodGet, a.MakeGetDataHandler(ucVersion)) webSrv.AddListRoute('x', server.MethodPost, a.MakePostCommandHandler(&ucIsAuth, &ucRefresh)) Index: cmd/command.go ================================================================== --- cmd/command.go +++ cmd/command.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2020-2022 Detlef Stern +// Copyright (c) 2020-2021 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- @@ -10,12 +10,12 @@ package cmd import ( "flag" + "sort" - "zettelstore.de/c/maps" "zettelstore.de/z/logger" ) // Command stores information about commands / sub-commands. type Command struct { @@ -61,6 +61,13 @@ cmd, ok := commands[name] return cmd, ok } // List returns a sorted list of all registered command names. -func List() []string { return maps.Keys(commands) } +func List() []string { + result := make([]string, 0, len(commands)) + for name := range commands { + result = append(result, name) + } + sort.Strings(result) + return result +} Index: cmd/main.go ================================================================== --- cmd/main.go +++ cmd/main.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- // Copyright (c) 2020-2022 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- @@ -15,11 +15,10 @@ "flag" "fmt" "net" "net/url" "os" - "runtime/debug" "strconv" "strings" "zettelstore.de/c/api" "zettelstore.de/z/auth" @@ -34,11 +33,13 @@ "zettelstore.de/z/kernel" "zettelstore.de/z/logger" "zettelstore.de/z/web/server" ) -const strRunSimple = "run-simple" +const ( + defConfigfile = ".zscfg" +) func init() { RegisterCommand(Command{ Name: "help", Func: func(*flag.FlagSet) (int, error) { @@ -61,11 +62,11 @@ Header: true, LineServer: true, SetFlags: flgRun, }) RegisterCommand(Command{ - Name: strRunSimple, + Name: "run-simple", Func: runFunc, Simple: true, Boxes: true, Header: true, // LineServer: true, @@ -85,41 +86,26 @@ Name: "password", Func: cmdPassword, }) } -func fetchStartupConfiguration(fs *flag.FlagSet) (cfg *meta.Meta) { +func readConfig(fs *flag.FlagSet) (cfg *meta.Meta) { + var configFile string if configFlag := fs.Lookup("c"); configFlag != nil { - if filename := configFlag.Value.String(); filename != "" { - content, err := readConfiguration(filename) - return createConfiguration(content, err) - } - } - content, err := searchAndReadConfiguration() - return createConfiguration(content, err) -} - -func createConfiguration(content []byte, err error) *meta.Meta { + configFile = configFlag.Value.String() + } else { + configFile = defConfigfile + } + content, err := os.ReadFile(configFile) if err != nil { return meta.New(id.Invalid) } return meta.NewFromInput(id.Invalid, input.NewInput(content)) } -func readConfiguration(filename string) ([]byte, error) { return os.ReadFile(filename) } - -func searchAndReadConfiguration() ([]byte, error) { - for _, filename := range []string{"zettelstore.cfg", "zsconfig.txt", "zscfg.txt", "_zscfg"} { - if content, err := readConfiguration(filename); err == nil { - return content, nil - } - } - return readConfiguration(".zscfg") -} - func getConfig(fs *flag.FlagSet) *meta.Meta { - cfg := fetchStartupConfiguration(fs) + cfg := readConfig(fs) fs.Visit(func(flg *flag.Flag) { switch flg.Name { case "p": if portStr, err := parsePort(flg.Value.String()); err == nil { cfg.Set(keyListenAddr, net.JoinHostPort("127.0.0.1", portStr)) @@ -172,11 +158,10 @@ keyDebug = "debug-mode" keyDefaultDirBoxType = "default-dir-box-type" keyInsecureCookie = "insecure-cookie" keyListenAddr = "listen-addr" keyLogLevel = "log-level" - keyMaxRequestSize = "max-request-size" keyOwner = "owner" keyPersistentCookie = "persistent-cookie" keyBoxOneURI = kernel.BoxURIs + "1" keyReadOnly = "read-only-mode" keyTokenLifetimeHTML = "token-lifetime-html" @@ -222,13 +207,10 @@ ok, kernel.WebService, kernel.WebListenAddress, cfg.GetDefault(keyListenAddr, "127.0.0.1:23123")) ok = setConfigValue(ok, kernel.WebService, kernel.WebURLPrefix, cfg.GetDefault(keyURLPrefix, "/")) ok = setConfigValue(ok, kernel.WebService, kernel.WebSecureCookie, !cfg.GetBool(keyInsecureCookie)) ok = setConfigValue(ok, kernel.WebService, kernel.WebPersistentCookie, cfg.GetBool(keyPersistentCookie)) - if val, found := cfg.Get(keyMaxRequestSize); found { - ok = setConfigValue(ok, kernel.WebService, kernel.WebMaxRequestSize, val) - } ok = setConfigValue( ok, kernel.WebService, kernel.WebTokenLifetimeAPI, cfg.GetDefault(keyTokenLifetimeAPI, "")) ok = setConfigValue( ok, kernel.WebService, kernel.WebTokenLifetimeHTML, cfg.GetDefault(keyTokenLifetimeHTML, "")) @@ -279,19 +261,13 @@ } } else { createManager = func([]*url.URL, auth.Manager, config.Config) (box.Manager, error) { return nil, nil } } - secret := cfg.GetDefault("secret", "") - if len(secret) < 16 && cfg.GetDefault(keyOwner, "") != "" { - fmt.Fprintf(os.Stderr, "secret must have at least length 16 when authentication is enabled, but is %q\n", secret) - return 2 - } - kern.SetCreators( func(readonly bool, owner id.Zid) (auth.Manager, error) { - return impl.New(readonly, owner, secret), nil + return impl.New(readonly, owner, cfg.GetDefault("secret", "")), nil }, createManager, func(srv server.Server, plMgr box.Manager, authMgr auth.Manager, rtConfig config.Config) error { setupRouting(srv, plMgr, authMgr, rtConfig) return nil @@ -311,29 +287,25 @@ } // 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() int { - if _, err := searchAndReadConfiguration(); err == nil { - return executeCommand(strRunSimple) - } dir := "./zettel" if err := os.MkdirAll(dir, 0750); err != nil { fmt.Fprintf(os.Stderr, "Unable to create zettel directory %q (%s)\n", dir, err) return 1 } - return executeCommand(strRunSimple, "-d", dir) + return executeCommand("run-simple", "-d", dir) } var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`") var memprofile = flag.String("memprofile", "", "write memory profile to `file`") // Main is the real entrypoint of the zettelstore. func Main(progName, buildVersion string) int { - fullVersion := retrieveFullVersion(buildVersion) kernel.Main.SetConfig(kernel.CoreService, kernel.CoreProgname, progName) - kernel.Main.SetConfig(kernel.CoreService, kernel.CoreVersion, fullVersion) + kernel.Main.SetConfig(kernel.CoreService, kernel.CoreVersion, buildVersion) flag.Parse() if *cpuprofile != "" || *memprofile != "" { if *cpuprofile != "" { kernel.Main.StartProfiling(kernel.ProfileCPU, *cpuprofile) } else { @@ -345,27 +317,5 @@ if len(args) == 0 { return runSimple() } return executeCommand(args[0], args[1:]...) } - -func retrieveFullVersion(version string) string { - info, ok := debug.ReadBuildInfo() - if !ok { - return version - } - var revision, dirty string - for _, kv := range info.Settings { - switch kv.Key { - case "vcs.revision": - revision = "+" + kv.Value - if len(revision) > 11 { - revision = revision[:11] - } - case "vcs.modified": - if kv.Value == "true" { - dirty = "-dirty" - } - } - } - return version + revision + dirty -} Index: cmd/register.go ================================================================== --- cmd/register.go +++ cmd/register.go @@ -17,16 +17,17 @@ _ "zettelstore.de/z/box/constbox" // Allow to use global internal box. _ "zettelstore.de/z/box/dirbox" // Allow to use directory box. _ "zettelstore.de/z/box/filebox" // Allow to use file box. _ "zettelstore.de/z/box/membox" // Allow to use in-memory box. _ "zettelstore.de/z/encoder/htmlenc" // Allow to use HTML encoder. - _ "zettelstore.de/z/encoder/sexprenc" // Allow to use sexpr encoder. + _ "zettelstore.de/z/encoder/nativeenc" // Allow to use native encoder. _ "zettelstore.de/z/encoder/textenc" // Allow to use text encoder. _ "zettelstore.de/z/encoder/zjsonenc" // Allow to use ZJSON encoder. _ "zettelstore.de/z/encoder/zmkenc" // Allow to use zmk encoder. _ "zettelstore.de/z/kernel/impl" // Allow kernel implementation to create itself _ "zettelstore.de/z/parser/blob" // Allow to use BLOB parser. + _ "zettelstore.de/z/parser/draw" // Allow to use draw parser. _ "zettelstore.de/z/parser/markdown" // Allow to use markdown parser. _ "zettelstore.de/z/parser/none" // Allow to use none parser. _ "zettelstore.de/z/parser/plain" // Allow to use plain parser. _ "zettelstore.de/z/parser/zettelmark" // Allow to use zettelmark parser. ) Index: config/config.go ================================================================== --- config/config.go +++ config/config.go @@ -1,9 +1,9 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2020-2022 Detlef Stern +// Copyright (c) 2020-2021 Detlef Stern // -// This file is part of Zettelstore. +// This file is part of zettelstore. // // Zettelstore is licensed under the latest version of the EUPL (European Union // Public License). Please see file LICENSE.txt for your rights and obligations // under this license. //----------------------------------------------------------------------------- @@ -21,19 +21,31 @@ type Config interface { AuthConfig // AddDefaultValues enriches the given meta data with its default values. AddDefaultValues(m *meta.Meta) *meta.Meta + + // GetDefaultTitle returns the current value of the "default-title" key. + GetDefaultTitle() string + + // GetDefaultRole returns the current value of the "default-role" key. + GetDefaultRole() string + + // GetDefaultSyntax returns the current value of the "default-syntax" key. + GetDefaultSyntax() string // GetDefaultLang returns the current value of the "default-lang" key. GetDefaultLang() string // GetSiteName returns the current value of the "site-name" key. GetSiteName() string // GetHomeZettel returns the value of the "home-zettel" key. GetHomeZettel() id.Zid + + // GetDefaultVisibility returns the default value for zettel visibility. + GetDefaultVisibility() meta.Visibility // GetMaxTransclusions return the maximum number of indirect transclusions. GetMaxTransclusions() int // GetYAMLHeader returns the current value of the "yaml-header" key. @@ -59,14 +71,44 @@ GetExpertMode() bool // GetVisibility returns the visibility value of the metadata. GetVisibility(m *meta.Meta) meta.Visibility } + +// GetTitle returns the value of the "title" key of the given meta. If there +// is no such value, GetDefaultTitle is returned. +func GetTitle(m *meta.Meta, cfg Config) string { + if val, ok := m.Get(api.KeyTitle); ok { + return val + } + if cfg != nil { + return cfg.GetDefaultTitle() + } + return "Untitled" +} + +// GetRole returns the value of the "role" key of the given meta. If there +// is no such value, GetDefaultRole is returned. +func GetRole(m *meta.Meta, cfg Config) string { + if val, ok := m.Get(api.KeyRole); ok { + return val + } + return cfg.GetDefaultRole() +} + +// GetSyntax returns the value of the "syntax" key of the given meta. If there +// is no such value, GetDefaultSyntax is returned. +func GetSyntax(m *meta.Meta, cfg Config) string { + if val, ok := m.Get(api.KeySyntax); ok { + return val + } + return cfg.GetDefaultSyntax() +} // GetLang returns the value of the "lang" key of the given meta. If there is // no such value, GetDefaultLang is returned. func GetLang(m *meta.Meta, cfg Config) string { if val, ok := m.Get(api.KeyLang); ok { return val } return cfg.GetDefaultLang() } Index: docs/manual/00001003305000.zettel ================================================================== --- docs/manual/00001003305000.zettel +++ docs/manual/00001003305000.zettel @@ -40,11 +40,11 @@ On the negative side, you will not be notified when you enter the wrong data in the Task scheduler and Zettelstore fails to start. This can be mitigated by first using the command line prompt to start Zettelstore with the appropriate options. Once everything works, you can register Zettelstore to be automatically started by the task scheduler. There you should make sure that you have followed the first steps as described on the [[parent page|00001003300000]]. -To start the Task scheduler management console, press the Windows logo key and the key ''R'', type ''taskschd.msc''. +To sart the Task scheduler management console, press the Windows logo key and the key ''R'', type ''taskschd.msc''. Select the OK button. {{00001003305102}} This will start the ""Task Scheduler"". Index: docs/manual/00001003310000.zettel ================================================================== --- docs/manual/00001003310000.zettel +++ docs/manual/00001003310000.zettel @@ -40,11 +40,11 @@ If you want to execute Zettelstore automatically and less visible, and if you know a little bit about working in the terminal application, then you could try to run Zettelstore under the control of the [[Launchd system|https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/Introduction.html]]. First, you have to create a description for ""Launchd"". This is a text file named ''zettelstore.plist'' with the following content. -It assumes that you have copied the Zettelstore executable in a local folder called ''~/bin'' and have created a file for [[startup configuration|00001004010000]] called ''zettelstore.cfg'', which is placed in the same folder[^If you are not using a configuration file, just remove the lines ``-c`` and ``/Users/USERNAME/bin/zettelstore.cfg``.]: +It assumes that you have copied the Zettelstore executable in a local folder called ''~/bin'' and have created a file for [[startup configuration|00001004010000]] called ''zettelstore.cfg'', which is placed in the same folder[^If you are not using a confguration file, just remove the lines ``-c`` and ``/Users/USERNAME/bin/zettelstore.cfg``.]: ``` Index: docs/manual/00001004010000.zettel ================================================================== --- docs/manual/00001004010000.zettel +++ docs/manual/00001004010000.zettel @@ -1,11 +1,11 @@ id: 00001004010000 title: Zettelstore startup configuration role: manual tags: #configuration #manual #zettelstore syntax: zmk -modified: 20220419193611 +modified: 20220304115353 The configuration file, as specified by the ''-c CONFIGFILE'' [[command line option|00001004051000]], allows you to specify some startup 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 stored. An attacker that is able to change the owner can do anything. @@ -59,22 +59,14 @@ Can be changed at runtime, even for specific internal services, with the ''log-level'' command of the [[administrator console|00001004101000#log-level]]. Default: ""info"". When you are familiar to operate the Zettelstore, you might set the level to ""warn"" or ""error"" to receive less noisy messages from the Zettelstore. -; [!max-request-size|''max-request-size''] -: Limits the maximum byte size of a web request body to prevent clients from accidentally or maliciously sending a large request and wasting server resources. - The minimum value is 1024. - - Default: 16777216 (16 MiB). ; [!owner|''owner''] : [[Identifier|00001006050000]] of a zettel that contains data about the owner of the Zettelstore. The owner has full authorization for the Zettelstore. Only if owner is set to some value, user [[authentication|00001010000000]] is enabled. - - Ensure that key [[''secret''|#secret]] is set to a value of at least 16 bytes. - Otherwise the Zettelstore will not start for security reasons. ; [!persistent-cookie|''persistent-cookie''] : A [[boolean value|00001006030500]] to make the access cookie persistent. This is helpful if you access the Zettelstore via a mobile device. On these devices, the operating system is free to stop the web browser and to remove temporary cookies. Therefore, an authenticated user will be logged off. @@ -86,15 +78,10 @@ ; [!read-only-mode|''read-only-mode''] : Puts the Zettelstore service into a read-only mode, if set to a [[true value|00001006030500]]. No changes are possible. Default: ""false"". -; [!secret|''secret''] -: A string value to make the communication with external clients strong enough so that sessions of the [[web user interface|00001014000000]] or [[API access token|00001010040700]] cannot be modified by some external unfriendly party. - The string must have a length of at least 16 bytes. - - It is only needed to set this value, if [[authentication is enabled|00001010040100]] by setting key [[''owner''|#owner]] to some user identification. ; [!token-lifetime-api|''token-lifetime-api''], [!token-lifetime-html|''token-lifetime-html''] : Define lifetime of access tokens in minutes. Values are only valid if authentication is enabled, i.e. key ''owner'' is set. ''token-lifetime-api'' is for accessing Zettelstore via its [[API|00001012000000]]. Index: docs/manual/00001004011400.zettel ================================================================== --- docs/manual/00001004011400.zettel +++ docs/manual/00001004011400.zettel @@ -1,11 +1,11 @@ id: 00001004011400 title: Configure file directory boxes role: manual tags: #configuration #manual #zettelstore syntax: zmk -modified: 20220724200512 +modified: 20220307121244 Under certain circumstances, it is preferable to further configure a file directory box. This is done by appending query parameters after the base box URI ''dir:\//DIR''. The following parameters are supported: @@ -16,11 +16,11 @@ |readonly|Allow only operations that do not create or change zettel|n/a === Type On some operating systems, Zettelstore tries to detect changes to zettel files outside of Zettelstore's control[^This includes Linux, Windows, and macOS.]. On other operating systems, this may be not possible, due to technical limitations. -Automatic detection of external changes is also not possible, if zettel files are put on an external service, such as a file server accessed via SMB/CIFS or NFS. +Automatic detection of external changes is also not possible, if zettel files are put on an external service, such as a file server accessed via SMD/CIFS or NFS. To cope with this uncertainty, Zettelstore provides various internal implementations of a directory box. The default values should match the needs of different users, as explained in the [[installation part|00001003000000]] of this manual. The following values are supported: Index: docs/manual/00001004020000.zettel ================================================================== --- docs/manual/00001004020000.zettel +++ docs/manual/00001004020000.zettel @@ -1,11 +1,11 @@ id: 00001004020000 title: Configure the running Zettelstore role: manual tags: #configuration #manual #zettelstore syntax: zmk -modified: 20220628110920 +modified: 20220304114412 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: @@ -23,10 +23,21 @@ Use values according to the language definition of [[RFC-5646|https://tools.ietf.org/html/rfc5646]]. ; [!default-license|''default-license''] : License value to be used when rendering content. Can be overwritten in a zettel with [[meta key|00001006020000]] ''license''. Default: (the empty string). +; [!default-role|''default-role''] +: Role to be used, if a zettel specifies no ''role'' [[meta key|00001006020000]]. + Default: ""zettel"". +; [!default-syntax|''default-syntax''] +: Syntax to be used, if a zettel specifies no ''syntax'' [[meta key|00001006020000]]. + Default: ""zmk"" (""[[Zettelmarkup|00001007000000]]""). +; [!default-title|''default-title''] +: Title to be used, if a zettel specifies no ''title'' [[meta key|00001006020000]]. + Default: ""Untitled"". + + You can use all [[inline-structured elements|00001007040000]] of Zettelmarkup. ; [!default-visibility|''default-visibility''] : Visibility to be used, if zettel does not specify a value for the [[''visibility''|00001006020000#visibility]] metadata key. Default: ""login"". ; [!expert-mode|''expert-mode''] : If set to a [[boolean true value|00001006030500]], all zettel with [[visibility ""expert""|00001010070200]] will be shown (to the owner, if [[authentication is enabled|00001010040100]]; to all, otherwise). Index: docs/manual/00001004051000.zettel ================================================================== --- docs/manual/00001004051000.zettel +++ docs/manual/00001004051000.zettel @@ -1,11 +1,11 @@ id: 00001004051000 title: The ''run'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk -modified: 20220724162050 +modified: 20220214175947 === ``zettelstore run`` This starts the web service. ``` @@ -17,11 +17,11 @@ See the explanation of [[''admin-port''|00001004010000#admin-port]] for more details. ; [!c|''-c CONFIGFILE''] : Specifies ''CONFIGFILE'' as a file, where [[startup configuration data|00001004010000]] is read. It is ignored, when the given file is not available, nor readable. - Default: tries to read the following files in the ""current directory"": ''zettelstore.cfg'', ''zsconfig.txt'', ''zscfg.txt'', ''_zscfg'', and ''.zscfg''. + Default: ''./.zscfg''. (''.\\.zscfg'' on Windows)), where ''.'' denotes the ""current directory"". ; [!d|''-d DIR''] : Specifies ''DIR'' as the directory that contains all zettel. Default is ''./zettel'' (''.\\zettel'' on Windows), where ''.'' denotes the ""current directory"". ; [!debug|''-debug''] Index: docs/manual/00001004051100.zettel ================================================================== --- docs/manual/00001004051100.zettel +++ docs/manual/00001004051100.zettel @@ -1,21 +1,17 @@ id: 00001004051100 title: The ''run-simple'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk -modified: 20220724162843 +modified: 20220214180253 === ``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]]. -First, this sub-command checks if it can read a [[Zettelstore startup configuration|00001004010000]] file by trying the [[default values|00001004051000#c]]. -If this is the case, ''run-simple'' just continues as the [[''run'' sub-command|00001004051000]], but ignores any command line options (including ''-d DIR'').[^This allows a [[curious user|00001003000000]] to become an intermediate user.] - - -If no startup configuration was found, the sub-command allows only to specify a zettel directory. +It allows only to specify a zettel directory. The directory will be created automatically, if it does not exist. This is a difference to the ''run'' sub-command, where the directory must exists. In contrast to the ''run'' sub-command, other command line parameter are not allowed. ``` Index: docs/manual/00001004051200.zettel ================================================================== --- docs/manual/00001004051200.zettel +++ docs/manual/00001004051200.zettel @@ -1,11 +1,11 @@ id: 00001004051200 title: The ''file'' sub-command role: manual tags: #command #configuration #manual #zettelstore syntax: zmk -modified: 20220423131738 +modified: 20220209114650 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]] @@ -13,11 +13,11 @@ ; ''-t FORMAT'' : Specifies the output format. Supported values are: [[''html''|00001012920510]] (default), - [[''sexpr''|00001012920516]], + [[''native''|00001012920513]], [[''text''|00001012920519]], [[''zjson''|00001012920503]], and [[''zmk''|00001012920522]]. ; ''file-1'' : Specifies the file name, where at least metadata is read. Index: docs/manual/00001004100000.zettel ================================================================== --- docs/manual/00001004100000.zettel +++ docs/manual/00001004100000.zettel @@ -16,10 +16,10 @@ Therefore, you can also use tools like [[netcat|https://nc110.sourceforge.io/]], [[socat|http://www.dest-unreach.org/socat/]], etc. After connecting to the administrator console, there is no further authentication. It is not needed because you must be logged in on the same computer where Zettelstore is running. You cannot connect to the administrator console if you are on a different computer. -Of course, on multi-user systems with encrusted users, you should not enable the administrator console. +Of course, on multi-user systems with untrusted users, you should not enable the administrator console. * Enable via [[command line|00001004051000#a]] * Enable via [[configuration file|00001004010000#admin-port]] * [[List of supported commands|00001004101000]] Index: docs/manual/00001005000000.zettel ================================================================== --- docs/manual/00001005000000.zettel +++ docs/manual/00001005000000.zettel @@ -44,11 +44,11 @@ Other filename extensions are used to determine the ""syntax"" of a zettel. This allows to use other content within the Zettelstore, e.g. images or HTML templates. For example, you want to store an important figure in the Zettelstore that is encoded as a ''.png'' file. Since each zettel contains some metadata, e.g. the title of the figure, the question arises where these data should be stores. -The solution is a meta-file with the same zettel identifier, but without a filename extension. +The solution is a metafile with the same zettel identifier, but without a filename extension. Zettelstore recognizes this situation and reads in both files for the one zettel containing the figure. 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 put in the same file, separated by an empty line or a line with three dashes (""''-\-\-''"", also known as ""YAML separator""). @@ -63,11 +63,11 @@ One reason for this is to allow you to modify these zettel to adapt Zettelstore to your needs and visual preferences. Where are these zettel stored? They are stored within the Zettelstore software itself, because one [[design goal|00001002000000]] was to have just one executable file to use Zettelstore. -But data stored within an executable program cannot be changed later[^Well, it can, but it is a very bad idea to allow this. Mostly for security reasons.]. +But data stored within an executable programm cannot be changed later[^Well, it can, but it is a very bad idea to allow this. Mostly for security reasons.]. To allow changing predefined zettel, both the file store and the internal zettel store are internally chained together. If you change a zettel, it will be always stored as a file. If a zettel is requested, Zettelstore will first try to read that zettel from a file. If such a file was not found, the internal zettel store is searched secondly. Index: docs/manual/00001005090000.zettel ================================================================== --- docs/manual/00001005090000.zettel +++ docs/manual/00001005090000.zettel @@ -1,11 +1,11 @@ id: 00001005090000 title: List of predefined zettel role: manual tags: #manual #reference #zettelstore syntax: zmk -modified: 20220321192401 +modified: 20211229000646 The following table lists all predefined zettel with their purpose. |= Identifier :|= Title | Purpose | [[00000000000001]] | Zettelstore Version | Contains the version string of the running Zettelstore @@ -22,23 +22,22 @@ | [[00000000000100]] | Zettelstore Runtime Configuration | Allows to [[configure Zettelstore at runtime|00001004020000]] | [[00000000010100]] | Zettelstore Base HTML Template | Contains the general layout of the HTML view | [[00000000010200]] | Zettelstore Login Form HTML Template | Layout of the login form, when authentication is [[enabled|00001010040100]] | [[00000000010300]] | Zettelstore List Meta HTML Template | Used when displaying a list of zettel | [[00000000010401]] | Zettelstore Detail HTML Template | Layout for the HTML detail view of one zettel -| [[00000000010402]] | Zettelstore Info HTML Template | Layout for the information view of a specific zettel +| [[00000000010402]] | Zettelstore Info HTML Templöate | Layout for the information view of a specific zettel | [[00000000010403]] | Zettelstore Form HTML Template | Form that is used to create a new or to change an existing zettel that contains text | [[00000000010404]] | Zettelstore Rename Form HTML Template | View that is displayed to change the [[zettel identifier|00001006050000]] | [[00000000010405]] | Zettelstore Delete HTML Template | View to confirm the deletion of a zettel | [[00000000010500]] | Zettelstore List Roles HTML Template | Layout for listing all roles | [[00000000010600]] | Zettelstore List Tags HTML Template | Layout of tags lists | [[00000000020001]] | Zettelstore Base CSS | System-defined CSS file that is included by the [[Base HTML Template|00000000010100]] | [[00000000025001]] | Zettelstore User CSS | User-defined CSS file that is included by the [[Base HTML Template|00000000010100]] -| [[00000000029000]] | Zettelstore Role to CSS Map | Maps [[role|00001006020000#role]] to a zettel identifier that is included by the [[Base HTML Template|00000000010100]] as an CSS file | [[00000000040001]] | Generic Emoji | Image that is shown if [[original image reference|00001007040322]] is invalid | [[00000000090000]] | New Menu | Contains items that should contain in the zettel template menu | [[00000000090001]] | New Zettel | Template for a new zettel with role ""[[zettel|00001006020100]]"" | [[00000000090002]] | New User | Template for a new [[user zettel|00001010040200]] | [[00010000000000]] | Home | Default home zettel, contains some welcome information If a zettel is not linked, it is not accessible for the current user. **Important:** All identifier may change until a stable version of the software is released. Index: docs/manual/00001006000000.zettel ================================================================== --- docs/manual/00001006000000.zettel +++ docs/manual/00001006000000.zettel @@ -1,11 +1,11 @@ id: 00001006000000 title: Layout of a Zettel role: manual tags: #design #manual #zettelstore syntax: zmk -modified: 20220724165931 +modified: 20220113185522 A zettel consists of two parts: the metadata and the zettel content. Metadata gives some information mostly about the zettel content, how it should be interpreted, how it is sorted within Zettelstore. The zettel content is, well, the actual content. In many cases, the content is in plain text form. @@ -23,26 +23,7 @@ Zettelstore contains some predefined parsers that interpret the zettel content to the syntax of the zettel. This includes markup languages, like [[Zettelmarkup|00001007000000]] and [[CommonMark|00001008010500]]. Other text formats are also supported, like CSS and HTML templates. Plain text content is always Unicode, encoded as UTF-8. Other character encodings are not supported and will never be[^This is not a real problem, since every modern software should support UTF-8 as an encoding.]. -There is support for a graphical format with a text representation: SVG. +There is support for a graphical format with a text represenation: SVG. And there is support for some binary image formats, like GIF, PNG, and JPEG. - -=== Plain, parsed, and evaluated zettel -Zettelstore may present your zettel in various forms. -One way is to present the zettel as it was read by Zettelstore. -This is called ""[[plain zettel|00001003000000#plain]]"", typically retrieved with the [[endpoint|00001012920000]] ''/z/{ID}''. - -The second way is to present the zettel as it was recognized by Zettelstore. -This is called ""[[parsed zettel|00001012053600]]"", typically retrieved with the [[endpoint|00001012920000]] ''/p/{ID}''. -Such a zettel was read and analyzed. -It can be presented in various [[encodings|00001012920500]].[^The [[zmk encoding|00001012920522]] allows you to compare the plain, the parsed, and the evaluated form of a zettel.] - -However, a zettel such as this one you are currently reading, is a ""[[evaluated zettel|00001012053500]]"", typically retrieved with the [[endpoint|00001012920000]] ''/v/{ID}''. -The biggest difference to a parsed zettel is the inclusion of [[block transclusions|00001007031100]] or [[inline transclusions|00001007040324]] for an evaluated zettel. -It can also be presented in various encoding, including the ""zmk"" encoding. -Evaluations also applies to metadata of a zettel, if appropriate. - -Please note, that searching for content is based on parsed zettel. -Transcluded content will only be found in transcluded zettel, but not in the zettel that transcluded the content. -However, you will easily pick up that zettel by follow the [[backward|00001006020000#backward]] metadata key of the transcluded zettel. Index: docs/manual/00001006020000.zettel ================================================================== --- docs/manual/00001006020000.zettel +++ docs/manual/00001006020000.zettel @@ -1,11 +1,11 @@ id: 00001006020000 title: Supported Metadata Keys role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk -modified: 20220628111132 +modified: 20220218130146 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]]. @@ -12,11 +12,11 @@ ; [!all-tags|''all-tags''] : A property (a computed values that is not stored) that contains both the value of [[''tags''|#tags]] together with all [[tags|00001007040000#tag]] that are specified within the content. ; [!back|''back''] : Is a property that contains the identifier of all zettel that reference the zettel of this metadata, that are not referenced by this zettel. - Basically, it is the value of [[''backward''|#backward]], but without any zettel identifier that is contained in [[''forward''|#forward]]. + Basically, it is the value of [[''backward''|#bachward]], but without any zettel identifier that is contained in [[''forward''|#forward]]. ; [!backward|''backward''] : Is a property that contains the identifier of all zettel that reference the zettel of this metadata. References within invertible values are not included here, e.g. [[''precursor''|#precursor]]. ; [!box-number|''box-number''] : Is a computed value and contains the number of the box where the zettel was found. @@ -70,21 +70,21 @@ The interpretation of [[supported values|00001006020400]] for this key depends, whether authentication is [[enabled|00001010040100]] or not. ; [!role|''role''] : Defines the role of the zettel. Can be used for selecting zettel. See [[supported zettel roles|00001006020100]]. - If not given, it is ignored. + 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 it is not given, it defaults to ''plain''. + 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. Each Tag must begin with the number sign character (""''#''"", U+0023). ; [!title|''title''] : Specifies the title of the zettel. - If not given, the value of [[''id''|#id]] will be used. + If not given, the value ''default-title'' from the [[configuration zettel|00001004020000#default-title]] will be used. You can use all [[inline-structured elements|00001007040000]] of Zettelmarkup. ; [!url|''url''] : Defines an URL / URI for this zettel that possibly references external material. One use case is to specify the document that the current zettel comments on. Index: docs/manual/00001006020100.zettel ================================================================== --- docs/manual/00001006020100.zettel +++ docs/manual/00001006020100.zettel @@ -1,15 +1,16 @@ id: 00001006020100 title: Supported Zettel Roles role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk -modified: 20220623183234 +modified: 20220214174553 The [[''role'' key|00001006020000#role]] defines what kind of zettel you are writing. You are free to define your own roles. -It is allowed to set an empty value or to omit the role. + +The role ''zettel'' is predefined as the default role, but you can [[change this|00001004020000#default-role]]. Some roles are defined for technical reasons: ; [!configuration|''configuration''] : A zettel that contains some configuration data for the Zettelstore. Index: docs/manual/00001006036000.zettel ================================================================== --- docs/manual/00001006036000.zettel +++ docs/manual/00001006036000.zettel @@ -1,19 +1,19 @@ id: 00001006036000 title: WordSet Key Type role: manual tags: #manual #meta #reference #zettel #zettelstore syntax: zmk -modified: 20220724201056 +modified: 20220111103714 Values of this type denote a (sorted) set of [[words|00001006035500]]. A set is different to a list, as no duplicate values are allowed. === Allowed values Must be a sequence of at least one word, separated by space characters. === Match operator -A value matches a WordSet value, if the first value is equal to one of the word values in the word set. +A value matches an wordset value, if the first value is equal to one of the word values in the word set. === Sorting Sorting is done by comparing the [[String|00001006033500]] values. Index: docs/manual/00001006055000.zettel ================================================================== --- docs/manual/00001006055000.zettel +++ docs/manual/00001006055000.zettel @@ -1,11 +1,11 @@ id: 00001006055000 title: Reserved zettel identifier role: manual tags: #design #manual #zettelstore syntax: zmk -modified: 20220311111751 +modified: 20211124182600 [[Zettel identifier|00001006050000]] are typically created by examine the current date and time. By renaming a zettel, you are able to provide any sequence of 14 digits. If no other zettel has the same identifier, you are allowed to rename a zettel. @@ -39,6 +39,5 @@ This list may change in the future. ==== External Applications |= From | To | Description | 00009000001000 | 00009000001999 | [[Zettel Presenter|https://zettelstore.de/contrib]], an application to display zettel as a HTML-based slideshow -| 00009000002000 | 00009000002999 | [[Zettel Blog|https://zettelstore.de/contrib]], an application to collect and transform zettel into a blog Index: docs/manual/00001007000000.zettel ================================================================== --- docs/manual/00001007000000.zettel +++ docs/manual/00001007000000.zettel @@ -6,23 +6,23 @@ modified: 20220113185501 Zettelmarkup is a rich plain-text based markup language for writing zettel content. Besides the zettel content, Zettelmarkup is also used for specifying the title of a zettel, regardless of the syntax of a zettel. -Zettelmarkup supports the longevity of stored notes by providing a syntax that any person can easily read, as well as a computer. -Zettelmarkup can be much easier parsed / consumed by a software compared to other markup languages. +Zettelmark supports the longevity of stored notes by providing a syntax that any person can easily read, as well as a computer. +Zettelmark can be much easier parsed / consumed by a software compared to other markup languages. Writing a parser for [[Markdown|https://daringfireball.net/projects/markdown/syntax]] is quite challenging. [[CommonMark|00001008010500]] is an attempt to make it simpler by providing a comprehensive specification, combined with an extra chapter to give hints for the implementation. -Zettelmarkup follows some simple principles that anybody who knows to ho write software should be able understand to create an implementation. +Zettelmark follows some simple principles that anybody who knows to ho write software should be able understand to create an implementation. Zettelmarkup is a markup language on its own. -This is in contrast to Markdown, which is basically a super-set of HTML. +This is in contrast to Markdown, which is basically a superset of HTML. While HTML is a markup language that will probably last for a long time, it cannot be easily translated to other formats, such as PDF, JSON, or LaTeX. Additionally, it is allowed to embed other languages into HTML, such as CSS or even JavaScript. This could create problems with longevity as well as security problems. -Zettelmarkup is a rich markup language, but it focuses on relatively short zettel content. +Zettelmarkup is a rich markup language, but it focusses on relatively short zettel content. It allows embedding other content, simple tables, quotations, description lists, and images. It provides a broad range of inline formatting, including __emphasized__, **strong**, ~~deleted~~{-} and >>inserted>> text. Footnotes[^like this] are supported, links to other zettel and to external material, as well as citation keys. Zettelmarkup might be seen as a proprietary markup language. Index: docs/manual/00001007010000.zettel ================================================================== --- docs/manual/00001007010000.zettel +++ docs/manual/00001007010000.zettel @@ -31,11 +31,11 @@ These elements begin with one opening square bracket (""``[``""), use a character for specifying the kind of the inline, typically allow to specify some content, and end with one closing square bracket (""``]``""). One inline element that does not begin with two characters is the ""entity"". It allows to specify any Unicode character. The specification of that character is put between an ampersand character and a semicolon: ``&...;``{=zmk}. -For example, an ""n-dash"" could also be specified as ``–``{==zmk}. +For exmple, an ""n-dash"" could also be specified as ``–``{==zmk}. The backslash character (""``\\``"") possibly gives the next character a special meaning. This allows to resolve some left ambiguities. For example, a list of depth 2 will begin a line with ``** Item 2.2``{=zmk}. An inline element to strongly emphasize some text begin with a space will be specified as ``** Text**``{=zmk}. Index: docs/manual/00001007030000.zettel ================================================================== --- docs/manual/00001007030000.zettel +++ docs/manual/00001007030000.zettel @@ -1,11 +1,11 @@ id: 00001007030000 title: Zettelmarkup: Block-Structured Elements role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk -modified: 20220311181036 +modified: 20220201133655 Every markup for blocks-structured elements (""blocks"") begins at the very first position of a line. There are five kinds of blocks: lists, one-line blocks, line-range blocks, tables, and paragraphs. @@ -37,12 +37,10 @@ * [[Verbatim blocks|00001007030500]] do not interpret their content, * [[Quotation blocks|00001007030600]] specify a block-length quotations, * [[Verse blocks|00001007030700]] allow to enter poetry, lyrics and similar text, where line endings are important, * [[Region blocks|00001007030800]] just mark regions, e.g. for common formatting, * [[Comment blocks|00001007030900]] allow to enter text that will be ignored when rendered. -* [[Evaluation blocks|00001007031300]] specify some content to be evaluated by either Zettelstore or external software. -* [[Math-mode blocks|00001007031400]] can be used to enter mathematical formulas / equations. * [[Inline-Zettel blocks|00001007031200]] provide a mechanism to specify zettel content with a new syntax without creating a new zettel. === Tables Similar to lists are tables not specified explicitly. Index: docs/manual/00001007030200.zettel ================================================================== --- docs/manual/00001007030200.zettel +++ docs/manual/00001007030200.zettel @@ -89,11 +89,11 @@ * C ::: Please note that two lists cannot be separated by an empty line. -Instead you should put a horizontal rule (""thematic break"") between them. +Instead you should put a horizonal rule (""thematic break"") between them. You could also use a [[mark element|00001007040350]] or a hard line break to separate the two lists: ```zmk # One # Two [!sep] Index: docs/manual/00001007030600.zettel ================================================================== --- docs/manual/00001007030600.zettel +++ docs/manual/00001007030600.zettel @@ -5,11 +5,11 @@ syntax: zmk modified: 20220218131806 A simple way to enter a quotation is to use the [[quotation list|00001007030200]]. A quotation list loosely follows the convention of quoting text within emails. -However, if you want to attribute the quotation to someone, a quotation block is more appropriately. +However, if you want to attribute the quotation to seomeone, a quotation block is more appropriately. This kind of line-range block begins with at least three less-than characters (""''<''"", U+003C) at the first position of a line. You can add some [[attributes|00001007050000]] on the beginning line of a quotation block, following the initiating characters. The quotation does not support the default attribute, nor the generic attribute. Attributes are interpreted on HTML rendering. Index: docs/manual/00001007030800.zettel ================================================================== --- docs/manual/00001007030800.zettel +++ docs/manual/00001007030800.zettel @@ -1,11 +1,11 @@ id: 00001007030800 title: Zettelmarkup: Region Blocks role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk -modified: 20220323190829 +modified: 20220218131131 Region blocks does not directly have a visual representation. They just group a range of lines. You can use region blocks to enter [[attributes|00001007050000]] that apply only to this range of lines. One example is to enter a multi-line warning that should be visible. @@ -12,11 +12,10 @@ This kind of line-range block begins with at least three colon characters (""'':''"", U+003A) at the first position of a line[^Since a [[description text|00001007030100]] only use exactly one colon character at the first position of a line, there is no possible ambiguity between these elements.]. You can add some [[attributes|00001007050000]] on the beginning line of a region block, following the initiating characters. The region block does not support the default attribute, but it supports the generic attribute. Some generic attributes, like ``=note``, ``=warning`` will be rendered special. -All other generic attributes are used as a CSS class definition. Attributes are interpreted on HTML rendering. Any other character in this line will be ignored. Text following the beginning line will be interpreted, until a line begins with at least the same number of the same characters given at the beginning line. This allows to enter a region block within a region block. @@ -67,18 +66,5 @@ * note * tip * important * caution * warning - -All other generic attribute values are rendered as a CSS class: -```zmk -:::abc -def -::: -``` -is rendered as -::::example -:::abc -def -::: -:::: Index: docs/manual/00001007030900.zettel ================================================================== --- docs/manual/00001007030900.zettel +++ docs/manual/00001007030900.zettel @@ -11,11 +11,11 @@ Comment blocks begin with at least three percent sign characters (""''%''"", U+0025) at the first position of a line. You can add some [[attributes|00001007050000]] on the beginning line of a comment block, following the initiating characters. The comment block supports the default attribute: when given, the text will be rendered, e.g. as an HTML comment. When rendered to JSON, the comment block will not be ignored but it will output some JSON text. -Same for other renderer. +Same for other renderers. Any other character in this line will be ignored Text following the beginning line will not be interpreted, until a line begins with at least the same number of the same characters given at the beginning line. This allows to enter some percent sign characters in the text that should not be interpreted. Index: docs/manual/00001007031000.zettel ================================================================== --- docs/manual/00001007031000.zettel +++ docs/manual/00001007031000.zettel @@ -3,11 +3,11 @@ role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk modified: 20220218131107 -Tables are used to show some data in a two-dimensional fashion. +Tables are used to show some data in a two-dimenensional fashion. In zettelmarkup, table are not specified explicitly, but by entering __table rows__. Therefore, a table can be seen as a sequence of table rows. A table row is nothing as a sequence of __table cells__. The length of a table is the number of table rows, the width of a table is the maximum length of its rows. Index: docs/manual/00001007031200.zettel ================================================================== --- docs/manual/00001007031200.zettel +++ docs/manual/00001007031200.zettel @@ -1,31 +1,49 @@ id: 00001007031200 title: Zettelmarkup: Inline-Zettel Block role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk -modified: 20220311112247 +modified: 20220218172121 An inline-zettel block allows to specify some content with another syntax without creating a new zettel. -This is useful, for example, if you want to embed some [[Markdown|00001008010500]] content, because you are too lazy to translate Markdown into Zettelmarkup. -Another example is to specify HTML code to use it for some kind of web front-end framework. +This is useful, for example, if you want to specify a [[simple drawing|00001008050000]] within your zettel and you are sure that you do not need the drawing in another context. +Another example is to embed some [[Markdown|00001008010500]] content, because you are too lazy to translate Markdown into Zettelmarkup.[^However, translating into Zettelmarkup is quite easy with the [[zmk encoder|00001012920522]].] +A last example is to specify HTML code to use it for some kind of web frontend framework. As all other [[line-range blocks|00001007030000#line-range-blocks]], an inline-zettel block begins with at least three identical characters, starting at the first position of a line. For inline-zettel blocks, the at-sign character (""''@''"", U+0040) is used. You can add some [[attributes|00001007050000]] on the beginning line of a verbatim block, following the initiating characters. The inline-zettel block uses the attribute key ""syntax"" to specify the [[syntax|00001008000000]] of the inline-zettel. Alternatively, you can use the generic attribute to specify the syntax value. -If no value is provided, ""[[text|00001008000000#text]]"" is assumed. +If no value is provided, ""draw"" is assumed. Any other character in this first line will be ignored. Text following the beginning line will not be interpreted, until a line begins with at least the same number of the same at-sign characters given at the beginning line. This allows to enter some at-sign characters in the text that should not be interpreted at this level. Some examples: ```zmk +@@@draw ++-------+ +-------+ +| Box 1 | ---> | Box 2 | ++-------+ +-------+ +@@@ +``` +This will be rendered as: +:::example +@@@draw ++-------+ +-------+ +| Box 1 | ---> | Box 2 | ++-------+ +-------+ +@@@ +::: + +Using Markdown syntax: +```zmk @@@markdown A link to [this](00001007031200) zettel. @@@ ``` will be rendered as: DELETED docs/manual/00001007031300.zettel Index: docs/manual/00001007031300.zettel ================================================================== --- docs/manual/00001007031300.zettel +++ docs/manual/00001007031300.zettel @@ -1,66 +0,0 @@ -id: 00001007031300 -title: Zettelmarkup: Evaluation Blocks -role: manual -tags: #manual #zettelmarkup #zettelstore -syntax: zmk -modified: 20220311120658 - -Evaluation blocks are used to enter text that could be evaluated by either Zettelstore or external software. -They begin with at least three tilde characters (""''~''"", U+007E) at the first position of a line. - -You can add some [[attributes|00001007050000]] on the beginning line of a verbatim block, following the initiating characters. -The evaluation block supports the default attribute[^Depending on the syntax value.]: when given, all spaces in the text are rendered in HTML as open box characters (U+2423). -If you want to give only one attribute and this attribute is the generic attribute, you can omit the most of the attribute syntax and just specify the value. -It will be interpreted as a [[syntax|00001008000000]] value to evaluate its content. -Not all syntax values are supported by Zettelstore.[^Currently just ""[[draw|00001008050000]]"".] -The main reason for an evaluation block is to be used with external software via the [[ZJSON encoding|00001012920503]]. - -Any other character in this line will be ignored - -Text following the beginning line will not be interpreted, until a line begins with at least the same number of the same characters given at the beginning line. -This allows to enter some tilde characters in the text that should not be interpreted. - -For example: -`````zmk -~~~~ -~~~ -~~~~ -````` -will be rendered in HTML as: -:::example -~~~~ -~~~ -~~~~ -::: - -`````zmk -~~~{-} -This is some -text with no - real sense. -~~~~ -````` -will be rendered as: -:::example -~~~{-} -This is some -text with no - real sense. -~~~~ -::: - -`````zmk -~~~draw -+---+ +---+ -| A | --> | B | -+---+ +---+ -~~~ -````` -will be rendered as: -:::example -~~~draw -+---+ +---+ -| A | --> | B | -+---+ +---+ -~~~ -::: DELETED docs/manual/00001007031400.zettel Index: docs/manual/00001007031400.zettel ================================================================== --- docs/manual/00001007031400.zettel +++ docs/manual/00001007031400.zettel @@ -1,74 +0,0 @@ -id: 00001007031400 -title: Zettelmarkup: Math-mode Blocks -role: manual -tags: #manual #zettelmarkup #zettelstore -syntax: zmk -modified: 20220311182505 - -Math-mode blocks are used to enter mathematical formulas / equations in a display style mode. -Similar to a [[evaluation blocks|00001007031300]], the block content will be interpreted by either Zettelstore or an external software. -They begin with at least three dollar sign characters (""''$''"", U+0024) at the first position of a line. - -You can add some [[attributes|00001007050000]] on the beginning line of a verbatim block, following the initiating characters. -A math-mode block supports the default attribute[^Depending on the syntax value.]: when given, all spaces in the text are rendered in HTML as open box characters (U+2423). -If you want to give only one attribute and this attribute is the generic attribute, you can omit the most of the attribute syntax and just specify the value. -It will be interpreted as a [[syntax|00001008000000]] value to evaluate its content. -Alternatively, you could provide an attribute with the key ""syntax"" and use the value to specify the syntax. -Not all syntax values are supported by Zettelstore.[^Currently: none.] -External software might support several values via the [[ZJSON encoding|00001012920503]]. - -Any other character in this line will be ignored - -Text following the beginning line will not be interpreted, until a line begins with at least the same number of the same characters given at the beginning line. -This allows to enter some dollar-sign characters in the text that should not be interpreted. - -For example: -`````zmk -$$$$ -$$$ -$$$$ -````` -will be rendered in HTML as: -:::example -$$$$ -$$$ -$$$$ -::: - -`````zmk -$$${-} -This is some -text with no - real sense. -$$$$ -````` -will be rendered as: -:::example -$$${-} -This is some -text with no - real sense. -$$$$ -::: - -In the future, Zettelstore might somehow support mathematical formulae with a $$\TeX$$-like syntax. -Until then, -`````zmk -$$$ -\begin{align*} - f(x) &= x^2\\ - g(x) &= \frac{1}{x}\\ - F(x) &= \int^a_b \frac{1}{3}x^3 -\end{align*} -$$$ -````` -is rendered as: -:::example -$$$ -\begin{align*} - f(x) &= x^2\\ - g(x) &= \frac{1}{x}\\ - F(x) &= \int^a_b \frac{1}{3}x^3 -\end{align*} -$$$ -::: Index: docs/manual/00001007040100.zettel ================================================================== --- docs/manual/00001007040100.zettel +++ docs/manual/00001007040100.zettel @@ -20,14 +20,14 @@ ** Example: ``abc **def** ghi`` is rendered in HTML as: ::abc **def** ghi::{=example}. * The greater-than sign character (""''>''"", U+003E) marks text as inserted. ** Example: ``abc >>def>> ghi`` is rendered in HTML as: ::abc >>def>> ghi::{=example}. * Similar, the tilde character (""''~''"", U+007E) marks deleted text. ** Example: ``abc ~~def~~ ghi`` is rendered in HTML as: ::abc ~~def~~ ghi::{=example}. -* The circumflex accent character (""''^''"", U+005E) allows to enter super-scripted text. +* The circumflex accent character (""''^''"", U+005E) allows to enter superscripted text. ** Example: ``e=mc^^2^^`` is rendered in HTML as: ::e=mc^^2^^::{=example}. -* The comma character (""'',''"", U+002C) produces sub-scripted text. +* The comma character (""'',''"", U+002C) produces subscripted text. ** Example: ``H,,2,,O`` is rendered in HTML as: ::H,,2,,O::{=example}. * The quotation mark character (""''"''"", U+0022) marks an inline quotation, according to the [[specified language|00001007050100]]. ** Example: ``""To be or not""`` is rendered in HTML as: ::""To be or not""::{=example}. ** Example: ``""Sein oder nicht""{lang=de}`` is rendered in HTML as: ::""Sein oder nicht""{lang=de}::{=example}. * The colon character (""'':''"", U+003A) mark some text that should belong together. It fills a similar role as [[region blocks|00001007030800]], but just for inline elements. ** Example: ``abc ::def::{=example} ghi`` is rendered in HTML as: abc ::def::{=example} ghi. Index: docs/manual/00001007040200.zettel ================================================================== --- docs/manual/00001007040200.zettel +++ docs/manual/00001007040200.zettel @@ -1,11 +1,11 @@ id: 00001007040200 title: Zettelmarkup: Literal-like formatting role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk -modified: 20220311185110 +modified: 20220218131420 There are some reasons to mark text that should be rendered as uninterpreted: * Mark text as literal, sometimes as part of a program. * Mark text as input you give into a computer via a keyboard. * Mark text as output from some computer, e.g. shown at the command line. @@ -49,32 +49,13 @@ === Inline-zettel snippet To specify an inline snippet in a different [[syntax|00001008000000]], delimit your text with two at-sign characters (""''@''"", U+0040) on each side. You can add some [[attributes|00001007050000]] immediate after the two closing at-sign characters to specify the syntax to use. Either use the attribute key ""syntax"" or use the generic attribute to specify the syntax value. -If no value is provided, ""[[text|00001008000000#text]]"" is assumed. +If no value is provided, ""draw"" is assumed. Examples: * ``A @@-->@@ B`` renders in HTML as ::A @@-->@@ B::{=example}. * ``@@@@{=html}Small@@@@{=html}`` renders in HTML as ::@@@@{=html}Small@@@@{=html}::{=example}. To some degree, an inline-zettel snippet is the @@@@{=html}smaller@@@@{=html} sibling of the [[inline-zettel block|00001007031200]]. For HTML syntax, the same rules apply. - -=== Math mode / $$\TeX$$ input -This allows to enter text, that is typically interpreted by $$\TeX$$ or similar software. -The main difference to all other literal-like formatting above is that the backslash character (""''\\''"", U+005C) has no special meaning. -Therefore it is well suited the enter text with a lot of backslash characters. - -Math mode text is delimited with two dollar signs (""''$''"", U+0024) on each side. - -You can add some [[attributes|00001007050000]] immediate after the two closing at-sign characters to specify the syntax to use. -Either use the attribute key ""syntax"" or use the generic attribute to specify the syntax value. -If no syntax value is provided, math mode text roughly corresponds to literal text. - -Currently, Zettelstore does not support any syntax. -This will probably change. -However, external software might support specific syntax value, like ""tex"", ""latex"", ""mathjax"", ""itex"", or ""webtex"". -Even an empty syntax value might be supported. - -Example: -* ``Happy $$\\TeX$$!``is rendered as ::Happy $$\TeX$$!::{=example} Index: docs/manual/00001007040324.zettel ================================================================== --- docs/manual/00001007040324.zettel +++ docs/manual/00001007040324.zettel @@ -1,14 +1,15 @@ id: 00001007040324 title: Zettelmarkup: Inline-mode Transclusion role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk -modified: 20220311110814 +modified: 20220131155955 Inline-mode transclusion applies to all zettel that are parsed in a non-trivial way, e.g. as structured textual content. For example, textual content is assumed if the [[syntax|00001006020000#syntax]] of a zettel is ""zmk"" ([[Zettelmarkup|00001007000000]]), or ""markdown"" / ""md"" ([[Markdown|00001008010000]]). +If the syntax is ""[[draw|00001008050000]]"", it is also a non-trivial way. Since this type of transclusion is at the level of [[inline-structured elements|00001007040000]], the transclude specification must be replaced with some inline-structured elements. First, the referenced zettel is read. If it contains other transclusions, these will be expanded, recursively. Index: docs/manual/00001007040340.zettel ================================================================== --- docs/manual/00001007040340.zettel +++ docs/manual/00001007040340.zettel @@ -3,13 +3,13 @@ role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk modified: 20220218133447 -A citation key references some external material that is part of a bibliographical collection. +A citation key references some external material that is part of a bibliografical collection. Currently, Zettelstore implements this only partially, it is ""work in progress"". However, the syntax is: beginning with a left square bracket and followed by an at sign character (""''@''"", U+0040), a the citation key is given. The key is typically a sequence of letters and digits. If a comma character (""'',''"", U+002C) or a vertical bar character is given, the following is interpreted as [[inline elements|00001007040000]]. A right square bracket ends the text and the citation key element. Index: docs/manual/00001007050000.zettel ================================================================== --- docs/manual/00001007050000.zettel +++ docs/manual/00001007050000.zettel @@ -1,11 +1,11 @@ id: 00001007050000 title: Zettelmarkup: Attributes role: manual tags: #manual #zettelmarkup #zettelstore syntax: zmk -modified: 20220630194106 +modified: 20220218132935 Attributes allows to modify the way how material is presented. Alternatively, they provide additional information to markup elements. To some degree, attributes are similar to [[HTML attributes|https://html.spec.whatwg.org/multipage/dom.html#global-attributes]]. @@ -52,19 +52,49 @@ For example, when used for plain text, it replaces the non-visible space with a visible representation: * ''``Hello, world``{-}'' produces ==Hello, world=={-}. * ''``Hello, world``'' produces ==Hello, world==. -Attributes may be continued on the next line when a space or line ending character is possible. -In case of a quoted attribute value, the line ending character will be part of the attribute value. -For example: -``` -{key="quoted -value"} -``` -will produce a value ''quoted\\nvalue'' (where \\n denotes a line ending character). - +For some [[block-structured elements|00001007030000]], there is a syntax variant if you only want to specify a generic attribute. +For all line-range blocks you can specify the generic attributes directly in the first line, after the three (or more) block characters. + +``` +:::attr +... +::: +``` +is equivalent to +``` +:::{=attr} +... +::: +```. + +For other blocks, the closing curly bracket must be on the same line where the block element begins. +However, spaces are allowed between the blocks characters and the attributes. +``` +=== Heading {example} +``` +is allowed and equivalent to +``` +=== Heading{example} +```. +But +``` +=== Heading {class=example +background=grey} +``` +is not allowed. Same for +``` +=== Heading {background=color:" +green"} +```. + +For [[inline-structued elements|00001007040000]], the attributes must immediately follow the inline markup. +However, the attributes may be continued on the next line when a space or line ending character is possible. + +``::GREEN::{example}`` is allowed, but not ``::GREEN:: {example}``. ``` ::GREEN::{class=example background=grey} ``` @@ -78,38 +108,9 @@ ``` ::GREEN::{background=color:" green"} ``` is allowed, because line endings are allowed within quotes. - -For [[block-structured elements|00001007030000]], there is a syntax variant if you only want to specify a generic attribute. -For all line-range blocks you can specify the generic attributes directly in the first line, after the three (or more) characters starting the block. - -``` -:::attr -... -::: -``` -is equivalent to -``` -:::{=attr} -... -::: -```. - -For block-structured elements, spaces are allowed between the blocks characters and the attributes. -``` -=== Heading {example} -``` -is allowed and equivalent to -``` -=== Heading{example} -```. - -For [[inline-structured elements|00001007040000]], the attributes must immediately follow the inline markup. - -``::GREEN::{example}`` is allowed, but not ``::GREEN:: {example}``. - === Reference material * [[Supported attribute values for natural languages|00001007050100]] * [[Supported attribute values for programming languages|00001007050200]] Index: docs/manual/00001007060000.zettel ================================================================== --- docs/manual/00001007060000.zettel +++ docs/manual/00001007060000.zettel @@ -1,11 +1,11 @@ id: 00001007060000 title: Zettelmarkup: Summary of Formatting Characters role: manual tags: #manual #reference #zettelmarkup #zettelstore syntax: zmk -modified: 20220311120759 +modified: 20220218124943 The following table gives an overview about the use of all characters that begin a markup element. |= Character :|= [[Blocks|00001007030000]] <|= [[Inlines|00001007040000]] < | ''!'' | (free) | (free) @@ -17,26 +17,26 @@ | ''\''' | (free) | [[Computer input|00001007040200]] | ''('' | (free) | (free) | '')'' | (free) | (free) | ''*'' | [[Unordered list|00001007030200]] | [[strongly emphasized text|00001007040100]] | ''+'' | (free) | (free) -| '','' | (free) | [[Sub-scripted text|00001007040100]] -| ''-'' | [[Horizontal rule|00001007030400]] | ""[[en-dash|00001007040000]]"" +| '','' | (free) | [[Subscripted text|00001007040100]] +| ''-'' | [[Horizonal rule|00001007030400]] | ""[[en-dash|00001007040000]]"" | ''.'' | (free) | [[Horizontal ellipsis|00001007040000]] | ''/'' | (free) | (free) | '':'' | [[Region block|00001007030800]] / [[description text|00001007030100]] | [[Inline region|00001007040100]] | '';'' | [[Description term|00001007030100]] | [[Small text|00001007040100]] | ''<'' | [[Quotation block|00001007030600]] | (free) | ''='' | [[Headings|00001007030300]] | [[Computer output|00001007040200]] | ''>'' | [[Quotation lists|00001007030200]] | [[Inserted text|00001007040100]] | ''?'' | (free) | (free) -| ''@'' | [[Inline-Zettel block|00001007031200]] | [[Inline-zettel snippet|00001007040200#inline-zettel-snippet]] +| ''@'' | [[Inline-Zettel blocks|00001007031200]] | [[Inline-zettel snippets|00001007040200#inline-zettel-snippet]] | ''['' | (reserved) | [[Linked material|00001007040300]], [[citation key|00001007040300]], [[footnote|00001007040300]], [[mark|00001007040300]] | ''\\'' | (blocked by inline meaning) | [[Escape character|00001007040000]] | '']'' | (reserved) | End of [[link|00001007040300]], [[citation key|00001007040300]], [[footnote|00001007040300]], [[mark|00001007040300]] -| ''^'' | (free) | [[Super-scripted text|00001007040100]] +| ''^'' | (free) | [[Superscripted text|00001007040100]] | ''_'' | (free) | [[Emphasized text|00001007040100]] | ''`'' | [[Verbatim block|00001007030500]] | [[Literal text|00001007040200]] | ''{'' | [[Transclusion|00001007031100]] | [[Embedded material|00001007040300]], [[Attribute|00001007050000]] | ''|'' | [[Table row / table cell|00001007031000]] | Separator within link and [[embed|00001007040320]] formatting | ''}'' | End of [[Transclusion|00001007031100]] | End of embedded material, End of Attribute -| ''~'' | [[Evaluation block|00001007031300]] | [[Deleted text|00001007040100]] +| ''~'' | (free) | [[Deleted text|00001007040100]] Index: docs/manual/00001008000000.zettel ================================================================== --- docs/manual/00001008000000.zettel +++ docs/manual/00001008000000.zettel @@ -1,11 +1,11 @@ id: 00001008000000 title: Other Markup Languages role: manual tags: #manual #zettelstore syntax: zmk -modified: 20220627192329 +modified: 20220214180202 [[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: @@ -15,24 +15,25 @@ * Image formats: GIF, PNG, JPEG, SVG * Markdown * Plain text, not further interpreted The [[metadata key|00001006020000#syntax]] ""''syntax''"" specifies which language should be used. -If it is not given, it defaults to ''plain''. +If it is not given, the key ""''default-syntax''"" will be used (specified in the [[configuration zettel|00001004020000#default-syntax]]). The following syntax values are supported: ; [!css|''css''] : A [[Cascading Style Sheet|https://www.w3.org/Style/CSS/]], to be used when rendering a zettel as HTML. +; [!draw|''draw''] +: A simple [[language|00001008050000]] to ""draw"" a graphic by using some simple Unicode characters. ; [!gif|''gif'']; [!jpeg|''jpeg'']; [!jpg|''jpg'']; [!png|''png''] : The formats for pixel graphics. - Typically the data is stored in a separate file and the syntax is given in the meta-file, which has the same name as the zettel identifier and has no file extension.[^Before version 0.2, the meta-file had the file extension ''.meta''] + Typically the data is stored in a separate file and the syntax is given in the metafile, which has the same name as the zettel identifier and has no file extension.[^Before version 0.2.0, the metafile had the file extension ''.meta''] ; [!html|''html''] : Hypertext Markup Language, will not be parsed further. Instead, it is treated as [[text|#text]], but will be encoded differently for [[HTML format|00001012920510]] (same for the [[web user interface|00001014000000]]). - For security reasons, equivocal elements will not be encoded in the HTML format / web user interface. - The ``< script ...>`` tag is an example. + For security reasons, equivocal elements will not be encoded in the HTML format / web user interface, e.g. the ``