Compare commits
18 Commits
preserve_m
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
6f0401b576 | ||
|
e173c32171 | ||
|
9c24f0f6a5 | ||
|
499ea51411 | ||
|
aabb6c6132 | ||
|
2bee08477d | ||
|
5bede0a357 | ||
|
768ebb3ecd | ||
|
66108b5128 | ||
|
9044fc83a8 | ||
|
76c61c6a07 | ||
|
7b1794eb71 | ||
|
7916cf47e3 | ||
|
3afab84d69 | ||
|
e2ef435f04 | ||
|
6d0e693ed7 | ||
|
72735cfff8 | ||
|
564bee1d92 |
29
.github/renovate.json5
vendored
29
.github/renovate.json5
vendored
@ -4,6 +4,7 @@
|
||||
"schedule:monthly",
|
||||
// Group updates to linters together in one PR
|
||||
"group:linters",
|
||||
":semanticCommitsDisabled"
|
||||
],
|
||||
dependencyDashboard: true,
|
||||
"labels": ["dependencies"],
|
||||
@ -22,6 +23,19 @@
|
||||
"packageNameTemplate": "rust-lang/rust",
|
||||
"datasourceTemplate": "github-releases"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"fileMatch": ["^Justfile$"],
|
||||
"matchStrings": [
|
||||
// https://regex101.com/r/vOmY6R/1
|
||||
// Matching on word boundaries (\b) around start and end ensures we
|
||||
// match variations like "towncrier==1.2.3" as well as "pipx run
|
||||
// towncrier==1.2.3", adding some future proofness.
|
||||
"\".*\\btowncrier==(?<currentValue>.+?)\\b\""
|
||||
],
|
||||
"depNameTemplate": "towncrier",
|
||||
"datasourceTemplate": "pypi"
|
||||
},
|
||||
],
|
||||
packageRules: [
|
||||
{
|
||||
@ -29,6 +43,21 @@
|
||||
minimumReleaseAge: "3 days",
|
||||
automerge: true
|
||||
},
|
||||
{
|
||||
// pulldown-cmark and pulldown-cmark-to-mark must be updated in
|
||||
// lockstep in case of breaking changes, so it's best to group them
|
||||
// together.
|
||||
"matchPackageNames": ["pulldown-cmark*"],
|
||||
// pulldown-cmark is currently on a 0.x release series while
|
||||
// pulldown-cmark-to-cmark tends to bump the major version
|
||||
// component whenever pulldown-cmark creates a new release (which
|
||||
// increments the minor component). Renovate by default creates
|
||||
// separate PRs for major and minor bumps which fails to match up
|
||||
// with the grouping. Disabling this behavior ensures that both
|
||||
// packages are always updated together in a single PR.
|
||||
"separateMajorMinor": false,
|
||||
"groupName": "pulldown-cmark (group)"
|
||||
},
|
||||
],
|
||||
ignorePaths: [
|
||||
// Auto-generated by cargo-dist (https://opensource.axo.dev/cargo-dist/)
|
||||
|
2
.github/workflows/publish-crate.yml
vendored
2
.github/workflows/publish-crate.yml
vendored
@ -15,5 +15,5 @@ jobs:
|
||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: ./.github/actions/setup-ci
|
||||
- run: cargo publish
|
||||
|
@ -30,8 +30,3 @@ repos:
|
||||
language: system
|
||||
files: \.rs$
|
||||
pass_filenames: false
|
||||
- id: README
|
||||
name: Render README.md
|
||||
entry: docs/generate.sh
|
||||
language: script
|
||||
files: ^(README\.md)|(docs/.*)
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Changelog
|
||||
|
||||
<!-- towncrier release notes start -->
|
||||
|
||||
## v23.12.0 (2023-12-03)
|
||||
|
||||
### New
|
||||
|
@ -74,4 +74,9 @@ If you don't feel comfortable writing user documentation, I will be happy to gui
|
||||
|
||||
> **⚠ Warning**
|
||||
>
|
||||
> If you update the README file, take note that you must edit the fragments in the [docs](docs/) directory as opposed to the README in the root of the repository, which is auto-generated.
|
||||
> If you update the README file, take note that you must edit the fragments in the [docs](docs/) directory as opposed to the README in the root of the repository, which is auto-generated with every release.
|
||||
|
||||
## Release notes
|
||||
|
||||
[Towncrier](https://towncrier.readthedocs.io/en/stable/index.html) is used to generate release notes.
|
||||
If you add a changelog fragment to the `changelog.d` directory with `just add-changelog` (requires [just](https://github.com/casey/just#installation)) it will automatically be picked up when a new release is made.
|
||||
|
157
Cargo.lock
generated
157
Cargo.lock
generated
@ -101,7 +101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -116,9 +116,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
@ -176,7 +188,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn 2.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -299,9 +311,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -314,16 +326,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
@ -337,16 +354,6 @@ version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "matter"
|
||||
version = "0.1.0-alpha4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc16e839c57e0ad77957c42d39baab3692a1c6fa47692066470cddc24a5b0cd0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
@ -358,9 +365,9 @@ name = "obsidian-export"
|
||||
version = "23.12.0"
|
||||
dependencies = [
|
||||
"eyre",
|
||||
"filetime",
|
||||
"gumdrop",
|
||||
"ignore",
|
||||
"matter",
|
||||
"pathdiff",
|
||||
"percent-encoding",
|
||||
"pretty_assertions",
|
||||
@ -437,30 +444,37 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.9.6"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
|
||||
checksum = "4d31cbfcd94884c3a67ec210c83efb06cb43674043458b0ad59f6947f8462c23"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"getopts",
|
||||
"memchr",
|
||||
"pulldown-cmark-escape",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark-to-cmark"
|
||||
version = "11.2.0"
|
||||
name = "pulldown-cmark-escape"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dd464f32d7631035e849fcd969a603e9bb17ceaebe8467352a7728147f34e42"
|
||||
checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark-to-cmark"
|
||||
version = "16.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "171b9687038fb417937aee4ce1d0a269897091f05be16660a1e45777533c54b9"
|
||||
dependencies = [
|
||||
"pulldown-cmark",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -485,6 +499,15 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.6"
|
||||
@ -546,7 +569,7 @@ dependencies = [
|
||||
"regex",
|
||||
"relative-path",
|
||||
"rustc_version",
|
||||
"syn 2.0.72",
|
||||
"syn 2.0.76",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
@ -569,7 +592,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -595,22 +618,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
version = "1.0.209"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.204"
|
||||
version = "1.0.209"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn 2.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -637,9 +660,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "slug"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4"
|
||||
checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724"
|
||||
dependencies = [
|
||||
"deunicode",
|
||||
"wasm-bindgen",
|
||||
@ -663,7 +686,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn 2.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -679,9 +702,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.72"
|
||||
version = "2.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -690,15 +713,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.11.0"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
|
||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -718,9 +741,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.7"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
@ -787,34 +810,35 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.92"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.92"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn 2.0.76",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -822,30 +846,30 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.92"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn 2.0.76",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -857,6 +881,15 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
|
@ -28,17 +28,17 @@ doc = false
|
||||
eyre = "0.6.12"
|
||||
gumdrop = "0.8.1"
|
||||
ignore = "0.4.22"
|
||||
matter = "0.1.0-alpha4"
|
||||
pathdiff = "0.2.1"
|
||||
percent-encoding = "2.3.1"
|
||||
pulldown-cmark = "0.9.3"
|
||||
pulldown-cmark-to-cmark = "11.0.2"
|
||||
pulldown-cmark = "0.12.0"
|
||||
pulldown-cmark-to-cmark = "16.0.0"
|
||||
rayon = "1.10.0"
|
||||
regex = "1.10.5"
|
||||
serde_yaml = "0.9.34"
|
||||
slug = "0.1.5"
|
||||
snafu = "0.8.3"
|
||||
unicode-normalization = "0.1.23"
|
||||
filetime = "0.2.23"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.0"
|
||||
|
67
Justfile
Normal file
67
Justfile
Normal file
@ -0,0 +1,67 @@
|
||||
towncrier_cmd := "pipx run towncrier==24.8.0"
|
||||
|
||||
_default:
|
||||
@{{just_executable()}} --choose
|
||||
|
||||
# Add a new changelog entry using towncrier
|
||||
add-changelog:
|
||||
{{towncrier_cmd}} create --edit
|
||||
git add changelog.d
|
||||
|
||||
# Create a new release
|
||||
make-new-release:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
get_next_version_number() {
|
||||
DATEPART=$(date +%y.%-m)
|
||||
ITERATION=0
|
||||
|
||||
while true; do
|
||||
VERSION_STRING="${DATEPART}.${ITERATION}"
|
||||
if git rev-list "v$VERSION_STRING" > /dev/null 2>&1; then
|
||||
((ITERATION++))
|
||||
else
|
||||
echo "$VERSION_STRING"
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
git add .
|
||||
if ! git diff-index --quiet HEAD; then
|
||||
printf "Working directory is not clean. Please commit or stash your changes.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$(get_next_version_number)
|
||||
COMMITMSG=$(mktemp --tmpdir commitmsg.XXXXXXXXXX)
|
||||
trap 'rm "$COMMITMSG"' EXIT
|
||||
set -x
|
||||
|
||||
cargo set-version "${VERSION}"
|
||||
|
||||
# Construct a git commit message.
|
||||
# This must be done before the next step so we can leverage the --draft
|
||||
# flag here to get a list of changes being introduced by this release.
|
||||
printf "Release v${VERSION}\n\n" > "$COMMITMSG"
|
||||
{{towncrier_cmd}} build --draft --version "${VERSION}" >> "$COMMITMSG"
|
||||
|
||||
# Generate changelog and docs
|
||||
{{towncrier_cmd}} build --version "${VERSION}"
|
||||
docs/generate.sh
|
||||
|
||||
# Stage all the changes we've prepared
|
||||
git add .
|
||||
# There are likely trailing whitespace changes in the changelog, but a single
|
||||
# run of pre-commit will fix these automatically.
|
||||
pre-commit run || git add .
|
||||
|
||||
git commit --file "$COMMITMSG"
|
||||
git tag "v${VERSION}"
|
||||
|
||||
set +x
|
||||
printf "\n\nSuccessfully created release %s\n" "v${VERSION}"
|
||||
printf "\nYou'll probably want to continue with:\n"
|
||||
printf "\tgit push origin main\n"
|
||||
printf "\tgit push origin %s\n" "v${VERSION}"
|
4
changelog.d/+52650337.change.md
Normal file
4
changelog.d/+52650337.change.md
Normal file
@ -0,0 +1,4 @@
|
||||
Bump to the minimum supported Rust version to 1.80.0
|
||||
|
||||
Obsidian-export now uses [std::sync::LazyLock](https://doc.rust-lang.org/std/sync/struct.LazyLock.html) instead of [lazy_static](https://crates.io/crates/lazy_static), which was only stabilized in Rust 1.80.0.
|
||||
This change made it possible to drop the external dependency on lazy_static, though as a result of this, compiling with older versions will no longer be possible.
|
0
changelog.d/.gitignore
vendored
Normal file
0
changelog.d/.gitignore
vendored
Normal file
1
changelog.d/14.breaking.md
Symbolic link
1
changelog.d/14.breaking.md
Symbolic link
@ -0,0 +1 @@
|
||||
252.breaking.md
|
4
changelog.d/14.fix.md
Normal file
4
changelog.d/14.fix.md
Normal file
@ -0,0 +1,4 @@
|
||||
Don't escape square brackets in math expressions
|
||||
|
||||
The upgrade to [pulldown-cmark](https://crates.io/crates/pulldown-cmark) 0.11 (see Backwards-incompatible Changes) includes official support for LaTeX-style math expressions.
|
||||
With the markdown parser supporting this syntax natively, math expressions are now processed correctly without edge-cases.
|
1
changelog.d/154.new.md
Symbolic link
1
changelog.d/154.new.md
Symbolic link
@ -0,0 +1 @@
|
||||
204.new.md
|
5
changelog.d/204.new.md
Normal file
5
changelog.d/204.new.md
Normal file
@ -0,0 +1,5 @@
|
||||
Optionally preserve modified time of exported files
|
||||
|
||||
Add a new argument `--preserve-mtime` to keep the original modified time attribute of notes being exported, instead of setting them to the current time.
|
||||
|
||||
Contribution made by [Davis Davalos-DeLosh](https://github.com/Programmerino).
|
12
changelog.d/252.breaking.md
Normal file
12
changelog.d/252.breaking.md
Normal file
@ -0,0 +1,12 @@
|
||||
Upgrade [pulldown-cmark](https://crates.io/crates/pulldown-cmark) from 0.9 to 0.12
|
||||
|
||||
pulldown-cmark is the Markdown/CommonMark parser that is used to read and convert notes (together with [pulldown-cmark-to-cmark](https://crates.io/crates/pulldown-cmark-to-cmark)).
|
||||
|
||||
For end-users that call the obsidian-export CLI this upgrade will be mostly transparent, except that Math blocks are now properly processed without getting mangled.
|
||||
|
||||
People who use the library directly may face more significant breaking changes if they have custom postprocessors, as pulldown-cmark's events have gone through various breaking changes.
|
||||
For more information, see:
|
||||
|
||||
- <https://github.com/zoni/obsidian-export/pull/252>
|
||||
- <https://github.com/pulldown-cmark/pulldown-cmark/releases/tag/v0.10.0>
|
||||
- <https://github.com/zoni/obsidian-export/pull/276/files#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759>
|
1
changelog.d/252.fix.md
Symbolic link
1
changelog.d/252.fix.md
Symbolic link
@ -0,0 +1 @@
|
||||
14.fix.md
|
1
changelog.d/259.breaking.md
Symbolic link
1
changelog.d/259.breaking.md
Symbolic link
@ -0,0 +1 @@
|
||||
252.breaking.md
|
1
changelog.d/285.breaking.md
Symbolic link
1
changelog.d/285.breaking.md
Symbolic link
@ -0,0 +1 @@
|
||||
252.breaking.md
|
@ -1,5 +1,5 @@
|
||||
# Release process
|
||||
|
||||
- [ ] Run `./make-new-release.sh`
|
||||
- [ ] Run `just make-new-release`
|
||||
- [ ] Push the created release commit/tag to GitHub
|
||||
- [ ] Wait for builds to turn green (<https://github.com/zoni/obsidian-export/actions>) and confirm everything looks OK.
|
||||
|
@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
get_next_version_number() {
|
||||
DATEPART=$(date +%y.%-m)
|
||||
ITERATION=0
|
||||
|
||||
while true; do
|
||||
VERSION_STRING="${DATEPART}.${ITERATION}"
|
||||
if git rev-list "v$VERSION_STRING" > /dev/null 2>&1; then
|
||||
((ITERATION++))
|
||||
else
|
||||
echo "$VERSION_STRING"
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
git add .
|
||||
if ! git diff-index --quiet HEAD; then
|
||||
printf "Working directory is not clean. Please commit or stash your changes.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$(get_next_version_number)
|
||||
git tag "v${VERSION}"
|
||||
|
||||
git cliff --latest --prepend CHANGELOG.md > /dev/null
|
||||
${EDITOR:-vim} CHANGELOG.md
|
||||
docs/generate.sh
|
||||
|
||||
sed -i -E "s/^version = \".+\"$/version = \"${VERSION}\"/" Cargo.toml
|
||||
cargo check
|
||||
|
||||
git add .
|
||||
# There are likely trailing whitespace changes in the changelog, but a single
|
||||
# run of pre-commit will fix these automatically.
|
||||
pre-commit run || git add .
|
||||
|
||||
git commit --message "Release v${VERSION}"
|
||||
git tag "v${VERSION}" --force
|
||||
|
||||
printf "\n\nSuccessfully created release %s\n" "v${VERSION}"
|
||||
printf "\nYou'll probably want to continue with:\n"
|
||||
printf "\tgit push origin main\n"
|
||||
printf "\tgit push origin %s\n" "v${VERSION}"
|
204
src/lib.rs
204
src/lib.rs
@ -14,11 +14,12 @@ use std::path::{Path, PathBuf};
|
||||
use std::{fmt, str};
|
||||
|
||||
pub use context::Context;
|
||||
use filetime::set_file_mtime;
|
||||
use frontmatter::{frontmatter_from_str, frontmatter_to_str};
|
||||
pub use frontmatter::{Frontmatter, FrontmatterStrategy};
|
||||
use pathdiff::diff_paths;
|
||||
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
||||
use pulldown_cmark::{CodeBlockKind, CowStr, Event, HeadingLevel, Options, Parser, Tag};
|
||||
use pulldown_cmark::{CodeBlockKind, CowStr, Event, HeadingLevel, Options, Parser, Tag, TagEnd};
|
||||
use pulldown_cmark_to_cmark::cmark_with_options;
|
||||
use rayon::prelude::*;
|
||||
use references::{ObsidianNoteReference, RefParser, RefParserState, RefType};
|
||||
@ -160,6 +161,20 @@ pub enum ExportError {
|
||||
source: ignore::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("Failed to read the mtime of '{}'", path.display()))]
|
||||
/// This occurs when a file's modified time cannot be read
|
||||
ModTimeReadError {
|
||||
path: PathBuf,
|
||||
source: std::io::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("Failed to set the mtime of '{}'", path.display()))]
|
||||
/// This occurs when a file's modified time cannot be set
|
||||
ModTimeSetError {
|
||||
path: PathBuf,
|
||||
source: std::io::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("No such file or directory: {}", path.display()))]
|
||||
/// This occurs when an operation is requested on a file or directory which does not exist.
|
||||
PathDoesNotExist { path: PathBuf },
|
||||
@ -227,6 +242,7 @@ pub struct Exporter<'a> {
|
||||
vault_contents: Option<Vec<PathBuf>>,
|
||||
walk_options: WalkOptions<'a>,
|
||||
process_embeds_recursively: bool,
|
||||
preserve_mtime: bool,
|
||||
postprocessors: Vec<&'a Postprocessor<'a>>,
|
||||
embed_postprocessors: Vec<&'a Postprocessor<'a>>,
|
||||
}
|
||||
@ -243,6 +259,7 @@ impl<'a> fmt::Debug for Exporter<'a> {
|
||||
"process_embeds_recursively",
|
||||
&self.process_embeds_recursively,
|
||||
)
|
||||
.field("preserve_mtime", &self.preserve_mtime)
|
||||
.field(
|
||||
"postprocessors",
|
||||
&format!("<{} postprocessors active>", self.postprocessors.len()),
|
||||
@ -270,6 +287,7 @@ impl<'a> Exporter<'a> {
|
||||
frontmatter_strategy: FrontmatterStrategy::Auto,
|
||||
walk_options: WalkOptions::default(),
|
||||
process_embeds_recursively: true,
|
||||
preserve_mtime: false,
|
||||
vault_contents: None,
|
||||
postprocessors: vec![],
|
||||
embed_postprocessors: vec![],
|
||||
@ -312,6 +330,15 @@ impl<'a> Exporter<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether the modified time of exported files should be preserved.
|
||||
///
|
||||
/// When `preserve` is true, the modified time of exported files will be set to the modified
|
||||
/// time of the source file.
|
||||
pub fn preserve_mtime(&mut self, preserve: bool) -> &mut Self {
|
||||
self.preserve_mtime = preserve;
|
||||
self
|
||||
}
|
||||
|
||||
/// Append a function to the chain of [postprocessors][Postprocessor] to run on exported
|
||||
/// Obsidian Markdown notes.
|
||||
pub fn add_postprocessor(&mut self, processor: &'a Postprocessor<'_>) -> &mut Self {
|
||||
@ -392,7 +419,13 @@ impl<'a> Exporter<'a> {
|
||||
true => self.parse_and_export_obsidian_note(src, dest),
|
||||
false => copy_file(src, dest),
|
||||
}
|
||||
.context(FileExportSnafu { path: src })
|
||||
.context(FileExportSnafu { path: src })?;
|
||||
|
||||
if self.preserve_mtime {
|
||||
copy_mtime(src, dest).context(FileExportSnafu { path: src })?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_and_export_obsidian_note(&self, src: &Path, dest: &Path) -> Result<()> {
|
||||
@ -434,6 +467,7 @@ impl<'a> Exporter<'a> {
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
#[allow(clippy::panic_in_result_fn)]
|
||||
#[allow(clippy::shadow_unrelated)]
|
||||
fn parse_obsidian_note<'b>(
|
||||
&self,
|
||||
path: &Path,
|
||||
@ -445,23 +479,40 @@ impl<'a> Exporter<'a> {
|
||||
});
|
||||
}
|
||||
let content = fs::read_to_string(path).context(ReadSnafu { path })?;
|
||||
let (frontmatter, content) =
|
||||
matter::matter(&content).unwrap_or((String::new(), content.clone()));
|
||||
let frontmatter =
|
||||
frontmatter_from_str(&frontmatter).context(FrontMatterDecodeSnafu { path })?;
|
||||
let mut frontmatter = String::new();
|
||||
|
||||
let mut parser_options = Options::empty();
|
||||
parser_options.insert(Options::ENABLE_TABLES);
|
||||
parser_options.insert(Options::ENABLE_FOOTNOTES);
|
||||
parser_options.insert(Options::ENABLE_STRIKETHROUGH);
|
||||
parser_options.insert(Options::ENABLE_TASKLISTS);
|
||||
let parser_options = Options::ENABLE_TABLES
|
||||
| Options::ENABLE_FOOTNOTES
|
||||
| Options::ENABLE_STRIKETHROUGH
|
||||
| Options::ENABLE_TASKLISTS
|
||||
| Options::ENABLE_MATH
|
||||
| Options::ENABLE_YAML_STYLE_METADATA_BLOCKS;
|
||||
|
||||
let mut ref_parser = RefParser::new();
|
||||
let mut events = vec![];
|
||||
// Most of the time, a reference triggers 5 events: [ or ![, [, <text>, ], ]
|
||||
let mut buffer = Vec::with_capacity(5);
|
||||
|
||||
for event in Parser::new_ext(&content, parser_options) {
|
||||
let mut parser = Parser::new_ext(&content, parser_options);
|
||||
'outer: while let Some(event) = parser.next() {
|
||||
// When encountering a metadata block (frontmatter), collect all events until getting
|
||||
// to the end of the block, at which point the nested loop will break out to the outer
|
||||
// loop again.
|
||||
if matches!(event, Event::Start(Tag::MetadataBlock(_kind))) {
|
||||
for event in parser.by_ref() {
|
||||
match event {
|
||||
Event::Text(cowstr) => frontmatter.push_str(&cowstr),
|
||||
Event::End(TagEnd::MetadataBlock(_kind)) => {
|
||||
continue 'outer;
|
||||
},
|
||||
_ => panic!(
|
||||
"Encountered an unexpected event while processing frontmatter in {}. Please report this as a bug with a copy of the note contents and this text: \n\nEvent: {:?}\n",
|
||||
path.display(),
|
||||
event
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
if ref_parser.state == RefParserState::Resetting {
|
||||
events.append(&mut buffer);
|
||||
buffer.clear();
|
||||
@ -550,8 +601,9 @@ impl<'a> Exporter<'a> {
|
||||
if !buffer.is_empty() {
|
||||
events.append(&mut buffer);
|
||||
}
|
||||
|
||||
Ok((
|
||||
frontmatter,
|
||||
frontmatter_from_str(&frontmatter).context(FrontMatterDecodeSnafu { path })?,
|
||||
events.into_iter().map(event_to_owned).collect(),
|
||||
))
|
||||
}
|
||||
@ -629,20 +681,18 @@ impl<'a> Exporter<'a> {
|
||||
// into an image reference instead. Slightly hacky, but avoids needing
|
||||
// to keep another utility function around for this, or introducing an
|
||||
// extra parameter on make_link_to_file.
|
||||
Event::Start(Tag::Link(linktype, cowstr1, cowstr2)) => {
|
||||
Event::Start(Tag::Image(
|
||||
linktype,
|
||||
CowStr::from(cowstr1.into_string()),
|
||||
CowStr::from(cowstr2.into_string()),
|
||||
))
|
||||
}
|
||||
Event::End(Tag::Link(linktype, cowstr1, cowstr2)) => {
|
||||
Event::End(Tag::Image(
|
||||
linktype,
|
||||
CowStr::from(cowstr1.into_string()),
|
||||
CowStr::from(cowstr2.into_string()),
|
||||
))
|
||||
}
|
||||
Event::Start(Tag::Link {
|
||||
link_type,
|
||||
dest_url,
|
||||
title,
|
||||
id,
|
||||
}) => Event::Start(Tag::Image {
|
||||
link_type,
|
||||
dest_url: CowStr::from(dest_url.into_string()),
|
||||
title: CowStr::from(title.into_string()),
|
||||
id: CowStr::from(id.into_string()),
|
||||
}),
|
||||
Event::End(TagEnd::Link) => Event::End(TagEnd::Image),
|
||||
_ => event,
|
||||
})
|
||||
.collect()
|
||||
@ -674,7 +724,7 @@ impl<'a> Exporter<'a> {
|
||||
return vec![
|
||||
Event::Start(Tag::Emphasis),
|
||||
Event::Text(CowStr::from(reference.display())),
|
||||
Event::End(Tag::Emphasis),
|
||||
Event::End(TagEnd::Emphasis),
|
||||
];
|
||||
}
|
||||
let target_file = target_file.unwrap();
|
||||
@ -698,16 +748,17 @@ impl<'a> Exporter<'a> {
|
||||
link.push_str(&slugify(section));
|
||||
}
|
||||
|
||||
let link_tag = Tag::Link(
|
||||
pulldown_cmark::LinkType::Inline,
|
||||
CowStr::from(link),
|
||||
CowStr::from(""),
|
||||
);
|
||||
let link_tag = Tag::Link {
|
||||
link_type: pulldown_cmark::LinkType::Inline,
|
||||
dest_url: CowStr::from(link),
|
||||
title: CowStr::from(""),
|
||||
id: CowStr::from(""),
|
||||
};
|
||||
|
||||
vec![
|
||||
Event::Start(link_tag.clone()),
|
||||
Event::Start(link_tag),
|
||||
Event::Text(CowStr::from(reference.display())),
|
||||
Event::End(link_tag.clone()),
|
||||
Event::End(TagEnd::Link),
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -766,6 +817,16 @@ fn create_file(dest: &Path) -> Result<File> {
|
||||
Ok(file)
|
||||
}
|
||||
|
||||
fn copy_mtime(src: &Path, dest: &Path) -> Result<()> {
|
||||
let metadata = fs::metadata(src).context(ModTimeReadSnafu { path: src })?;
|
||||
let modified_time = metadata
|
||||
.modified()
|
||||
.context(ModTimeReadSnafu { path: src })?;
|
||||
|
||||
set_file_mtime(dest, modified_time.into()).context(ModTimeSetSnafu { path: dest })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_file(src: &Path, dest: &Path) -> Result<()> {
|
||||
fs::copy(src, dest)
|
||||
.or_else(|err| {
|
||||
@ -798,8 +859,7 @@ fn reduce_to_section<'a>(events: MarkdownEvents<'a>, section: &str) -> MarkdownE
|
||||
for event in events {
|
||||
filtered_events.push(event.clone());
|
||||
match event {
|
||||
// FIXME: This should propagate fragment_identifier and classes.
|
||||
Event::Start(Tag::Heading(level, _fragment_identifier, _classes)) => {
|
||||
Event::Start(Tag::Heading { level, .. }) => {
|
||||
last_tag_was_heading = true;
|
||||
last_level = level;
|
||||
if currently_in_target_section && level <= section_level {
|
||||
@ -838,10 +898,11 @@ fn reduce_to_section<'a>(events: MarkdownEvents<'a>, section: &str) -> MarkdownE
|
||||
fn event_to_owned<'a>(event: Event<'_>) -> Event<'a> {
|
||||
match event {
|
||||
Event::Start(tag) => Event::Start(tag_to_owned(tag)),
|
||||
Event::End(tag) => Event::End(tag_to_owned(tag)),
|
||||
Event::End(tag) => Event::End(tag),
|
||||
Event::Text(cowstr) => Event::Text(CowStr::from(cowstr.into_string())),
|
||||
Event::Code(cowstr) => Event::Code(CowStr::from(cowstr.into_string())),
|
||||
Event::Html(cowstr) => Event::Html(CowStr::from(cowstr.into_string())),
|
||||
Event::InlineHtml(cowstr) => Event::InlineHtml(CowStr::from(cowstr.into_string())),
|
||||
Event::FootnoteReference(cowstr) => {
|
||||
Event::FootnoteReference(CowStr::from(cowstr.into_string()))
|
||||
}
|
||||
@ -849,17 +910,37 @@ fn event_to_owned<'a>(event: Event<'_>) -> Event<'a> {
|
||||
Event::HardBreak => Event::HardBreak,
|
||||
Event::Rule => Event::Rule,
|
||||
Event::TaskListMarker(checked) => Event::TaskListMarker(checked),
|
||||
Event::InlineMath(cowstr) => Event::InlineMath(CowStr::from(cowstr.into_string())),
|
||||
Event::DisplayMath(cowstr) => Event::DisplayMath(CowStr::from(cowstr.into_string())),
|
||||
}
|
||||
}
|
||||
|
||||
fn tag_to_owned<'a>(tag: Tag<'_>) -> Tag<'a> {
|
||||
match tag {
|
||||
Tag::Paragraph => Tag::Paragraph,
|
||||
Tag::Heading(level, _fragment_identifier, _classes) => {
|
||||
// FIXME: This should propagate fragment_identifier and classes.
|
||||
Tag::Heading(level, None, Vec::new())
|
||||
}
|
||||
Tag::BlockQuote => Tag::BlockQuote,
|
||||
Tag::Heading {
|
||||
level: heading_level,
|
||||
id,
|
||||
classes,
|
||||
attrs,
|
||||
} => Tag::Heading {
|
||||
level: heading_level,
|
||||
id: id.map(|cowstr| CowStr::from(cowstr.into_string())),
|
||||
classes: classes
|
||||
.into_iter()
|
||||
.map(|cowstr| CowStr::from(cowstr.into_string()))
|
||||
.collect(),
|
||||
attrs: attrs
|
||||
.into_iter()
|
||||
.map(|(attr, value)| {
|
||||
(
|
||||
CowStr::from(attr.into_string()),
|
||||
value.map(|cowstr| CowStr::from(cowstr.into_string())),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
},
|
||||
Tag::BlockQuote(blockquote_kind) => Tag::BlockQuote(blockquote_kind),
|
||||
Tag::CodeBlock(codeblock_kind) => Tag::CodeBlock(codeblock_kind_to_owned(codeblock_kind)),
|
||||
Tag::List(optional) => Tag::List(optional),
|
||||
Tag::Item => Tag::Item,
|
||||
@ -873,16 +954,33 @@ fn tag_to_owned<'a>(tag: Tag<'_>) -> Tag<'a> {
|
||||
Tag::Emphasis => Tag::Emphasis,
|
||||
Tag::Strong => Tag::Strong,
|
||||
Tag::Strikethrough => Tag::Strikethrough,
|
||||
Tag::Link(linktype, cowstr1, cowstr2) => Tag::Link(
|
||||
linktype,
|
||||
CowStr::from(cowstr1.into_string()),
|
||||
CowStr::from(cowstr2.into_string()),
|
||||
),
|
||||
Tag::Image(linktype, cowstr1, cowstr2) => Tag::Image(
|
||||
linktype,
|
||||
CowStr::from(cowstr1.into_string()),
|
||||
CowStr::from(cowstr2.into_string()),
|
||||
),
|
||||
Tag::Link {
|
||||
link_type,
|
||||
dest_url,
|
||||
title,
|
||||
id,
|
||||
} => Tag::Link {
|
||||
link_type,
|
||||
dest_url: CowStr::from(dest_url.into_string()),
|
||||
title: CowStr::from(title.into_string()),
|
||||
id: CowStr::from(id.into_string()),
|
||||
},
|
||||
Tag::Image {
|
||||
link_type,
|
||||
dest_url,
|
||||
title,
|
||||
id,
|
||||
} => Tag::Image {
|
||||
link_type,
|
||||
dest_url: CowStr::from(dest_url.into_string()),
|
||||
title: CowStr::from(title.into_string()),
|
||||
id: CowStr::from(id.into_string()),
|
||||
},
|
||||
Tag::HtmlBlock => Tag::HtmlBlock,
|
||||
Tag::MetadataBlock(metadata_block_kind) => Tag::MetadataBlock(metadata_block_kind),
|
||||
Tag::DefinitionList => Tag::DefinitionList,
|
||||
Tag::DefinitionListTitle => Tag::DefinitionListTitle,
|
||||
Tag::DefinitionListDefinition => Tag::DefinitionListDefinition,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,13 @@ struct Opts {
|
||||
#[options(no_short, help = "Don't process embeds recursively", default = "false")]
|
||||
no_recursive_embeds: bool,
|
||||
|
||||
#[options(
|
||||
no_short,
|
||||
help = "Preserve the mtime of exported files",
|
||||
default = "false"
|
||||
)]
|
||||
preserve_mtime: bool,
|
||||
|
||||
#[options(
|
||||
no_short,
|
||||
help = "Convert soft line breaks to hard line breaks. This mimics Obsidian's 'Strict line breaks' setting",
|
||||
@ -97,6 +104,7 @@ fn main() {
|
||||
let mut exporter = Exporter::new(root, destination);
|
||||
exporter.frontmatter_strategy(args.frontmatter_strategy);
|
||||
exporter.process_embeds_recursively(!args.no_recursive_embeds);
|
||||
exporter.preserve_mtime(args.preserve_mtime);
|
||||
exporter.walk_options(walk_options);
|
||||
|
||||
if args.hard_linebreaks {
|
||||
|
@ -360,6 +360,44 @@ fn test_no_recursive_embeds() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preserve_mtime() {
|
||||
let tmp_dir = TempDir::new().expect("failed to make tempdir");
|
||||
|
||||
let mut exporter = Exporter::new(
|
||||
PathBuf::from("tests/testdata/input/main-samples/"),
|
||||
tmp_dir.path().to_path_buf(),
|
||||
);
|
||||
exporter.preserve_mtime(true);
|
||||
exporter.run().expect("exporter returned error");
|
||||
|
||||
let src = "tests/testdata/input/main-samples/obsidian-wikilinks.md";
|
||||
let dest = tmp_dir.path().join(PathBuf::from("obsidian-wikilinks.md"));
|
||||
let src_meta = std::fs::metadata(src).unwrap();
|
||||
let dest_meta = std::fs::metadata(dest).unwrap();
|
||||
|
||||
assert_eq!(src_meta.modified().unwrap(), dest_meta.modified().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_preserve_mtime() {
|
||||
let tmp_dir = TempDir::new().expect("failed to make tempdir");
|
||||
|
||||
let mut exporter = Exporter::new(
|
||||
PathBuf::from("tests/testdata/input/main-samples/"),
|
||||
tmp_dir.path().to_path_buf(),
|
||||
);
|
||||
exporter.preserve_mtime(false);
|
||||
exporter.run().expect("exporter returned error");
|
||||
|
||||
let src = "tests/testdata/input/main-samples/obsidian-wikilinks.md";
|
||||
let dest = tmp_dir.path().join(PathBuf::from("obsidian-wikilinks.md"));
|
||||
let src_meta = std::fs::metadata(src).unwrap();
|
||||
let dest_meta = std::fs::metadata(dest).unwrap();
|
||||
|
||||
assert_ne!(src_meta.modified().unwrap(), dest_meta.modified().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_non_ascii_filenames() {
|
||||
let tmp_dir = TempDir::new().expect("failed to make tempdir");
|
||||
|
11
tests/testdata/expected/main-samples/math.md
vendored
Normal file
11
tests/testdata/expected/main-samples/math.md
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
This sentence uses `$` delimiters to show math inline: $\sqrt{3x-1}+(1+x)^2$
|
||||
|
||||
This is the same math expression expressed as a block element:
|
||||
$$\sqrt{3x-1}+(1+x)^2$$
|
||||
|
||||
<!-- https://github.com/zoni/obsidian-export/issues/14 -->
|
||||
|
||||
With square brackets (inline): $[0, 2\pi]$
|
||||
|
||||
With square brackets (block):
|
||||
$$[0, 2\pi]$$
|
@ -37,7 +37,7 @@
|
||||
~~Strikethrough~~
|
||||
|
||||
|Table||
|
||||
|-----|--|
|
||||
|-----|-|
|
||||
|Foo|Bar|
|
||||
|
||||
[link text](link-location.md)
|
||||
|
10
tests/testdata/input/main-samples/math.md
vendored
Normal file
10
tests/testdata/input/main-samples/math.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
This sentence uses `$` delimiters to show math inline: $\sqrt{3x-1}+(1+x)^2$
|
||||
|
||||
This is the same math expression expressed as a block element:
|
||||
$$\sqrt{3x-1}+(1+x)^2$$
|
||||
|
||||
<!-- https://github.com/zoni/obsidian-export/issues/14 -->
|
||||
With square brackets (inline): $[0, 2\pi]$
|
||||
|
||||
With square brackets (block):
|
||||
$$[0, 2\pi]$$
|
33
towncrier.toml
Normal file
33
towncrier.toml
Normal file
@ -0,0 +1,33 @@
|
||||
[tool.towncrier]
|
||||
name = "obsidian-export"
|
||||
directory = "changelog.d"
|
||||
filename = "CHANGELOG.md"
|
||||
start_string = "<!-- towncrier release notes start -->\n"
|
||||
underlines = ["", "", ""]
|
||||
title_format = "## [{version}](https://github.com/zoni/obsidian-export/tree/{version}) - {project_date}"
|
||||
issue_format = "[#{issue}](https://github.com/zoni/obsidian-export/issues/{issue})"
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "new"
|
||||
name = "New Features"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "change"
|
||||
name = "Changes"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "fix"
|
||||
name = "Fixes"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "breaking"
|
||||
name = "Backwards-incompatible Changes"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "deprecation"
|
||||
name = "Deprecations"
|
||||
showcontent = true
|
Loading…
Reference in New Issue
Block a user