bibsync 0.3.5__tar.gz → 0.4.0__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.
- {bibsync-0.3.5 → bibsync-0.4.0}/.pre-commit-config.yaml +2 -2
- {bibsync-0.3.5 → bibsync-0.4.0}/CITATION.cff +2 -2
- {bibsync-0.3.5 → bibsync-0.4.0}/Cargo.lock +55 -262
- {bibsync-0.3.5 → bibsync-0.4.0}/Cargo.toml +2 -2
- {bibsync-0.3.5 → bibsync-0.4.0}/PKG-INFO +23 -6
- {bibsync-0.3.5 → bibsync-0.4.0}/README.md +22 -5
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/user-guide/usage.md +32 -2
- {bibsync-0.3.5 → bibsync-0.4.0}/src/cli.rs +2 -2
- {bibsync-0.3.5 → bibsync-0.4.0}/src/lib.rs +221 -8
- {bibsync-0.3.5 → bibsync-0.4.0}/tests/cli.rs +27 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/.gitignore +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/.markdownlint.yaml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/.pre-commit-hooks.yaml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/.prettierrc +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/.typos.toml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/CODE_OF_CONDUCT.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/CONTRIBUTING.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/LICENSE +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/SECURITY.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/SUPPORT.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/benches/greeting.rs +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/cliff.toml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/deny.toml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/api/index.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/contributing.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/index.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/security.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/user-guide/examples.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/user-guide/installation.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/user-guide/pre-commit.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/docs/user-guide/providers.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/examples/README.md +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/examples/greet.rs +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/examples/inspire-main.bib +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/examples/inspire-main.tex +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/examples/main.bib +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/examples/main.tex +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/pyproject.toml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/python/bibsync/__init__.py +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/python/bibsync/__init__.pyi +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/python/bibsync/__main__.py +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/python/bibsync/py.typed +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/renovate.json +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/rust-toolchain.toml +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/scripts/pre-commit-bibsync +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/setup_repo.sh +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/src/main.rs +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/src/python.rs +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/tests/examples.rs +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/tests/python/test_bindings.py +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/uv.lock +0 -0
- {bibsync-0.3.5 → bibsync-0.4.0}/zensical.toml +0 -0
|
@@ -31,14 +31,14 @@ repos:
|
|
|
31
31
|
pass_filenames: false
|
|
32
32
|
|
|
33
33
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
34
|
-
rev: v0.15.
|
|
34
|
+
rev: v0.15.18
|
|
35
35
|
hooks:
|
|
36
36
|
- id: ruff
|
|
37
37
|
args: [--fix, --config=pyproject.toml]
|
|
38
38
|
- id: ruff-format
|
|
39
39
|
|
|
40
40
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
41
|
-
rev: 0.11.
|
|
41
|
+
rev: 0.11.23
|
|
42
42
|
hooks:
|
|
43
43
|
- id: uv-lock
|
|
44
44
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
cff-version: 1.2.0
|
|
2
2
|
title: "bibsync: A Rust package to automatically resolve, synchronize, and validate LaTeX citations across BibTeX databases"
|
|
3
|
-
version: "0.
|
|
4
|
-
date-released: "2026-06-
|
|
3
|
+
version: "0.4.0"
|
|
4
|
+
date-released: "2026-06-22"
|
|
5
5
|
license: "BSD-3-Clause"
|
|
6
6
|
type: software
|
|
7
7
|
authors:
|
|
@@ -61,12 +61,6 @@ dependencies = [
|
|
|
61
61
|
"windows-sys 0.61.2",
|
|
62
62
|
]
|
|
63
63
|
|
|
64
|
-
[[package]]
|
|
65
|
-
name = "anyhow"
|
|
66
|
-
version = "1.0.102"
|
|
67
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
68
|
-
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
|
69
|
-
|
|
70
64
|
[[package]]
|
|
71
65
|
name = "assert_cmd"
|
|
72
66
|
version = "2.2.2"
|
|
@@ -124,7 +118,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
|
124
118
|
|
|
125
119
|
[[package]]
|
|
126
120
|
name = "bibsync"
|
|
127
|
-
version = "0.
|
|
121
|
+
version = "0.4.0"
|
|
128
122
|
dependencies = [
|
|
129
123
|
"assert_cmd",
|
|
130
124
|
"clap",
|
|
@@ -164,15 +158,15 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
|
|
164
158
|
|
|
165
159
|
[[package]]
|
|
166
160
|
name = "bytes"
|
|
167
|
-
version = "1.
|
|
161
|
+
version = "1.12.0"
|
|
168
162
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
169
|
-
checksum = "
|
|
163
|
+
checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
|
|
170
164
|
|
|
171
165
|
[[package]]
|
|
172
166
|
name = "cc"
|
|
173
|
-
version = "1.2.
|
|
167
|
+
version = "1.2.65"
|
|
174
168
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
175
|
-
checksum = "
|
|
169
|
+
checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
|
|
176
170
|
dependencies = [
|
|
177
171
|
"find-msvc-tools",
|
|
178
172
|
"jobserver",
|
|
@@ -328,12 +322,6 @@ version = "1.0.5"
|
|
|
328
322
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
329
323
|
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
|
330
324
|
|
|
331
|
-
[[package]]
|
|
332
|
-
name = "equivalent"
|
|
333
|
-
version = "1.0.2"
|
|
334
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
335
|
-
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
336
|
-
|
|
337
325
|
[[package]]
|
|
338
326
|
name = "errno"
|
|
339
327
|
version = "0.3.14"
|
|
@@ -365,12 +353,6 @@ dependencies = [
|
|
|
365
353
|
"num-traits",
|
|
366
354
|
]
|
|
367
355
|
|
|
368
|
-
[[package]]
|
|
369
|
-
name = "foldhash"
|
|
370
|
-
version = "0.1.5"
|
|
371
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
372
|
-
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
|
373
|
-
|
|
374
356
|
[[package]]
|
|
375
357
|
name = "form_urlencoded"
|
|
376
358
|
version = "1.2.2"
|
|
@@ -464,32 +446,15 @@ dependencies = [
|
|
|
464
446
|
|
|
465
447
|
[[package]]
|
|
466
448
|
name = "getrandom"
|
|
467
|
-
version = "0.4.
|
|
449
|
+
version = "0.4.3"
|
|
468
450
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
469
|
-
checksum = "
|
|
451
|
+
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
|
470
452
|
dependencies = [
|
|
471
453
|
"cfg-if",
|
|
472
454
|
"libc",
|
|
473
455
|
"r-efi 6.0.0",
|
|
474
|
-
"wasip2",
|
|
475
|
-
"wasip3",
|
|
476
456
|
]
|
|
477
457
|
|
|
478
|
-
[[package]]
|
|
479
|
-
name = "hashbrown"
|
|
480
|
-
version = "0.15.5"
|
|
481
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
482
|
-
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
|
483
|
-
dependencies = [
|
|
484
|
-
"foldhash",
|
|
485
|
-
]
|
|
486
|
-
|
|
487
|
-
[[package]]
|
|
488
|
-
name = "hashbrown"
|
|
489
|
-
version = "0.17.1"
|
|
490
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
491
|
-
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|
492
|
-
|
|
493
458
|
[[package]]
|
|
494
459
|
name = "heck"
|
|
495
460
|
version = "0.5.0"
|
|
@@ -674,12 +639,6 @@ dependencies = [
|
|
|
674
639
|
"zerovec",
|
|
675
640
|
]
|
|
676
641
|
|
|
677
|
-
[[package]]
|
|
678
|
-
name = "id-arena"
|
|
679
|
-
version = "2.3.0"
|
|
680
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
681
|
-
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
|
682
|
-
|
|
683
642
|
[[package]]
|
|
684
643
|
name = "idna"
|
|
685
644
|
version = "1.1.0"
|
|
@@ -701,18 +660,6 @@ dependencies = [
|
|
|
701
660
|
"icu_properties",
|
|
702
661
|
]
|
|
703
662
|
|
|
704
|
-
[[package]]
|
|
705
|
-
name = "indexmap"
|
|
706
|
-
version = "2.14.0"
|
|
707
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
708
|
-
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
|
709
|
-
dependencies = [
|
|
710
|
-
"equivalent",
|
|
711
|
-
"hashbrown 0.17.1",
|
|
712
|
-
"serde",
|
|
713
|
-
"serde_core",
|
|
714
|
-
]
|
|
715
|
-
|
|
716
663
|
[[package]]
|
|
717
664
|
name = "ipnet"
|
|
718
665
|
version = "2.12.0"
|
|
@@ -792,21 +739,15 @@ dependencies = [
|
|
|
792
739
|
|
|
793
740
|
[[package]]
|
|
794
741
|
name = "js-sys"
|
|
795
|
-
version = "0.3.
|
|
742
|
+
version = "0.3.102"
|
|
796
743
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
797
|
-
checksum = "
|
|
744
|
+
checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
|
|
798
745
|
dependencies = [
|
|
799
746
|
"cfg-if",
|
|
800
747
|
"futures-util",
|
|
801
748
|
"wasm-bindgen",
|
|
802
749
|
]
|
|
803
750
|
|
|
804
|
-
[[package]]
|
|
805
|
-
name = "leb128fmt"
|
|
806
|
-
version = "0.1.0"
|
|
807
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
808
|
-
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|
809
|
-
|
|
810
751
|
[[package]]
|
|
811
752
|
name = "libc"
|
|
812
753
|
version = "0.2.186"
|
|
@@ -827,9 +768,9 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
|
|
|
827
768
|
|
|
828
769
|
[[package]]
|
|
829
770
|
name = "log"
|
|
830
|
-
version = "0.4.
|
|
771
|
+
version = "0.4.33"
|
|
831
772
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
832
|
-
checksum = "
|
|
773
|
+
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
|
|
833
774
|
|
|
834
775
|
[[package]]
|
|
835
776
|
name = "lru-slab"
|
|
@@ -839,9 +780,9 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
|
|
839
780
|
|
|
840
781
|
[[package]]
|
|
841
782
|
name = "memchr"
|
|
842
|
-
version = "2.8.
|
|
783
|
+
version = "2.8.2"
|
|
843
784
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
844
|
-
checksum = "
|
|
785
|
+
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
|
|
845
786
|
|
|
846
787
|
[[package]]
|
|
847
788
|
name = "mio"
|
|
@@ -953,16 +894,6 @@ dependencies = [
|
|
|
953
894
|
"termtree",
|
|
954
895
|
]
|
|
955
896
|
|
|
956
|
-
[[package]]
|
|
957
|
-
name = "prettyplease"
|
|
958
|
-
version = "0.2.37"
|
|
959
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
960
|
-
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
|
961
|
-
dependencies = [
|
|
962
|
-
"proc-macro2",
|
|
963
|
-
"syn",
|
|
964
|
-
]
|
|
965
|
-
|
|
966
897
|
[[package]]
|
|
967
898
|
name = "proc-macro2"
|
|
968
899
|
version = "1.0.106"
|
|
@@ -974,9 +905,9 @@ dependencies = [
|
|
|
974
905
|
|
|
975
906
|
[[package]]
|
|
976
907
|
name = "pyo3"
|
|
977
|
-
version = "0.
|
|
908
|
+
version = "0.29.0"
|
|
978
909
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
979
|
-
checksum = "
|
|
910
|
+
checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c"
|
|
980
911
|
dependencies = [
|
|
981
912
|
"libc",
|
|
982
913
|
"once_cell",
|
|
@@ -988,18 +919,18 @@ dependencies = [
|
|
|
988
919
|
|
|
989
920
|
[[package]]
|
|
990
921
|
name = "pyo3-build-config"
|
|
991
|
-
version = "0.
|
|
922
|
+
version = "0.29.0"
|
|
992
923
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
993
|
-
checksum = "
|
|
924
|
+
checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078"
|
|
994
925
|
dependencies = [
|
|
995
926
|
"target-lexicon",
|
|
996
927
|
]
|
|
997
928
|
|
|
998
929
|
[[package]]
|
|
999
930
|
name = "pyo3-ffi"
|
|
1000
|
-
version = "0.
|
|
931
|
+
version = "0.29.0"
|
|
1001
932
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1002
|
-
checksum = "
|
|
933
|
+
checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b"
|
|
1003
934
|
dependencies = [
|
|
1004
935
|
"libc",
|
|
1005
936
|
"pyo3-build-config",
|
|
@@ -1007,9 +938,9 @@ dependencies = [
|
|
|
1007
938
|
|
|
1008
939
|
[[package]]
|
|
1009
940
|
name = "pyo3-macros"
|
|
1010
|
-
version = "0.
|
|
941
|
+
version = "0.29.0"
|
|
1011
942
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1012
|
-
checksum = "
|
|
943
|
+
checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771"
|
|
1013
944
|
dependencies = [
|
|
1014
945
|
"proc-macro2",
|
|
1015
946
|
"pyo3-macros-backend",
|
|
@@ -1019,13 +950,12 @@ dependencies = [
|
|
|
1019
950
|
|
|
1020
951
|
[[package]]
|
|
1021
952
|
name = "pyo3-macros-backend"
|
|
1022
|
-
version = "0.
|
|
953
|
+
version = "0.29.0"
|
|
1023
954
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1024
|
-
checksum = "
|
|
955
|
+
checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362"
|
|
1025
956
|
dependencies = [
|
|
1026
957
|
"heck",
|
|
1027
958
|
"proc-macro2",
|
|
1028
|
-
"pyo3-build-config",
|
|
1029
959
|
"quote",
|
|
1030
960
|
"syn",
|
|
1031
961
|
]
|
|
@@ -1088,9 +1018,9 @@ dependencies = [
|
|
|
1088
1018
|
|
|
1089
1019
|
[[package]]
|
|
1090
1020
|
name = "quote"
|
|
1091
|
-
version = "1.0.
|
|
1021
|
+
version = "1.0.46"
|
|
1092
1022
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1093
|
-
checksum = "
|
|
1023
|
+
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
|
1094
1024
|
dependencies = [
|
|
1095
1025
|
"proc-macro2",
|
|
1096
1026
|
]
|
|
@@ -1138,9 +1068,9 @@ dependencies = [
|
|
|
1138
1068
|
|
|
1139
1069
|
[[package]]
|
|
1140
1070
|
name = "regex"
|
|
1141
|
-
version = "1.12.
|
|
1071
|
+
version = "1.12.4"
|
|
1142
1072
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1143
|
-
checksum = "
|
|
1073
|
+
checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
|
|
1144
1074
|
dependencies = [
|
|
1145
1075
|
"aho-corasick",
|
|
1146
1076
|
"memchr",
|
|
@@ -1167,9 +1097,9 @@ checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973"
|
|
|
1167
1097
|
|
|
1168
1098
|
[[package]]
|
|
1169
1099
|
name = "regex-syntax"
|
|
1170
|
-
version = "0.8.
|
|
1100
|
+
version = "0.8.11"
|
|
1171
1101
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1172
|
-
checksum = "
|
|
1102
|
+
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
|
1173
1103
|
|
|
1174
1104
|
[[package]]
|
|
1175
1105
|
name = "reqwest"
|
|
@@ -1472,9 +1402,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
|
|
1472
1402
|
|
|
1473
1403
|
[[package]]
|
|
1474
1404
|
name = "smallvec"
|
|
1475
|
-
version = "1.15.
|
|
1405
|
+
version = "1.15.2"
|
|
1476
1406
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1477
|
-
checksum = "
|
|
1407
|
+
checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
|
|
1478
1408
|
|
|
1479
1409
|
[[package]]
|
|
1480
1410
|
name = "socket2"
|
|
@@ -1506,9 +1436,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|
|
1506
1436
|
|
|
1507
1437
|
[[package]]
|
|
1508
1438
|
name = "syn"
|
|
1509
|
-
version = "2.0.
|
|
1439
|
+
version = "2.0.118"
|
|
1510
1440
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1511
|
-
checksum = "
|
|
1441
|
+
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
|
1512
1442
|
dependencies = [
|
|
1513
1443
|
"proc-macro2",
|
|
1514
1444
|
"quote",
|
|
@@ -1548,7 +1478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
1548
1478
|
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
|
1549
1479
|
dependencies = [
|
|
1550
1480
|
"fastrand",
|
|
1551
|
-
"getrandom 0.4.
|
|
1481
|
+
"getrandom 0.4.3",
|
|
1552
1482
|
"once_cell",
|
|
1553
1483
|
"rustix",
|
|
1554
1484
|
"windows-sys 0.61.2",
|
|
@@ -1715,12 +1645,6 @@ version = "1.0.24"
|
|
|
1715
1645
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1716
1646
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
1717
1647
|
|
|
1718
|
-
[[package]]
|
|
1719
|
-
name = "unicode-xid"
|
|
1720
|
-
version = "0.2.6"
|
|
1721
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1722
|
-
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
1723
|
-
|
|
1724
1648
|
[[package]]
|
|
1725
1649
|
name = "untrusted"
|
|
1726
1650
|
version = "0.9.0"
|
|
@@ -1791,23 +1715,14 @@ version = "1.0.1+wasi-0.2.4"
|
|
|
1791
1715
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1792
1716
|
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
|
1793
1717
|
dependencies = [
|
|
1794
|
-
"wit-bindgen
|
|
1795
|
-
]
|
|
1796
|
-
|
|
1797
|
-
[[package]]
|
|
1798
|
-
name = "wasip3"
|
|
1799
|
-
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
|
1800
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1801
|
-
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
|
1802
|
-
dependencies = [
|
|
1803
|
-
"wit-bindgen 0.51.0",
|
|
1718
|
+
"wit-bindgen",
|
|
1804
1719
|
]
|
|
1805
1720
|
|
|
1806
1721
|
[[package]]
|
|
1807
1722
|
name = "wasm-bindgen"
|
|
1808
|
-
version = "0.2.
|
|
1723
|
+
version = "0.2.125"
|
|
1809
1724
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1810
|
-
checksum = "
|
|
1725
|
+
checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
|
|
1811
1726
|
dependencies = [
|
|
1812
1727
|
"cfg-if",
|
|
1813
1728
|
"once_cell",
|
|
@@ -1818,9 +1733,9 @@ dependencies = [
|
|
|
1818
1733
|
|
|
1819
1734
|
[[package]]
|
|
1820
1735
|
name = "wasm-bindgen-futures"
|
|
1821
|
-
version = "0.4.
|
|
1736
|
+
version = "0.4.75"
|
|
1822
1737
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1823
|
-
checksum = "
|
|
1738
|
+
checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
|
|
1824
1739
|
dependencies = [
|
|
1825
1740
|
"js-sys",
|
|
1826
1741
|
"wasm-bindgen",
|
|
@@ -1828,9 +1743,9 @@ dependencies = [
|
|
|
1828
1743
|
|
|
1829
1744
|
[[package]]
|
|
1830
1745
|
name = "wasm-bindgen-macro"
|
|
1831
|
-
version = "0.2.
|
|
1746
|
+
version = "0.2.125"
|
|
1832
1747
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1833
|
-
checksum = "
|
|
1748
|
+
checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
|
|
1834
1749
|
dependencies = [
|
|
1835
1750
|
"quote",
|
|
1836
1751
|
"wasm-bindgen-macro-support",
|
|
@@ -1838,9 +1753,9 @@ dependencies = [
|
|
|
1838
1753
|
|
|
1839
1754
|
[[package]]
|
|
1840
1755
|
name = "wasm-bindgen-macro-support"
|
|
1841
|
-
version = "0.2.
|
|
1756
|
+
version = "0.2.125"
|
|
1842
1757
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1843
|
-
checksum = "
|
|
1758
|
+
checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
|
|
1844
1759
|
dependencies = [
|
|
1845
1760
|
"bumpalo",
|
|
1846
1761
|
"proc-macro2",
|
|
@@ -1851,52 +1766,18 @@ dependencies = [
|
|
|
1851
1766
|
|
|
1852
1767
|
[[package]]
|
|
1853
1768
|
name = "wasm-bindgen-shared"
|
|
1854
|
-
version = "0.2.
|
|
1769
|
+
version = "0.2.125"
|
|
1855
1770
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1856
|
-
checksum = "
|
|
1771
|
+
checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
|
|
1857
1772
|
dependencies = [
|
|
1858
1773
|
"unicode-ident",
|
|
1859
1774
|
]
|
|
1860
1775
|
|
|
1861
|
-
[[package]]
|
|
1862
|
-
name = "wasm-encoder"
|
|
1863
|
-
version = "0.244.0"
|
|
1864
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1865
|
-
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
|
1866
|
-
dependencies = [
|
|
1867
|
-
"leb128fmt",
|
|
1868
|
-
"wasmparser",
|
|
1869
|
-
]
|
|
1870
|
-
|
|
1871
|
-
[[package]]
|
|
1872
|
-
name = "wasm-metadata"
|
|
1873
|
-
version = "0.244.0"
|
|
1874
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1875
|
-
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
|
1876
|
-
dependencies = [
|
|
1877
|
-
"anyhow",
|
|
1878
|
-
"indexmap",
|
|
1879
|
-
"wasm-encoder",
|
|
1880
|
-
"wasmparser",
|
|
1881
|
-
]
|
|
1882
|
-
|
|
1883
|
-
[[package]]
|
|
1884
|
-
name = "wasmparser"
|
|
1885
|
-
version = "0.244.0"
|
|
1886
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1887
|
-
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
|
1888
|
-
dependencies = [
|
|
1889
|
-
"bitflags",
|
|
1890
|
-
"hashbrown 0.15.5",
|
|
1891
|
-
"indexmap",
|
|
1892
|
-
"semver",
|
|
1893
|
-
]
|
|
1894
|
-
|
|
1895
1776
|
[[package]]
|
|
1896
1777
|
name = "web-sys"
|
|
1897
|
-
version = "0.3.
|
|
1778
|
+
version = "0.3.102"
|
|
1898
1779
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1899
|
-
checksum = "
|
|
1780
|
+
checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
|
|
1900
1781
|
dependencies = [
|
|
1901
1782
|
"js-sys",
|
|
1902
1783
|
"wasm-bindgen",
|
|
@@ -1914,9 +1795,9 @@ dependencies = [
|
|
|
1914
1795
|
|
|
1915
1796
|
[[package]]
|
|
1916
1797
|
name = "webpki-root-certs"
|
|
1917
|
-
version = "1.0.
|
|
1798
|
+
version = "1.0.8"
|
|
1918
1799
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1919
|
-
checksum = "
|
|
1800
|
+
checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267"
|
|
1920
1801
|
dependencies = [
|
|
1921
1802
|
"rustls-pki-types",
|
|
1922
1803
|
]
|
|
@@ -2098,94 +1979,6 @@ version = "0.46.0"
|
|
|
2098
1979
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2099
1980
|
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
|
2100
1981
|
|
|
2101
|
-
[[package]]
|
|
2102
|
-
name = "wit-bindgen"
|
|
2103
|
-
version = "0.51.0"
|
|
2104
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2105
|
-
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
|
2106
|
-
dependencies = [
|
|
2107
|
-
"wit-bindgen-rust-macro",
|
|
2108
|
-
]
|
|
2109
|
-
|
|
2110
|
-
[[package]]
|
|
2111
|
-
name = "wit-bindgen-core"
|
|
2112
|
-
version = "0.51.0"
|
|
2113
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2114
|
-
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
|
2115
|
-
dependencies = [
|
|
2116
|
-
"anyhow",
|
|
2117
|
-
"heck",
|
|
2118
|
-
"wit-parser",
|
|
2119
|
-
]
|
|
2120
|
-
|
|
2121
|
-
[[package]]
|
|
2122
|
-
name = "wit-bindgen-rust"
|
|
2123
|
-
version = "0.51.0"
|
|
2124
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2125
|
-
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
|
2126
|
-
dependencies = [
|
|
2127
|
-
"anyhow",
|
|
2128
|
-
"heck",
|
|
2129
|
-
"indexmap",
|
|
2130
|
-
"prettyplease",
|
|
2131
|
-
"syn",
|
|
2132
|
-
"wasm-metadata",
|
|
2133
|
-
"wit-bindgen-core",
|
|
2134
|
-
"wit-component",
|
|
2135
|
-
]
|
|
2136
|
-
|
|
2137
|
-
[[package]]
|
|
2138
|
-
name = "wit-bindgen-rust-macro"
|
|
2139
|
-
version = "0.51.0"
|
|
2140
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2141
|
-
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
|
2142
|
-
dependencies = [
|
|
2143
|
-
"anyhow",
|
|
2144
|
-
"prettyplease",
|
|
2145
|
-
"proc-macro2",
|
|
2146
|
-
"quote",
|
|
2147
|
-
"syn",
|
|
2148
|
-
"wit-bindgen-core",
|
|
2149
|
-
"wit-bindgen-rust",
|
|
2150
|
-
]
|
|
2151
|
-
|
|
2152
|
-
[[package]]
|
|
2153
|
-
name = "wit-component"
|
|
2154
|
-
version = "0.244.0"
|
|
2155
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2156
|
-
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
|
2157
|
-
dependencies = [
|
|
2158
|
-
"anyhow",
|
|
2159
|
-
"bitflags",
|
|
2160
|
-
"indexmap",
|
|
2161
|
-
"log",
|
|
2162
|
-
"serde",
|
|
2163
|
-
"serde_derive",
|
|
2164
|
-
"serde_json",
|
|
2165
|
-
"wasm-encoder",
|
|
2166
|
-
"wasm-metadata",
|
|
2167
|
-
"wasmparser",
|
|
2168
|
-
"wit-parser",
|
|
2169
|
-
]
|
|
2170
|
-
|
|
2171
|
-
[[package]]
|
|
2172
|
-
name = "wit-parser"
|
|
2173
|
-
version = "0.244.0"
|
|
2174
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2175
|
-
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
|
2176
|
-
dependencies = [
|
|
2177
|
-
"anyhow",
|
|
2178
|
-
"id-arena",
|
|
2179
|
-
"indexmap",
|
|
2180
|
-
"log",
|
|
2181
|
-
"semver",
|
|
2182
|
-
"serde",
|
|
2183
|
-
"serde_derive",
|
|
2184
|
-
"serde_json",
|
|
2185
|
-
"unicode-xid",
|
|
2186
|
-
"wasmparser",
|
|
2187
|
-
]
|
|
2188
|
-
|
|
2189
1982
|
[[package]]
|
|
2190
1983
|
name = "writeable"
|
|
2191
1984
|
version = "0.6.3"
|
|
@@ -2217,18 +2010,18 @@ dependencies = [
|
|
|
2217
2010
|
|
|
2218
2011
|
[[package]]
|
|
2219
2012
|
name = "zerocopy"
|
|
2220
|
-
version = "0.8.
|
|
2013
|
+
version = "0.8.52"
|
|
2221
2014
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2222
|
-
checksum = "
|
|
2015
|
+
checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
|
|
2223
2016
|
dependencies = [
|
|
2224
2017
|
"zerocopy-derive",
|
|
2225
2018
|
]
|
|
2226
2019
|
|
|
2227
2020
|
[[package]]
|
|
2228
2021
|
name = "zerocopy-derive"
|
|
2229
|
-
version = "0.8.
|
|
2022
|
+
version = "0.8.52"
|
|
2230
2023
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2231
|
-
checksum = "
|
|
2024
|
+
checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
|
|
2232
2025
|
dependencies = [
|
|
2233
2026
|
"proc-macro2",
|
|
2234
2027
|
"quote",
|
|
@@ -2258,9 +2051,9 @@ dependencies = [
|
|
|
2258
2051
|
|
|
2259
2052
|
[[package]]
|
|
2260
2053
|
name = "zeroize"
|
|
2261
|
-
version = "1.
|
|
2054
|
+
version = "1.9.0"
|
|
2262
2055
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2263
|
-
checksum = "
|
|
2056
|
+
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
|
2264
2057
|
|
|
2265
2058
|
[[package]]
|
|
2266
2059
|
name = "zerotrie"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "bibsync"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
rust-version = "1.85"
|
|
6
6
|
authors = ["Isaac C. F. Wong"]
|
|
@@ -16,7 +16,7 @@ exclude = ["/.github", "/docs/template_documentation"]
|
|
|
16
16
|
|
|
17
17
|
[dependencies]
|
|
18
18
|
clap = { version = "4.6.1", features = ["derive"] }
|
|
19
|
-
pyo3 = { version = "0.
|
|
19
|
+
pyo3 = { version = "0.29.0", optional = true, features = ["abi3-py312"] }
|
|
20
20
|
regex = "1.12.3"
|
|
21
21
|
reqwest = { version = "0.13.4", default-features = false, features = [
|
|
22
22
|
"blocking",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bibsync
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -65,6 +65,23 @@ NASA ADS and/or InspireHEP, rewrites provider BibTeX entries so the citekey stay
|
|
|
65
65
|
the key used in TeX, and reports whether the output `.bib` file is current. With
|
|
66
66
|
`--fix`, it writes the merged bibliography.
|
|
67
67
|
|
|
68
|
+
Markdown sources are supported too, including
|
|
69
|
+
[Journal of Open Source Software](https://joss.theoj.org/) `paper.md` files.
|
|
70
|
+
`bibsync` reads pandoc citations and the `bibliography` field from the YAML
|
|
71
|
+
frontmatter:
|
|
72
|
+
|
|
73
|
+
```markdown
|
|
74
|
+
---
|
|
75
|
+
bibliography: paper.bib
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
Prior work [@1602.03837; @10.1103/PhysRevLett.116.061102].
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```shell
|
|
82
|
+
bibsync --fix paper.md
|
|
83
|
+
```
|
|
84
|
+
|
|
68
85
|
When a citekey cannot be resolved, the command prints the key together with a
|
|
69
86
|
reason and the likely fix. For example, an unsupported citekey is reported as an
|
|
70
87
|
identifier-format problem, while an arXiv ID or DOI that the provider cannot find
|
|
@@ -117,7 +134,7 @@ For convenience, you can also use:
|
|
|
117
134
|
@software{wong2026bibsync,
|
|
118
135
|
author = {Wong, Isaac C. F.},
|
|
119
136
|
title = {bibsync: A Rust package to automatically resolve, synchronize, and validate LaTeX citations across BibTeX databases},
|
|
120
|
-
version = {v0.
|
|
137
|
+
version = {v0.4.0},
|
|
121
138
|
year = {2026},
|
|
122
139
|
month = jun,
|
|
123
140
|
doi = {10.5281/zenodo.20422622},
|
|
@@ -269,7 +286,7 @@ Use the pre-built binary hook for faster installs:
|
|
|
269
286
|
```yaml
|
|
270
287
|
repos:
|
|
271
288
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
272
|
-
rev: v0.
|
|
289
|
+
rev: v0.4.0
|
|
273
290
|
hooks:
|
|
274
291
|
- id: bibsync-bin
|
|
275
292
|
args: [--cache, --provider, inspire, --output, references.bib]
|
|
@@ -284,7 +301,7 @@ installation:
|
|
|
284
301
|
```yaml
|
|
285
302
|
repos:
|
|
286
303
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
287
|
-
rev: v0.
|
|
304
|
+
rev: v0.4.0
|
|
288
305
|
hooks:
|
|
289
306
|
- id: bibsync
|
|
290
307
|
args: [--provider, inspire, --output, references.bib]
|
|
@@ -296,7 +313,7 @@ writing changes. To let the hook update files, add `--fix` to the hook args:
|
|
|
296
313
|
```yaml
|
|
297
314
|
repos:
|
|
298
315
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
299
|
-
rev: v0.
|
|
316
|
+
rev: v0.4.0
|
|
300
317
|
hooks:
|
|
301
318
|
- id: bibsync-bin
|
|
302
319
|
args: [--fix, --cache, --provider, inspire, --output, references.bib]
|
|
@@ -307,7 +324,7 @@ To skip manually curated entries, add `--ignore-file`:
|
|
|
307
324
|
```yaml
|
|
308
325
|
repos:
|
|
309
326
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
310
|
-
rev: v0.
|
|
327
|
+
rev: v0.4.0
|
|
311
328
|
hooks:
|
|
312
329
|
- id: bibsync-bin
|
|
313
330
|
args:
|
|
@@ -38,6 +38,23 @@ NASA ADS and/or InspireHEP, rewrites provider BibTeX entries so the citekey stay
|
|
|
38
38
|
the key used in TeX, and reports whether the output `.bib` file is current. With
|
|
39
39
|
`--fix`, it writes the merged bibliography.
|
|
40
40
|
|
|
41
|
+
Markdown sources are supported too, including
|
|
42
|
+
[Journal of Open Source Software](https://joss.theoj.org/) `paper.md` files.
|
|
43
|
+
`bibsync` reads pandoc citations and the `bibliography` field from the YAML
|
|
44
|
+
frontmatter:
|
|
45
|
+
|
|
46
|
+
```markdown
|
|
47
|
+
---
|
|
48
|
+
bibliography: paper.bib
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
Prior work [@1602.03837; @10.1103/PhysRevLett.116.061102].
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```shell
|
|
55
|
+
bibsync --fix paper.md
|
|
56
|
+
```
|
|
57
|
+
|
|
41
58
|
When a citekey cannot be resolved, the command prints the key together with a
|
|
42
59
|
reason and the likely fix. For example, an unsupported citekey is reported as an
|
|
43
60
|
identifier-format problem, while an arXiv ID or DOI that the provider cannot find
|
|
@@ -90,7 +107,7 @@ For convenience, you can also use:
|
|
|
90
107
|
@software{wong2026bibsync,
|
|
91
108
|
author = {Wong, Isaac C. F.},
|
|
92
109
|
title = {bibsync: A Rust package to automatically resolve, synchronize, and validate LaTeX citations across BibTeX databases},
|
|
93
|
-
version = {v0.
|
|
110
|
+
version = {v0.4.0},
|
|
94
111
|
year = {2026},
|
|
95
112
|
month = jun,
|
|
96
113
|
doi = {10.5281/zenodo.20422622},
|
|
@@ -242,7 +259,7 @@ Use the pre-built binary hook for faster installs:
|
|
|
242
259
|
```yaml
|
|
243
260
|
repos:
|
|
244
261
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
245
|
-
rev: v0.
|
|
262
|
+
rev: v0.4.0
|
|
246
263
|
hooks:
|
|
247
264
|
- id: bibsync-bin
|
|
248
265
|
args: [--cache, --provider, inspire, --output, references.bib]
|
|
@@ -257,7 +274,7 @@ installation:
|
|
|
257
274
|
```yaml
|
|
258
275
|
repos:
|
|
259
276
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
260
|
-
rev: v0.
|
|
277
|
+
rev: v0.4.0
|
|
261
278
|
hooks:
|
|
262
279
|
- id: bibsync
|
|
263
280
|
args: [--provider, inspire, --output, references.bib]
|
|
@@ -269,7 +286,7 @@ writing changes. To let the hook update files, add `--fix` to the hook args:
|
|
|
269
286
|
```yaml
|
|
270
287
|
repos:
|
|
271
288
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
272
|
-
rev: v0.
|
|
289
|
+
rev: v0.4.0
|
|
273
290
|
hooks:
|
|
274
291
|
- id: bibsync-bin
|
|
275
292
|
args: [--fix, --cache, --provider, inspire, --output, references.bib]
|
|
@@ -280,7 +297,7 @@ To skip manually curated entries, add `--ignore-file`:
|
|
|
280
297
|
```yaml
|
|
281
298
|
repos:
|
|
282
299
|
- repo: https://github.com/isaac-cf-wong/bibsync
|
|
283
|
-
rev: v0.
|
|
300
|
+
rev: v0.4.0
|
|
284
301
|
hooks:
|
|
285
302
|
- id: bibsync-bin
|
|
286
303
|
args:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Usage
|
|
2
2
|
|
|
3
|
-
The main command accepts one or more TeX files, or a single BibTeX
|
|
4
|
-
bibliography-refresh mode:
|
|
3
|
+
The main command accepts one or more TeX or Markdown files, or a single BibTeX
|
|
4
|
+
file in bibliography-refresh mode:
|
|
5
5
|
|
|
6
6
|
```shell
|
|
7
7
|
bibsync [OPTIONS] [FILE]...
|
|
@@ -73,6 +73,36 @@ Use `--output` when you want explicit control:
|
|
|
73
73
|
bibsync main.tex chapter.tex --output references.bib
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
## Markdown And JOSS Papers
|
|
77
|
+
|
|
78
|
+
`bibsync` also scans Markdown sources, including
|
|
79
|
+
[Journal of Open Source Software](https://joss.theoj.org/) `paper.md` files. Files
|
|
80
|
+
ending in `.md` or `.markdown` are parsed for pandoc-style citations and for the
|
|
81
|
+
bibliography declared in the YAML frontmatter:
|
|
82
|
+
|
|
83
|
+
```markdown
|
|
84
|
+
---
|
|
85
|
+
title: "My Software"
|
|
86
|
+
bibliography: paper.bib
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
Background and prior work [@1602.03837; @10.1103/PhysRevLett.116.061102].
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `bibliography` frontmatter field is used as the output file when `--output`
|
|
93
|
+
is not given, matching the way `\bibliography{...}` is discovered in TeX. A single
|
|
94
|
+
value, an inline list (`[a.bib, b.bib]`), and a block list of `-` items are all
|
|
95
|
+
supported.
|
|
96
|
+
|
|
97
|
+
Pandoc citation keys (`@key`, `[@key]`, `[-@key]`, and grouped `[@a; @b]` forms)
|
|
98
|
+
are extracted from the body. Citations inside fenced or inline code spans are
|
|
99
|
+
ignored, and email addresses such as `name@example.com` are not mistaken for
|
|
100
|
+
citations. As with TeX, the most reliable workflow is to cite by identifier:
|
|
101
|
+
|
|
102
|
+
```shell
|
|
103
|
+
bibsync --fix paper.md
|
|
104
|
+
```
|
|
105
|
+
|
|
76
106
|
## Existing Bibliographies
|
|
77
107
|
|
|
78
108
|
By default, `bibsync` leaves existing entries untouched unless they look like
|
|
@@ -10,7 +10,7 @@ use std::path::PathBuf;
|
|
|
10
10
|
#[command(version, about)]
|
|
11
11
|
#[allow(clippy::struct_excessive_bools)]
|
|
12
12
|
struct Cli {
|
|
13
|
-
/// TeX files to scan, or a single BibTeX file to check or update.
|
|
13
|
+
/// TeX or Markdown files to scan, or a single BibTeX file to check or update.
|
|
14
14
|
#[arg(value_name = "FILE")]
|
|
15
15
|
files: Vec<PathBuf>,
|
|
16
16
|
|
|
@@ -122,7 +122,7 @@ where
|
|
|
122
122
|
return 0;
|
|
123
123
|
}
|
|
124
124
|
if cli.files.is_empty() {
|
|
125
|
-
eprintln!("error: at least one TeX file or
|
|
125
|
+
eprintln!("error: at least one TeX file, Markdown file, or BibTeX file is required");
|
|
126
126
|
return 2;
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -525,10 +525,18 @@ fn scan_tex_files(files: &[PathBuf]) -> Result<TexScan> {
|
|
|
525
525
|
let bib_re =
|
|
526
526
|
Regex::new(r"\\(?:no)?bibliography\*?\s*\{([^{}]+)\}").expect("valid bibliography regex");
|
|
527
527
|
let comment_re = Regex::new(r"(?m)(?P<prefix>^|[^\\])%.*$").expect("valid comment regex");
|
|
528
|
+
// Pandoc citation key: `@` preceded by start-of-text or a non-word, non-`@`
|
|
529
|
+
// character (so email addresses like `name@host` are not treated as cites).
|
|
530
|
+
let markdown_cite_re =
|
|
531
|
+
Regex::new(r"(?:^|[^\w@])@([\w][\w:./#$%&+?<>~-]*)").expect("valid markdown cite regex");
|
|
528
532
|
let mut scan = TexScan::default();
|
|
529
533
|
|
|
530
534
|
for file in files {
|
|
531
535
|
let raw = read_to_string(file)?;
|
|
536
|
+
if is_markdown(file) {
|
|
537
|
+
scan_markdown_text(&raw, file, &markdown_cite_re, &mut scan);
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
532
540
|
let text = comment_re.replace_all(&raw, "$prefix");
|
|
533
541
|
for captures in cite_re.captures_iter(&text) {
|
|
534
542
|
for key in captures[1]
|
|
@@ -545,18 +553,161 @@ fn scan_tex_files(files: &[PathBuf]) -> Result<TexScan> {
|
|
|
545
553
|
.map(str::trim)
|
|
546
554
|
.filter(|bib| !bib.is_empty())
|
|
547
555
|
{
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
556
|
+
scan.bibliographies
|
|
557
|
+
.push(resolve_bibliography_path(bib, file));
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
Ok(scan)
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/// Scan a Markdown source (such as a JOSS `paper.md`) for pandoc citations and
|
|
565
|
+
/// the bibliography declared in the YAML frontmatter.
|
|
566
|
+
fn scan_markdown_text(raw: &str, file: &Path, cite_re: &Regex, scan: &mut TexScan) {
|
|
567
|
+
let (frontmatter, body) = split_markdown_frontmatter(raw);
|
|
568
|
+
if let Some(frontmatter) = frontmatter {
|
|
569
|
+
for spec in frontmatter_bibliographies(frontmatter) {
|
|
570
|
+
scan.bibliographies
|
|
571
|
+
.push(resolve_bibliography_path(&spec, file));
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
let body = strip_markdown_code(body);
|
|
575
|
+
for captures in cite_re.captures_iter(&body) {
|
|
576
|
+
let key = captures[1].trim_end_matches(['.', ',', ';', ':', '!', '?']);
|
|
577
|
+
if !key.is_empty() {
|
|
578
|
+
scan.citekeys.insert(key.to_owned());
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
fn is_markdown(path: &Path) -> bool {
|
|
584
|
+
has_extension(path, "md") || has_extension(path, "markdown")
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/// Resolve a bibliography reference to a path, defaulting the extension to `.bib`
|
|
588
|
+
/// and resolving relative paths against the source file's directory.
|
|
589
|
+
fn resolve_bibliography_path(spec: &str, source: &Path) -> PathBuf {
|
|
590
|
+
let mut path = PathBuf::from(spec);
|
|
591
|
+
if path.extension().is_none() {
|
|
592
|
+
path.set_extension("bib");
|
|
593
|
+
}
|
|
594
|
+
if path.is_relative() {
|
|
595
|
+
path = source.parent().unwrap_or_else(|| Path::new(".")).join(path);
|
|
596
|
+
}
|
|
597
|
+
path
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/// Split a Markdown document into its YAML frontmatter and body.
|
|
601
|
+
///
|
|
602
|
+
/// Frontmatter is recognized only when the document opens with a `---` fence on
|
|
603
|
+
/// its first line, closed by a line containing exactly `---` or `...`.
|
|
604
|
+
fn split_markdown_frontmatter(text: &str) -> (Option<&str>, &str) {
|
|
605
|
+
let after_open = text
|
|
606
|
+
.strip_prefix("---\n")
|
|
607
|
+
.or_else(|| text.strip_prefix("---\r\n"));
|
|
608
|
+
let Some(after_open) = after_open else {
|
|
609
|
+
return (None, text);
|
|
610
|
+
};
|
|
611
|
+
let open_len = text.len() - after_open.len();
|
|
612
|
+
let mut offset = 0;
|
|
613
|
+
for line in after_open.split_inclusive('\n') {
|
|
614
|
+
let trimmed = line.trim_end_matches(['\n', '\r']);
|
|
615
|
+
if trimmed == "---" || trimmed == "..." {
|
|
616
|
+
let frontmatter = &after_open[..offset];
|
|
617
|
+
let body = &text[open_len + offset + line.len()..];
|
|
618
|
+
return (Some(frontmatter), body);
|
|
619
|
+
}
|
|
620
|
+
offset += line.len();
|
|
621
|
+
}
|
|
622
|
+
(None, text)
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/// Extract `bibliography` entries from YAML frontmatter.
|
|
626
|
+
///
|
|
627
|
+
/// Supports a single scalar (`bibliography: paper.bib`), an inline list
|
|
628
|
+
/// (`bibliography: [a.bib, b.bib]`), and a block list of `-` items.
|
|
629
|
+
fn frontmatter_bibliographies(frontmatter: &str) -> Vec<String> {
|
|
630
|
+
let mut bibliographies = Vec::new();
|
|
631
|
+
let mut lines = frontmatter.lines().peekable();
|
|
632
|
+
while let Some(line) = lines.next() {
|
|
633
|
+
// Only consider top-level keys so nested `bibliography` fields under
|
|
634
|
+
// other mappings are ignored.
|
|
635
|
+
if line.starts_with([' ', '\t']) {
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
let Some(value) = line.trim().strip_prefix("bibliography:") else {
|
|
639
|
+
continue;
|
|
640
|
+
};
|
|
641
|
+
let value = value.trim();
|
|
642
|
+
if value.is_empty() {
|
|
643
|
+
while let Some(next) = lines.peek() {
|
|
644
|
+
let trimmed = next.trim_start();
|
|
645
|
+
if let Some(item) = trimmed.strip_prefix('-') {
|
|
646
|
+
let item = clean_yaml_scalar(item);
|
|
647
|
+
if !item.is_empty() {
|
|
648
|
+
bibliographies.push(item);
|
|
649
|
+
}
|
|
650
|
+
lines.next();
|
|
651
|
+
} else if trimmed.is_empty() || trimmed.starts_with('#') {
|
|
652
|
+
// Skip blank lines and YAML comments so they do not
|
|
653
|
+
// truncate the bibliography list.
|
|
654
|
+
lines.next();
|
|
655
|
+
} else {
|
|
656
|
+
break;
|
|
551
657
|
}
|
|
552
|
-
|
|
553
|
-
|
|
658
|
+
}
|
|
659
|
+
} else if let Some(inner) = value.strip_prefix('[').and_then(|v| v.strip_suffix(']')) {
|
|
660
|
+
for item in inner.split(',') {
|
|
661
|
+
let item = clean_yaml_scalar(item);
|
|
662
|
+
if !item.is_empty() {
|
|
663
|
+
bibliographies.push(item);
|
|
554
664
|
}
|
|
555
|
-
|
|
665
|
+
}
|
|
666
|
+
} else {
|
|
667
|
+
let value = clean_yaml_scalar(value);
|
|
668
|
+
if !value.is_empty() {
|
|
669
|
+
bibliographies.push(value);
|
|
556
670
|
}
|
|
557
671
|
}
|
|
558
672
|
}
|
|
559
|
-
|
|
673
|
+
bibliographies
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
fn clean_yaml_scalar(value: &str) -> String {
|
|
677
|
+
let value = value.trim();
|
|
678
|
+
// Quoted scalars are taken verbatim; a `#` inside quotes is not a comment.
|
|
679
|
+
if let Some(rest) = value.strip_prefix('\'') {
|
|
680
|
+
if let Some(end) = rest.find('\'') {
|
|
681
|
+
return rest[..end].trim().to_owned();
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if let Some(rest) = value.strip_prefix('"') {
|
|
685
|
+
if let Some(end) = rest.find('"') {
|
|
686
|
+
return rest[..end].trim().to_owned();
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
// Unquoted: strip a trailing YAML comment (a `#` preceded by whitespace or
|
|
690
|
+
// at the start of the value), leaving `#` that is part of the value alone.
|
|
691
|
+
strip_yaml_comment(value).trim().to_owned()
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
fn strip_yaml_comment(value: &str) -> &str {
|
|
695
|
+
let bytes = value.as_bytes();
|
|
696
|
+
for (index, &byte) in bytes.iter().enumerate() {
|
|
697
|
+
if byte == b'#' && (index == 0 || bytes[index - 1].is_ascii_whitespace()) {
|
|
698
|
+
return &value[..index];
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
value
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/// Replace fenced and inline code spans with blanks so `@`-prefixed tokens in
|
|
705
|
+
/// code (for example Python decorators) are not mistaken for citations.
|
|
706
|
+
fn strip_markdown_code(text: &str) -> String {
|
|
707
|
+
let fenced = Regex::new(r"(?s)```.*?```|~~~.*?~~~").expect("valid fenced code regex");
|
|
708
|
+
let inline = Regex::new(r"`[^`\n]*`").expect("valid inline code regex");
|
|
709
|
+
let stripped = fenced.replace_all(text, " ");
|
|
710
|
+
inline.replace_all(&stripped, " ").into_owned()
|
|
560
711
|
}
|
|
561
712
|
|
|
562
713
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
@@ -1611,7 +1762,7 @@ pub fn pre_commit_hook_manifest(ignore_file: Option<&Path>) -> String {
|
|
|
1611
1762
|
"bibsync".to_owned()
|
|
1612
1763
|
};
|
|
1613
1764
|
format!(
|
|
1614
|
-
"- id: bibsync\n name: bibsync\n description: Synchronize BibTeX entries from TeX citation keys\n entry: {entry}\n language: rust\n types_or: [tex, bib]\n"
|
|
1765
|
+
"- id: bibsync\n name: bibsync\n description: Synchronize BibTeX entries from TeX citation keys\n entry: {entry}\n language: rust\n types_or: [tex, markdown, bib]\n"
|
|
1615
1766
|
)
|
|
1616
1767
|
}
|
|
1617
1768
|
|
|
@@ -1681,6 +1832,68 @@ mod tests {
|
|
|
1681
1832
|
assert!(!keys.contains("ignored"));
|
|
1682
1833
|
}
|
|
1683
1834
|
|
|
1835
|
+
#[test]
|
|
1836
|
+
fn scans_joss_markdown_citations_and_bibliography() {
|
|
1837
|
+
let dir = tempdir().expect("tempdir");
|
|
1838
|
+
let paper = dir.path().join("paper.md");
|
|
1839
|
+
std::fs::write(
|
|
1840
|
+
&paper,
|
|
1841
|
+
"---\n\
|
|
1842
|
+
title: 'Example'\n\
|
|
1843
|
+
authors:\n\
|
|
1844
|
+
\x20\x20- name: A. Researcher\n\
|
|
1845
|
+
\x20\x20\x20\x20email: a@example.com\n\
|
|
1846
|
+
bibliography: paper.bib\n\
|
|
1847
|
+
---\n\
|
|
1848
|
+
\n\
|
|
1849
|
+
Some prose citing [@2404.14498] and @arXiv:2312.00752.\n\
|
|
1850
|
+
A grouped cite [see @10.1234/example; @2404.14498].\n\
|
|
1851
|
+
\n\
|
|
1852
|
+
```python\n\
|
|
1853
|
+
@decorator\n\
|
|
1854
|
+
def f():\n\
|
|
1855
|
+
\x20\x20\x20\x20pass\n\
|
|
1856
|
+
```\n\
|
|
1857
|
+
Inline `@inline.code` is ignored too.\n",
|
|
1858
|
+
)
|
|
1859
|
+
.expect("write paper.md");
|
|
1860
|
+
|
|
1861
|
+
let scan = super::scan_tex_files(std::slice::from_ref(&paper)).expect("scan markdown");
|
|
1862
|
+
assert!(scan.citekeys.contains("2404.14498"));
|
|
1863
|
+
assert!(scan.citekeys.contains("arXiv:2312.00752"));
|
|
1864
|
+
assert!(scan.citekeys.contains("10.1234/example"));
|
|
1865
|
+
assert!(!scan.citekeys.contains("decorator"));
|
|
1866
|
+
assert!(!scan.citekeys.contains("inline.code"));
|
|
1867
|
+
assert!(!scan.citekeys.iter().any(|key| key.contains("example.com")));
|
|
1868
|
+
assert_eq!(scan.bibliographies, vec![dir.path().join("paper.bib")]);
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
#[test]
|
|
1872
|
+
fn frontmatter_bibliography_supports_lists() {
|
|
1873
|
+
let inline = super::frontmatter_bibliographies("bibliography: [a.bib, 'b.bib']");
|
|
1874
|
+
assert_eq!(inline, vec!["a.bib".to_owned(), "b.bib".to_owned()]);
|
|
1875
|
+
|
|
1876
|
+
let block = super::frontmatter_bibliographies(
|
|
1877
|
+
"title: x\nbibliography:\n - a.bib\n - b.bib\nother: y",
|
|
1878
|
+
);
|
|
1879
|
+
assert_eq!(block, vec!["a.bib".to_owned(), "b.bib".to_owned()]);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
#[test]
|
|
1883
|
+
fn frontmatter_bibliography_strips_yaml_comments() {
|
|
1884
|
+
let scalar = super::frontmatter_bibliographies("bibliography: paper.bib # the refs");
|
|
1885
|
+
assert_eq!(scalar, vec!["paper.bib".to_owned()]);
|
|
1886
|
+
|
|
1887
|
+
let block = super::frontmatter_bibliographies(
|
|
1888
|
+
"bibliography:\n # primary\n - a.bib # main\n - b.bib\n",
|
|
1889
|
+
);
|
|
1890
|
+
assert_eq!(block, vec!["a.bib".to_owned(), "b.bib".to_owned()]);
|
|
1891
|
+
|
|
1892
|
+
// A `#` without preceding whitespace, or inside quotes, is part of the value.
|
|
1893
|
+
let hash = super::frontmatter_bibliographies("bibliography: 'paper #1.bib'");
|
|
1894
|
+
assert_eq!(hash, vec!["paper #1.bib".to_owned()]);
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1684
1897
|
#[test]
|
|
1685
1898
|
fn syncs_arxiv_key_to_output_bib() {
|
|
1686
1899
|
let dir = tempdir().expect("tempdir");
|
|
@@ -49,6 +49,33 @@ fn cli_defaults_to_check_mode() {
|
|
|
49
49
|
));
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
#[test]
|
|
53
|
+
fn cli_scans_joss_markdown_paper() {
|
|
54
|
+
let dir = tempdir().expect("tempdir");
|
|
55
|
+
let paper = dir.path().join("paper.md");
|
|
56
|
+
let bib = dir.path().join("refs.bib");
|
|
57
|
+
std::fs::write(
|
|
58
|
+
&paper,
|
|
59
|
+
"---\ntitle: Example\nbibliography: refs.bib\n---\n\nText citing [@NotAnIdentifier].\n",
|
|
60
|
+
)
|
|
61
|
+
.expect("write paper.md");
|
|
62
|
+
std::fs::write(&bib, "").expect("write bib");
|
|
63
|
+
|
|
64
|
+
let mut command = Command::cargo_bin("bibsync").expect("binary exists");
|
|
65
|
+
command
|
|
66
|
+
.arg("--provider")
|
|
67
|
+
.arg("inspire")
|
|
68
|
+
.arg("--output")
|
|
69
|
+
.arg(&bib)
|
|
70
|
+
.arg(&paper)
|
|
71
|
+
.assert()
|
|
72
|
+
.failure()
|
|
73
|
+
.stdout(predicate::str::contains("unresolved:"))
|
|
74
|
+
.stdout(predicate::str::contains(
|
|
75
|
+
"NotAnIdentifier: unsupported identifier format",
|
|
76
|
+
));
|
|
77
|
+
}
|
|
78
|
+
|
|
52
79
|
#[test]
|
|
53
80
|
fn cli_reports_missing_ignore_file() {
|
|
54
81
|
let dir = tempdir().expect("tempdir");
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|