logseq-md 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
logseq_md/__init__.py ADDED
@@ -0,0 +1,21 @@
1
+ """Read and write file-based Logseq markdown graphs.
2
+
3
+ A Logseq file graph is a directory of markdown: `pages/` for topics, `journals/`
4
+ for dates, one block per bullet, nested by indentation. This package reads that
5
+ shape and writes back into it without reformatting the parts it did not touch.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ __all__ = ["__version__"]
11
+
12
+ #: Resolved from the installed distribution rather than written here, so there is
13
+ #: one version in the repository and the release job owns it. A source checkout
14
+ #: that was never installed has no distribution metadata, and reports that rather
15
+ #: than guessing.
16
+ try: # pragma: no cover - the except branch needs an uninstalled checkout
17
+ from importlib.metadata import PackageNotFoundError, version
18
+
19
+ __version__ = version("logseq-md")
20
+ except PackageNotFoundError: # pragma: no cover
21
+ __version__ = "0.0.0+unknown"
logseq_md/__main__.py ADDED
@@ -0,0 +1,8 @@
1
+ """Allow `python -m logseq_md` as well as the console script."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from logseq_md.cli import run
6
+
7
+ if __name__ == "__main__":
8
+ run()
logseq_md/cli.py ADDED
@@ -0,0 +1,51 @@
1
+ """The command line entry point.
2
+
3
+ Nothing reads a graph yet. What is here is the parser, the version flag and the
4
+ exit convention, which is what the packaging, the entry point and the smoke test
5
+ in CI need in order to be checked before there is anything to check them on.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import sys
12
+ from collections.abc import Sequence
13
+
14
+ from logseq_md import __version__
15
+
16
+ #: Exit codes. `2` is argparse's own code for a usage error and is not reused
17
+ #: here for anything else, so a caller can tell "you asked wrongly" from "the
18
+ #: graph said no".
19
+ OK = 0
20
+ FAILED = 1
21
+
22
+
23
+ def build_parser() -> argparse.ArgumentParser:
24
+ """The argument parser, built separately so a test can inspect it."""
25
+ parser = argparse.ArgumentParser(
26
+ prog="logseq-md",
27
+ description="Read and write file-based Logseq markdown graphs.",
28
+ )
29
+ parser.add_argument(
30
+ "--version",
31
+ action="version",
32
+ version=f"%(prog)s {__version__}",
33
+ )
34
+ return parser
35
+
36
+
37
+ def main(argv: Sequence[str] | None = None) -> int:
38
+ """Run the command and return its exit code.
39
+
40
+ Returning rather than exiting keeps the whole command testable in-process;
41
+ `run` is the thin wrapper the console script points at.
42
+ """
43
+ parser = build_parser()
44
+ parser.parse_args(argv)
45
+ parser.print_help()
46
+ return OK
47
+
48
+
49
+ def run() -> None:
50
+ """Console script entry point."""
51
+ sys.exit(main())
@@ -0,0 +1,85 @@
1
+ Metadata-Version: 2.5
2
+ Name: logseq-md
3
+ Version: 0.1.0
4
+ Summary: Read and write file-based Logseq markdown graphs from the command line
5
+ Project-URL: Homepage, https://github.com/ftschindler/logseq-md
6
+ Project-URL: Source, https://github.com/ftschindler/logseq-md
7
+ Project-URL: Issues, https://github.com/ftschindler/logseq-md/issues
8
+ Author: Felix Schindler
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,logseq,markdown,notes,outliner
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
22
+ Classifier: Topic :: Utilities
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+
26
+ # logseq-md
27
+
28
+ Read and write file-based Logseq markdown graphs from the command line.
29
+
30
+ A Logseq file graph is a directory of markdown: `pages/` for topics, `journals/` for dates, one
31
+ block per bullet, nested by indentation, with `property:: value` lines, `[[page]]` links and
32
+ `((uuid))` block references. Ordinary tools read it well enough. Writing back into it is where
33
+ they go wrong.
34
+
35
+ ```sh
36
+ uvx logseq-md --help
37
+ ```
38
+
39
+ That needs no install beyond [uv](https://docs.astral.sh/uv/).
40
+
41
+ **Pre-alpha.** The packaging, the entry point and the guard suite are in place. Nothing reads a
42
+ graph yet.
43
+
44
+ ## What this is for
45
+
46
+ Agents and scripts that work against a graph the owner also edits by hand, in the app, on more
47
+ than one machine.
48
+
49
+ The constraint that shapes everything here: **a write changes the bytes it meant to change and
50
+ no others.** Every library in this space parses a page into a tree and serialises the tree back
51
+ over the file, which is correct in the sense that Logseq still reads it, and wrong in three
52
+ ways that matter.
53
+
54
+ - A one-line status append arrives as a thousand-line diff, so nobody reviews it.
55
+ - A graph is usually not a git repository, so a reflow is damage with no way back.
56
+ - A graph that syncs between devices gets conflicts, and a conflict between two files that each
57
+ changed one line is a mechanical merge, while a conflict where one side reflowed everything
58
+ cannot be merged by anything, including a person.
59
+
60
+ So the write path here splices lines into the file it was given. The round-trip test is the
61
+ acceptance criterion rather than a nicety: parse every file in a graph, write it back unchanged,
62
+ and assert the bytes are identical.
63
+
64
+ ## What it will not do
65
+
66
+ It knows about blocks, markers, properties, references, pages, journals and ids. It knows
67
+ nothing about what you use them for. There is no notion of a task queue, no integration with any
68
+ forge, no opinion about which of your graphs is private, and no daemon resolving sync conflicts.
69
+
70
+ The test of that boundary: every verb and flag is expressible in Logseq's own vocabulary. A flag
71
+ that needs a word Logseq does not have belongs in whatever is calling this, not here.
72
+
73
+ ## Development
74
+
75
+ ```sh
76
+ make bootstrap # install the pre-commit hooks into this clone
77
+ make test # run the suite
78
+ make check # run the full guard suite over every file
79
+ ```
80
+
81
+ [CONTRIBUTING.md](CONTRIBUTING.md) has the system requirements.
82
+
83
+ ## Licence
84
+
85
+ [MIT](LICENSE).
@@ -0,0 +1,8 @@
1
+ logseq_md/__init__.py,sha256=VxWAMuCSP1NKvAHLthpKq6WEIPO0-GET3Q89YhSFenQ,887
2
+ logseq_md/__main__.py,sha256=1WBom-HwSw32_q7LRYvEByKypNtzbol9eT3gdQ1h2Xw,170
3
+ logseq_md/cli.py,sha256=pUmqpEKibSOk3C2OrlrFr3sfbD4ws-WacDYdMehj7MI,1436
4
+ logseq_md-0.1.0.dist-info/METADATA,sha256=mIZs40ukkZvYUyWW8lO2Luq2gqqQ4WZyplGkC149mx0,3456
5
+ logseq_md-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
6
+ logseq_md-0.1.0.dist-info/entry_points.txt,sha256=N3sfgVSFJmrXiVnp2fWkr3nxZZRgv7NnhZNtEUugDHc,48
7
+ logseq_md-0.1.0.dist-info/licenses/LICENSE,sha256=45jm7nlf5VUNKHLwv_-x2ouCadL8HXXC5BVs6Pw_NsM,1079
8
+ logseq_md-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ logseq-md = logseq_md.cli:run
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 logseq-md contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.