onenote-converter 0.1.2__tar.gz
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.
- onenote_converter-0.1.2/CHANGELOG.md +73 -0
- onenote_converter-0.1.2/Cargo.lock +203 -0
- onenote_converter-0.1.2/Cargo.toml +38 -0
- onenote_converter-0.1.2/LICENSE +21 -0
- onenote_converter-0.1.2/LICENSE.python +21 -0
- onenote_converter-0.1.2/PKG-INFO +136 -0
- onenote_converter-0.1.2/README.md +265 -0
- onenote_converter-0.1.2/RELEASING.md +113 -0
- onenote_converter-0.1.2/pyproject.toml +41 -0
- onenote_converter-0.1.2/python/Cargo.toml +27 -0
- onenote_converter-0.1.2/python/LICENSE.python +21 -0
- onenote_converter-0.1.2/python/README.md +109 -0
- onenote_converter-0.1.2/python/requirements-dev.txt +4 -0
- onenote_converter-0.1.2/python/src/lib.rs +621 -0
- onenote_converter-0.1.2/python/tests/data/README.md +7 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Group Section 1/Group Section 1-a/Group Section 1-a.onetoc2 +0 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Group Section 1/Group Section 1-a/Subsection 3.one +0 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Group Section 1/Group Section 1.onetoc2 +0 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Group Section 1/Subsection 1.one +0 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Group Section 1/Subsection 2.one +0 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Nova Se/303/247/303/243o 1.one +0 -0
- onenote_converter-0.1.2/python/tests/data/notebook/Open Notebook.onetoc2 +0 -0
- onenote_converter-0.1.2/python/tests/test_onenote.py +215 -0
- onenote_converter-0.1.2/scripts/check.sh +76 -0
- onenote_converter-0.1.2/src/cab.rs +365 -0
- onenote_converter-0.1.2/src/doc.rs +1254 -0
- onenote_converter-0.1.2/src/filenode.rs +331 -0
- onenote_converter-0.1.2/src/fsshttpb.rs +909 -0
- onenote_converter-0.1.2/src/guid.rs +103 -0
- onenote_converter-0.1.2/src/header.rs +226 -0
- onenote_converter-0.1.2/src/lib.rs +55 -0
- onenote_converter-0.1.2/src/main.rs +1136 -0
- onenote_converter-0.1.2/src/markdown.rs +317 -0
- onenote_converter-0.1.2/src/notebook.rs +448 -0
- onenote_converter-0.1.2/src/output.rs +390 -0
- onenote_converter-0.1.2/src/packaging.rs +413 -0
- onenote_converter-0.1.2/src/prop.rs +850 -0
- onenote_converter-0.1.2/src/reader.rs +39 -0
- onenote_converter-0.1.2/src/store.rs +866 -0
- onenote_converter-0.1.2/tests/fixtures/README.md +23 -0
- onenote_converter-0.1.2/tests/fixtures/test-tika-3970-dupetext.one +0 -0
- onenote_converter-0.1.2/tests/fixtures/testOneNote2016.one +0 -0
- onenote_converter-0.1.2/tests/fuzz.rs +155 -0
- onenote_converter-0.1.2/tests/onestore.rs +252 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres
|
|
5
|
+
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.2] - 2026-10-27
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Wheels now carry the license text (`dist-info/licenses/LICENSE.python`), as the
|
|
14
|
+
MIT terms require; `scripts/check.sh` and CI fail if the copy drifts from the
|
|
15
|
+
repository `LICENSE`.
|
|
16
|
+
|
|
17
|
+
## [0.1.1] - 2026-10-27
|
|
18
|
+
|
|
19
|
+
Packaging and verification release; no parser behaviour changed.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- CI could not build the Python extension: `maturin develop` needs a virtualenv,
|
|
24
|
+
so the workflow now builds a wheel and installs it (the same commands
|
|
25
|
+
`scripts/check.sh` runs).
|
|
26
|
+
- The sdist no longer carries `.gitignore` or `PLAN.md`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Python floor is `>= 3.9` everywhere (the abi3 feature matched it).
|
|
31
|
+
- Runner labels are pinned (`ubuntu-24.04`, `macos-15`, `macos-15-intel`,
|
|
32
|
+
`windows-2025`) so label migrations cannot change the matrix.
|
|
33
|
+
- `scripts/check.sh` reproduces the CI gate, including creating a throwaway
|
|
34
|
+
virtualenv on a bare checkout and installing the built sdist into a clean one.
|
|
35
|
+
|
|
36
|
+
## [0.1.0] - 2026-10-26
|
|
37
|
+
|
|
38
|
+
First release: a CLI, a Rust library and Python bindings over one parser.
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **Sections** (`.one`): reads `[MS-ONESTORE]` revision stores — header, file node
|
|
43
|
+
lists, property sets, object spaces, revisions, object groups, file data.
|
|
44
|
+
- **Packages** (`.onepkg`): reads Microsoft Cabinets with stored and MSZIP
|
|
45
|
+
folders; Quantum and LZX are rejected with a message.
|
|
46
|
+
- **Notebooks** (`.onetoc2`): the table of contents is honoured exactly as given,
|
|
47
|
+
section groups become subfolders with their own `index.md`, and entries whose
|
|
48
|
+
file or folder is missing are reported instead of skipped.
|
|
49
|
+
- **Markdown output**: page headings, paragraphs, numbered and bulleted lists
|
|
50
|
+
with nesting, tables, pictures (extracted with stable deduplicated names),
|
|
51
|
+
attachments, ink markers, note tags, and inline run formatting (bold, italic,
|
|
52
|
+
strike, underline, colour, highlight, hyperlinks).
|
|
53
|
+
- **YAML front matter** per page: title, creation and modification dates,
|
|
54
|
+
authors, page level.
|
|
55
|
+
- **Diagnostics**: `header` and `inspect` commands (object spaces, declarations,
|
|
56
|
+
property sets, blob ranges, text search, hashed chunk list, transaction log).
|
|
57
|
+
- **Packaged stores** (`[MS-FSSHTTPB]`): data elements, cells, object data and
|
|
58
|
+
the storage index are translated into the same object model as plain stores.
|
|
59
|
+
- **Python bindings** (`onenote`): `read_section`, `read_notebook`,
|
|
60
|
+
`read_package` with `Section`/`Page`/`Image`/`Notebook`/`Package`, abi3 wheels
|
|
61
|
+
for CPython 3.9+.
|
|
62
|
+
- **Machine-readable runs**: `--report` writes a JSON summary, `--strict` turns
|
|
63
|
+
any warning into a non-zero exit status.
|
|
64
|
+
|
|
65
|
+
### Notes
|
|
66
|
+
|
|
67
|
+
- Encrypted sections are detected and reported; their content is not decrypted.
|
|
68
|
+
- Format decisions and the measurements behind them are recorded in `PLAN.md`.
|
|
69
|
+
|
|
70
|
+
[Unreleased]: https://github.com/wsmontes/one-note-converter/compare/v0.1.2...HEAD
|
|
71
|
+
[0.1.2]: https://github.com/wsmontes/one-note-converter/releases/tag/v0.1.2
|
|
72
|
+
[0.1.1]: https://github.com/wsmontes/one-note-converter/releases/tag/v0.1.1
|
|
73
|
+
[0.1.0]: https://github.com/wsmontes/one-note-converter/releases/tag/v0.1.0
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 3
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.1"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "cfg-if"
|
|
13
|
+
version = "1.0.5"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "flate2"
|
|
19
|
+
version = "1.1.10"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb"
|
|
22
|
+
dependencies = [
|
|
23
|
+
"zlib-rs",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "heck"
|
|
28
|
+
version = "0.5.0"
|
|
29
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "indoc"
|
|
34
|
+
version = "2.0.8"
|
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
36
|
+
checksum = "a37b2691796cffeb8a8cd305ac66e65841559f147f4e63231d0eafa4db5384d1"
|
|
37
|
+
dependencies = [
|
|
38
|
+
"rustversion",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[[package]]
|
|
42
|
+
name = "libc"
|
|
43
|
+
version = "0.2.191"
|
|
44
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
45
|
+
checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
|
|
46
|
+
|
|
47
|
+
[[package]]
|
|
48
|
+
name = "memoffset"
|
|
49
|
+
version = "0.9.1"
|
|
50
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
51
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
52
|
+
dependencies = [
|
|
53
|
+
"autocfg",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[[package]]
|
|
57
|
+
name = "once_cell"
|
|
58
|
+
version = "1.21.4"
|
|
59
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
60
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
61
|
+
|
|
62
|
+
[[package]]
|
|
63
|
+
name = "one-note-converter"
|
|
64
|
+
version = "0.1.2"
|
|
65
|
+
dependencies = [
|
|
66
|
+
"flate2",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[[package]]
|
|
70
|
+
name = "onenote-py"
|
|
71
|
+
version = "0.1.2"
|
|
72
|
+
dependencies = [
|
|
73
|
+
"one-note-converter",
|
|
74
|
+
"pyo3",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
[[package]]
|
|
78
|
+
name = "portable-atomic"
|
|
79
|
+
version = "1.15.0"
|
|
80
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
81
|
+
checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
|
|
82
|
+
|
|
83
|
+
[[package]]
|
|
84
|
+
name = "proc-macro2"
|
|
85
|
+
version = "1.0.107"
|
|
86
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
87
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
88
|
+
dependencies = [
|
|
89
|
+
"unicode-ident",
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
[[package]]
|
|
93
|
+
name = "pyo3"
|
|
94
|
+
version = "0.23.5"
|
|
95
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
96
|
+
checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
|
|
97
|
+
dependencies = [
|
|
98
|
+
"cfg-if",
|
|
99
|
+
"indoc",
|
|
100
|
+
"libc",
|
|
101
|
+
"memoffset",
|
|
102
|
+
"once_cell",
|
|
103
|
+
"portable-atomic",
|
|
104
|
+
"pyo3-build-config",
|
|
105
|
+
"pyo3-ffi",
|
|
106
|
+
"pyo3-macros",
|
|
107
|
+
"unindent",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[[package]]
|
|
111
|
+
name = "pyo3-build-config"
|
|
112
|
+
version = "0.23.5"
|
|
113
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
114
|
+
checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
|
|
115
|
+
dependencies = [
|
|
116
|
+
"once_cell",
|
|
117
|
+
"target-lexicon",
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
[[package]]
|
|
121
|
+
name = "pyo3-ffi"
|
|
122
|
+
version = "0.23.5"
|
|
123
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
124
|
+
checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
|
|
125
|
+
dependencies = [
|
|
126
|
+
"libc",
|
|
127
|
+
"pyo3-build-config",
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
[[package]]
|
|
131
|
+
name = "pyo3-macros"
|
|
132
|
+
version = "0.23.5"
|
|
133
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
134
|
+
checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
|
|
135
|
+
dependencies = [
|
|
136
|
+
"proc-macro2",
|
|
137
|
+
"pyo3-macros-backend",
|
|
138
|
+
"quote",
|
|
139
|
+
"syn",
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
[[package]]
|
|
143
|
+
name = "pyo3-macros-backend"
|
|
144
|
+
version = "0.23.5"
|
|
145
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
146
|
+
checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
|
|
147
|
+
dependencies = [
|
|
148
|
+
"heck",
|
|
149
|
+
"proc-macro2",
|
|
150
|
+
"pyo3-build-config",
|
|
151
|
+
"quote",
|
|
152
|
+
"syn",
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
[[package]]
|
|
156
|
+
name = "quote"
|
|
157
|
+
version = "1.0.47"
|
|
158
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
159
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
160
|
+
dependencies = [
|
|
161
|
+
"proc-macro2",
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
[[package]]
|
|
165
|
+
name = "rustversion"
|
|
166
|
+
version = "1.0.23"
|
|
167
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
168
|
+
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|
169
|
+
|
|
170
|
+
[[package]]
|
|
171
|
+
name = "syn"
|
|
172
|
+
version = "2.0.119"
|
|
173
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
174
|
+
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
175
|
+
dependencies = [
|
|
176
|
+
"proc-macro2",
|
|
177
|
+
"quote",
|
|
178
|
+
"unicode-ident",
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
[[package]]
|
|
182
|
+
name = "target-lexicon"
|
|
183
|
+
version = "0.12.16"
|
|
184
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
185
|
+
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
186
|
+
|
|
187
|
+
[[package]]
|
|
188
|
+
name = "unicode-ident"
|
|
189
|
+
version = "1.0.27"
|
|
190
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
191
|
+
checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"
|
|
192
|
+
|
|
193
|
+
[[package]]
|
|
194
|
+
name = "unindent"
|
|
195
|
+
version = "0.2.4"
|
|
196
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
197
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
198
|
+
|
|
199
|
+
[[package]]
|
|
200
|
+
name = "zlib-rs"
|
|
201
|
+
version = "0.6.8"
|
|
202
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
203
|
+
checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[workspace]
|
|
2
|
+
members = [".", "python"]
|
|
3
|
+
resolver = "2"
|
|
4
|
+
|
|
5
|
+
[workspace.package]
|
|
6
|
+
version = "0.1.2"
|
|
7
|
+
edition = "2021"
|
|
8
|
+
rust-version = "1.82"
|
|
9
|
+
license = "MIT"
|
|
10
|
+
repository = "https://github.com/wsmontes/one-note-converter"
|
|
11
|
+
homepage = "https://github.com/wsmontes/one-note-converter"
|
|
12
|
+
authors = ["Wagner Montes <wmontes@gmail.com>"]
|
|
13
|
+
|
|
14
|
+
[package]
|
|
15
|
+
name = "one-note-converter"
|
|
16
|
+
description = "Convert Microsoft OneNote .one sections, .onetoc2 notebooks and .onepkg packages to Markdown"
|
|
17
|
+
version.workspace = true
|
|
18
|
+
edition.workspace = true
|
|
19
|
+
rust-version.workspace = true
|
|
20
|
+
license.workspace = true
|
|
21
|
+
repository.workspace = true
|
|
22
|
+
homepage.workspace = true
|
|
23
|
+
authors.workspace = true
|
|
24
|
+
documentation = "https://docs.rs/one-note-converter"
|
|
25
|
+
readme = "README.md"
|
|
26
|
+
keywords = ["onenote", "markdown", "ms-onestore", "converter", "notes"]
|
|
27
|
+
categories = ["parser-implementations", "command-line-utilities"]
|
|
28
|
+
exclude = ["python", ".github", "target"]
|
|
29
|
+
|
|
30
|
+
[[bin]]
|
|
31
|
+
name = "onenote2md"
|
|
32
|
+
path = "src/main.rs"
|
|
33
|
+
|
|
34
|
+
[dependencies]
|
|
35
|
+
flate2 = { version = "1", default-features = false, features = ["zlib-rs"] }
|
|
36
|
+
|
|
37
|
+
[package.metadata.docs.rs]
|
|
38
|
+
all-features = true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wagner Montes
|
|
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.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wagner Montes
|
|
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.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: onenote-converter
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
+
Classifier: Programming Language :: Rust
|
|
11
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
12
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
13
|
+
License-File: LICENSE.python
|
|
14
|
+
Summary: Read Microsoft OneNote .one sections, .onetoc2 notebooks and .onepkg packages in Python
|
|
15
|
+
Keywords: onenote,markdown,ms-onestore,converter,notebook
|
|
16
|
+
Home-Page: https://github.com/wsmontes/one-note-converter
|
|
17
|
+
Author-email: Wagner Montes <wmontes@gmail.com>
|
|
18
|
+
License-Expression: MIT
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
21
|
+
Project-URL: Changelog, https://github.com/wsmontes/one-note-converter/blob/main/CHANGELOG.md
|
|
22
|
+
Project-URL: Documentation, https://github.com/wsmontes/one-note-converter/blob/main/python/README.md
|
|
23
|
+
Project-URL: Homepage, https://github.com/wsmontes/one-note-converter
|
|
24
|
+
Project-URL: Issues, https://github.com/wsmontes/one-note-converter/issues
|
|
25
|
+
Project-URL: Repository, https://github.com/wsmontes/one-note-converter
|
|
26
|
+
|
|
27
|
+
# onenote — Python bindings
|
|
28
|
+
|
|
29
|
+
`pip install onenote-converter` (the distribution is `onenote-converter`, the module is `onenote`).
|
|
30
|
+
|
|
31
|
+
Python API over the same Rust parser the `onenote2md` CLI uses. Nothing is
|
|
32
|
+
re-implemented here: a `.one` section, a `.onetoc2` notebook and a `.onepkg`
|
|
33
|
+
package are parsed by the crate in the parent directory.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
Requires Rust (stable) only when building.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# development: build and install into the active virtualenv
|
|
41
|
+
python -m venv .venv && . .venv/bin/activate
|
|
42
|
+
pip install maturin
|
|
43
|
+
maturin develop --release # or: maturin build --release + pip install target/wheels/*.whl
|
|
44
|
+
|
|
45
|
+
# a wheel for distribution (abi3: one wheel for CPython ≥ 3.8)
|
|
46
|
+
maturin build --release # → target/wheels/onenote-<ver>-cp38-abi3-<platform>.whl
|
|
47
|
+
pip install target/wheels/onenote-*.whl
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import onenote
|
|
54
|
+
|
|
55
|
+
section = onenote.read_section("Section.one") # path or bytes
|
|
56
|
+
section.page_count # int
|
|
57
|
+
page = section.pages[0]
|
|
58
|
+
page.title, page.level, page.created, page.modified # ISO-8601 UTC strings
|
|
59
|
+
page.authors # list[str]
|
|
60
|
+
page.images # list[Image]
|
|
61
|
+
|
|
62
|
+
section.markdown(front_matter=True) # str, pictures as bare names
|
|
63
|
+
section.images() # list[Image] with .filename/.data
|
|
64
|
+
|
|
65
|
+
stats = section.write("out/Section.md", "out/img", front_matter=True)
|
|
66
|
+
stats.pages, stats.assets, stats.failures
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`Image.data` is `bytes`. Names are unique and deduplicated per section **and are
|
|
70
|
+
the same names `markdown()` links to**, so the in-memory flow is safe:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
md = section.markdown()
|
|
74
|
+
for image in section.images():
|
|
75
|
+
Path(image.filename).write_bytes(image.data) # every delivered `` resolves
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`Page.images` uses the same names, filtered to the pictures that page references.
|
|
79
|
+
Links are percent-encoded; `Image.filename` is the raw name.
|
|
80
|
+
|
|
81
|
+
Some links have no payload in the file — OneNote web clippings and external
|
|
82
|
+
caches reference a picture without embedding it. Those are listed by
|
|
83
|
+
`section.missing_images()` (raw names), so callers can tell "delivered" from
|
|
84
|
+
"referenced only": `links ⊆ {i.filename for i in section.images()} ∪ set(section.missing_images())`.
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
notebook = onenote.read_notebook("Open Notebook.onetoc2")
|
|
88
|
+
notebook.name, notebook.toc
|
|
89
|
+
notebook.sections # [NotebookSection(name, path)]
|
|
90
|
+
notebook.groups # [Notebook] for section groups
|
|
91
|
+
notebook.errors # entries whose file/folder is missing
|
|
92
|
+
notebook.all_sections() # every section, depth first
|
|
93
|
+
|
|
94
|
+
stats = notebook.write("out/notebook", front_matter=True)
|
|
95
|
+
# out/notebook/<Section>.md + <Section>_assets/, one index.md per level
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The tree reflects what conversion does: a folder with its own `.onetoc2` is a
|
|
99
|
+
group even when the parent index does not list it, and `.onetoc2` dotfiles (the
|
|
100
|
+
OneNote Recycle Bin sentinel) are ignored.
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
package = onenote.read_package("Open Notebook.onepkg")
|
|
104
|
+
package.entries # file names inside the cabinet
|
|
105
|
+
package.sections() # parse every .one entry
|
|
106
|
+
package.extract_to("dir") # write the entries and return their paths
|
|
107
|
+
stats = package.write("out/package", front_matter=True)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`Package.write` follows the CLI: when the cabinet carries a table of contents it
|
|
111
|
+
converts a notebook tree, otherwise each section on its own. MSZIP and stored
|
|
112
|
+
(no compression) folders are supported; Quantum/LZX raise `ValueError`.
|
|
113
|
+
|
|
114
|
+
## Errors
|
|
115
|
+
|
|
116
|
+
Malformed files raise `ValueError` with the parser's message; unreadable paths
|
|
117
|
+
raise `OSError`. `write` never raises for a missing picture link — it reports the
|
|
118
|
+
paths in `stats.failures` and still writes the Markdown.
|
|
119
|
+
|
|
120
|
+
## Tests
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
pip install -r requirements-dev.txt # maturin, pytest, twine
|
|
124
|
+
python -m pytest tests -q
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The fixtures come from `../tests/fixtures` plus `tests/data/notebook`, a small
|
|
128
|
+
notebook tree (a table of contents, a group and a nested group). The package
|
|
129
|
+
tests build their cabinet in Python, independently of the Rust reader.
|
|
130
|
+
|
|
131
|
+
## Limitations
|
|
132
|
+
|
|
133
|
+
Same as the CLI: `[MS-ONESTORE]` revision stores are fully read, `[MS-FSSHTTPB]`
|
|
134
|
+
package stores are marked experimental, encrypted sections are reported but not
|
|
135
|
+
decrypted, and cabinet folders compressed with Quantum or LZX are rejected.
|
|
136
|
+
|