summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
committerNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
commitf1261b349e875b842745b63258c3e338cb1fe3bf (patch)
treeb5d402b3e80818cde2c079a42249f3dcb9732247
parent58aa1ac09b1d9e4769d0a0661cf12e2b2db41b14 (diff)
CTAN sync 202105230300
-rw-r--r--FILES.byname1231
-rw-r--r--FILES.byname.gzbin2313016 -> 2315878 bytes
-rw-r--r--FILES.last07days2098
-rw-r--r--fonts/kpfonts-otf/README.md11
-rw-r--r--fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx61
-rw-r--r--fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdfbin187084 -> 189920 bytes
-rw-r--r--fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx72
-rw-r--r--fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdfbin188514 -> 191924 bytes
-rw-r--r--fonts/kpfonts-otf/doc/unimath-kpfonts.pdfbin1788053 -> 1787182 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMath-Bold.otfbin196892 -> 196892 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMath-Light.otfbin455424 -> 456084 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMath-Regular.otfbin428692 -> 429640 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMath-Sans.otfbin275556 -> 276440 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMath-Semibold.otfbin198620 -> 198620 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMono-Bold.otfbin57768 -> 57768 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otfbin64992 -> 64992 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMono-Italic.otfbin66300 -> 66300 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpMono-Regular.otfbin58904 -> 58904 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-Bold.otfbin132080 -> 132080 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otfbin142704 -> 142704 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-Italic.otfbin134260 -> 134260 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-Light.otfbin130328 -> 130328 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otfbin135176 -> 135176 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-Regular.otfbin130976 -> 130976 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-Semibold.otfbin129324 -> 129324 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otfbin140488 -> 140488 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpSans-Bold.otfbin102972 -> 102972 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otfbin110904 -> 110904 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpSans-Italic.otfbin110936 -> 110936 bytes
-rw-r--r--fonts/kpfonts-otf/fonts/KpSans-Regular.otfbin102384 -> 102384 bytes
-rw-r--r--fonts/kpfonts-otf/tex/kpfonts-otf.sty16
-rw-r--r--fonts/newpx/README7
-rw-r--r--fonts/newpx/afm/zplbsl.afm13281
-rw-r--r--fonts/newpx/afm/zplrsl.afm13644
-rw-r--r--fonts/newpx/doc/newpxdoc.pdfbin804826 -> 808489 bytes
-rw-r--r--fonts/newpx/doc/newpxdoc.tex28
-rw-r--r--fonts/newpx/map/newpx.map64
-rw-r--r--fonts/newpx/tex/ly1zpllf.fd14
-rw-r--r--fonts/newpx/tex/ly1zplosf.fd14
-rw-r--r--fonts/newpx/tex/ly1zplth-lf.fd28
-rw-r--r--fonts/newpx/tex/ly1zplth-osf.fd28
-rw-r--r--fonts/newpx/tex/ly1zplth-tlf.fd28
-rw-r--r--fonts/newpx/tex/ly1zplth-tosf.fd28
-rw-r--r--fonts/newpx/tex/ly1zpltlf.fd14
-rw-r--r--fonts/newpx/tex/ly1zpltosf.fd14
-rw-r--r--fonts/newpx/tex/newpxtext.sty31
-rw-r--r--fonts/newpx/tex/ot1zpllf.fd14
-rw-r--r--fonts/newpx/tex/ot1zplosf.fd14
-rw-r--r--fonts/newpx/tex/ot1zplth-lf.fd28
-rw-r--r--fonts/newpx/tex/ot1zplth-osf.fd28
-rw-r--r--fonts/newpx/tex/ot1zplth-tlf.fd28
-rw-r--r--fonts/newpx/tex/ot1zplth-tosf.fd28
-rw-r--r--fonts/newpx/tex/ot1zpltlf.fd14
-rw-r--r--fonts/newpx/tex/ot1zpltosf.fd14
-rw-r--r--fonts/newpx/tex/t1zpllf.fd14
-rw-r--r--fonts/newpx/tex/t1zplosf.fd14
-rw-r--r--fonts/newpx/tex/t1zplth-lf.fd28
-rw-r--r--fonts/newpx/tex/t1zplth-osf.fd28
-rw-r--r--fonts/newpx/tex/t1zplth-tlf.fd28
-rw-r--r--fonts/newpx/tex/t1zplth-tosf.fd28
-rw-r--r--fonts/newpx/tex/t1zpltlf.fd14
-rw-r--r--fonts/newpx/tex/t1zpltosf.fd14
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-lf-ly1.tfmbin0 -> 7540 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-lf-ot1.tfmbin0 -> 3300 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ly1.tfmbin0 -> 8224 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ot1.tfmbin0 -> 3552 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-t1.tfmbin0 -> 13164 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-lf-t1.tfmbin0 -> 11892 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-osf-ly1.tfmbin0 -> 7528 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-osf-ot1.tfmbin0 -> 3288 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ly1.tfmbin0 -> 8212 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ot1.tfmbin0 -> 3536 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-t1.tfmbin0 -> 13152 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-osf-t1.tfmbin0 -> 11876 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tlf-ly1.tfmbin0 -> 7496 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tlf-ot1.tfmbin0 -> 3256 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ly1.tfmbin0 -> 8180 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ot1.tfmbin0 -> 3504 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-t1.tfmbin0 -> 13120 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tlf-t1.tfmbin0 -> 11844 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tosf-ly1.tfmbin0 -> 7496 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tosf-ot1.tfmbin0 -> 3256 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ly1.tfmbin0 -> 8180 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ot1.tfmbin0 -> 3508 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-t1.tfmbin0 -> 13120 bytes
-rw-r--r--fonts/newpx/tfm/zpl-BoldSlanted-tosf-t1.tfmbin0 -> 11844 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-lf-ly1.tfmbin0 -> 7944 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-lf-ot1.tfmbin0 -> 3548 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-lf-sc-ly1.tfmbin0 -> 8296 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-lf-sc-ot1.tfmbin0 -> 3588 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-lf-sc-t1.tfmbin0 -> 13344 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-lf-t1.tfmbin0 -> 12476 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-osf-ly1.tfmbin0 -> 7940 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-osf-ot1.tfmbin0 -> 3544 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-osf-sc-ly1.tfmbin0 -> 8292 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-osf-sc-ot1.tfmbin0 -> 3584 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-osf-sc-t1.tfmbin0 -> 13340 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-osf-t1.tfmbin0 -> 12464 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tlf-ly1.tfmbin0 -> 7904 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tlf-ot1.tfmbin0 -> 3508 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tlf-sc-ly1.tfmbin0 -> 8252 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tlf-sc-ot1.tfmbin0 -> 3544 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tlf-sc-t1.tfmbin0 -> 13300 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tlf-t1.tfmbin0 -> 12428 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tosf-ly1.tfmbin0 -> 7904 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tosf-ot1.tfmbin0 -> 3508 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tosf-sc-ly1.tfmbin0 -> 8252 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tosf-sc-ot1.tfmbin0 -> 3544 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tosf-sc-t1.tfmbin0 -> 13300 bytes
-rw-r--r--fonts/newpx/tfm/zpl-Slanted-tosf-t1.tfmbin0 -> 12428 bytes
-rw-r--r--fonts/newpx/tfm/zplexx.tfmbin1772 -> 1772 bytes
-rw-r--r--fonts/newpx/tfm/zplth-Italic-osf-ly1.tfm (renamed from fonts/newpx/tfm/zpl-Italic-osf-th-ly1.tfm)bin7444 -> 7444 bytes
-rw-r--r--fonts/newpx/tfm/zplth-Italic-osf-ot1.tfm (renamed from fonts/newpx/tfm/zpl-Italic-osf-th-ot1.tfm)bin3176 -> 3176 bytes
-rw-r--r--fonts/newpx/tfm/zplth-Italic-osf-t1.tfm (renamed from fonts/newpx/tfm/zpl-Italic-osf-th-t1.tfm)bin11852 -> 11852 bytes
-rw-r--r--fonts/newpx/tfm/zplth-Italic-tlf-ly1.tfm (renamed from fonts/newpx/tfm/zpl-Italic-tlf-th-ly1.tfm)bin7404 -> 7396 bytes
-rw-r--r--fonts/newpx/tfm/zplth-Italic-tlf-ot1.tfm (renamed from fonts/newpx/tfm/zpl-Italic-tlf-th-ot1.tfm)bin3136 -> 3136 bytes
-rw-r--r--fonts/newpx/tfm/zplth-Italic-tlf-t1.tfm (renamed from fonts/newpx/tfm/zpl-Italic-tlf-th-t1.tfm)bin11812 -> 11812 bytes
-rw-r--r--fonts/newpx/type1/zplbsl.pfbbin0 -> 213291 bytes
-rw-r--r--fonts/newpx/type1/zplrsl.pfbbin0 -> 205748 bytes
-rw-r--r--fonts/newtx/README5
-rw-r--r--fonts/newtx/tex/ly1ntxlf.fd4
-rw-r--r--fonts/newtx/tex/ly1ntxosf.fd4
-rw-r--r--fonts/newtx/tex/ly1ntxtlf.fd4
-rw-r--r--fonts/newtx/tex/ly1ntxtosf.fd4
-rw-r--r--fonts/newtx/tex/newtxtext.sty4
-rw-r--r--fonts/newtx/tex/ot1ntxlf.fd4
-rw-r--r--fonts/newtx/tex/ot1ntxosf.fd4
-rw-r--r--fonts/newtx/tex/ot1ntxtlf.fd4
-rw-r--r--fonts/newtx/tex/ot1ntxtosf.fd4
-rw-r--r--fonts/newtx/tex/t1ntxlf.fd5
-rw-r--r--fonts/newtx/tex/t1ntxosf.fd4
-rw-r--r--fonts/newtx/tex/t1ntxtlf.fd4
-rw-r--r--fonts/newtx/tex/t1ntxtosf.fd4
-rw-r--r--info/biblio/litprog.bib58
-rw-r--r--info/biblio/litprog.ltx12
-rw-r--r--info/tlmgrbasics/README2
-rw-r--r--info/tlmgrbasics/doc/tlmgr.pdfbin144813 -> 157582 bytes
-rw-r--r--info/tlmgrbasics/doc/tlmgr.tex17
-rw-r--r--macros/latex/contrib/bmstu-iu8/BMSTU-IU8.cls53
-rw-r--r--macros/latex/contrib/bmstu-iu8/LICENSE21
-rw-r--r--macros/latex/contrib/bmstu-iu8/README.md3
-rw-r--r--macros/latex/contrib/bmstu-iu8/example.pdfbin0 -> 192899 bytes
-rw-r--r--macros/latex/contrib/bmstu-iu8/example.tex55
-rw-r--r--macros/latex/contrib/bmstu-iu8/inc/bmstu.pngbin0 -> 53203 bytes
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/01-IU8-base.sty40
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/02-IU8-construction.sty66
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/03-IU8-numbering.sty17
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/04-IU8-section-numbering.sty52
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/05-IU8-figures.sty54
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/06-IU8-tables.sty78
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/07-IU8-footnotes.sty37
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/08-IU8-formulas.sty5
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/09-IU8-cites.sty19
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/10-IU8-titlepage.sty237
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/11-IU8-performers.sty5
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/12-IU8-abstract.sty27
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/13-IU8-contents.sty29
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/14-IU8-terms-and-definitions.sty44
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/15-IU8-list-of-abbreviations.sty29
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/16-IU8-references.sty27
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/17-IU8-appendices.sty23
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/18-IU8-extra.sty27
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/19-IU8-counters.sty22
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/20-IU8-listing.sty43
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/21-IU8-math.sty11
-rw-r--r--macros/latex/contrib/bmstu-iu8/styles/22-IU8-algorithms.sty26
-rw-r--r--macros/latex/contrib/mindflow/mindflow.dtx169
-rw-r--r--macros/latex/contrib/mindflow/mindflow.pdfbin179867 -> 187098 bytes
-rw-r--r--support/ltximg/README.md6
-rw-r--r--support/ltximg/ltximg-doc.pdfbin316588 -> 319369 bytes
-rw-r--r--support/ltximg/ltximg-doc.tex208
-rw-r--r--support/ltximg/ltximg.14
-rw-r--r--support/ltximg/ltximg.man1.pdfbin27866 -> 27866 bytes
-rw-r--r--support/ltximg/ltximg.pl25
-rw-r--r--support/texlab/CHANGELOG.md46
-rw-r--r--support/texlab/Cargo.lock1897
-rw-r--r--support/texlab/Cargo.toml125
-rw-r--r--support/texlab/README.md41
-rw-r--r--support/texlab/benches/bench_main.rs7
-rw-r--r--support/texlab/benches/benchmarks/completion.rs135
-rw-r--r--support/texlab/benches/benchmarks/mod.rs1
-rw-r--r--support/texlab/build.rs2
-rw-r--r--support/texlab/crates/jsonrpc/Cargo.toml20
-rw-r--r--support/texlab/crates/jsonrpc/src/client.rs77
-rw-r--r--support/texlab/crates/jsonrpc/src/lib.rs67
-rw-r--r--support/texlab/crates/jsonrpc/src/server.rs131
-rw-r--r--support/texlab/crates/jsonrpc/src/types.rs144
-rw-r--r--support/texlab/crates/jsonrpc_derive/Cargo.toml15
-rw-r--r--support/texlab/crates/jsonrpc_derive/src/lib.rs207
-rw-r--r--support/texlab/data/lang_data.json1122
-rw-r--r--support/texlab/docs/custom_messages.md102
-rw-r--r--support/texlab/docs/demo.gifbin0 -> 380190 bytes
-rw-r--r--support/texlab/docs/lsp_kinds.md31
-rw-r--r--support/texlab/docs/options.md145
-rw-r--r--support/texlab/docs/previewing.md217
-rw-r--r--support/texlab/docs/tectonic.md26
-rw-r--r--support/texlab/src/build.rs203
-rw-r--r--support/texlab/src/capabilities.rs (renamed from support/texlab/src/protocol/capabilities.rs)29
-rw-r--r--support/texlab/src/citation.rs (renamed from support/texlab/src/citeproc/mod.rs)138
-rw-r--r--support/texlab/src/citation/apa.csl (renamed from support/texlab/src/citeproc/apa.csl)0
-rw-r--r--support/texlab/src/citation/bibutils.rs (renamed from support/texlab/src/citeproc/bibutils.rs)9
-rw-r--r--support/texlab/src/citation/name.rs (renamed from support/texlab/src/citeproc/name/mod.rs)45
-rw-r--r--support/texlab/src/citation/name/parser.lalrpop (renamed from support/texlab/src/citeproc/name/parser.lalrpop)0
-rw-r--r--support/texlab/src/citation/ris.rs (renamed from support/texlab/src/citeproc/ris.rs)3
-rw-r--r--support/texlab/src/client.rs53
-rw-r--r--support/texlab/src/completion/bibtex/cmd.rs177
-rw-r--r--support/texlab/src/completion/bibtex/entry_type.rs164
-rw-r--r--support/texlab/src/completion/bibtex/field_name.rs190
-rw-r--r--support/texlab/src/completion/bibtex/mod.rs3
-rw-r--r--support/texlab/src/completion/latex/argument.rs215
-rw-r--r--support/texlab/src/completion/latex/begin_cmd.rs70
-rw-r--r--support/texlab/src/completion/latex/citation.rs261
-rw-r--r--support/texlab/src/completion/latex/color.rs91
-rw-r--r--support/texlab/src/completion/latex/color_model.rs101
-rw-r--r--support/texlab/src/completion/latex/combinators.rs143
-rw-r--r--support/texlab/src/completion/latex/component.rs351
-rw-r--r--support/texlab/src/completion/latex/glossary.rs114
-rw-r--r--support/texlab/src/completion/latex/import.rs188
-rw-r--r--support/texlab/src/completion/latex/include.rs133
-rw-r--r--support/texlab/src/completion/latex/label.rs230
-rw-r--r--support/texlab/src/completion/latex/mod.rs14
-rw-r--r--support/texlab/src/completion/latex/theorem.rs115
-rw-r--r--support/texlab/src/completion/latex/tikz_lib.rs138
-rw-r--r--support/texlab/src/completion/latex/user.rs204
-rw-r--r--support/texlab/src/completion/mod.rs419
-rw-r--r--support/texlab/src/completion/util.rs121
-rw-r--r--support/texlab/src/component_db.rs (renamed from support/texlab/src/components.rs)77
-rw-r--r--support/texlab/src/config.rs161
-rw-r--r--support/texlab/src/context.rs34
-rw-r--r--support/texlab/src/definition/bibtex_string.rs171
-rw-r--r--support/texlab/src/definition/latex_citation.rs118
-rw-r--r--support/texlab/src/definition/latex_cmd.rs154
-rw-r--r--support/texlab/src/definition/latex_label.rs155
-rw-r--r--support/texlab/src/definition/mod.rs47
-rw-r--r--support/texlab/src/diagnostics.rs55
-rw-r--r--support/texlab/src/diagnostics/bibtex.rs450
-rw-r--r--support/texlab/src/diagnostics/build_log.rs65
-rw-r--r--support/texlab/src/diagnostics/chktex.rs105
-rw-r--r--support/texlab/src/diagnostics/debouncer.rs77
-rw-r--r--support/texlab/src/diagnostics/latex.rs204
-rw-r--r--support/texlab/src/diagnostics/mod.rs28
-rw-r--r--support/texlab/src/dispatch.rs81
-rw-r--r--support/texlab/src/distro.rs74
-rw-r--r--support/texlab/src/distro/kpsewhich.rs74
-rw-r--r--support/texlab/src/distro/miktex.rs (renamed from support/texlab/src/tex/miktex.rs)51
-rw-r--r--support/texlab/src/distro/texlive.rs43
-rw-r--r--support/texlab/src/feature.rs405
-rw-r--r--support/texlab/src/features.rs272
-rw-r--r--support/texlab/src/features/build.rs133
-rw-r--r--support/texlab/src/features/completion.rs567
-rw-r--r--support/texlab/src/features/completion/acronym_ref.rs169
-rw-r--r--support/texlab/src/features/completion/argument.rs189
-rw-r--r--support/texlab/src/features/completion/begin_command.rs84
-rw-r--r--support/texlab/src/features/completion/citation.rs244
-rw-r--r--support/texlab/src/features/completion/color.rs122
-rw-r--r--support/texlab/src/features/completion/color_model.rs188
-rw-r--r--support/texlab/src/features/completion/component_command.rs177
-rw-r--r--support/texlab/src/features/completion/component_environment.rs174
-rw-r--r--support/texlab/src/features/completion/entry_type.rs231
-rw-r--r--support/texlab/src/features/completion/field.rs200
-rw-r--r--support/texlab/src/features/completion/glossary_ref.rs141
-rw-r--r--support/texlab/src/features/completion/import.rs196
-rw-r--r--support/texlab/src/features/completion/include.rs181
-rw-r--r--support/texlab/src/features/completion/label.rs196
-rw-r--r--support/texlab/src/features/completion/theorem.rs152
-rw-r--r--support/texlab/src/features/completion/tikz_library.rs169
-rw-r--r--support/texlab/src/features/completion/types.rs (renamed from support/texlab/src/completion/types.rs)142
-rw-r--r--support/texlab/src/features/completion/user_command.rs100
-rw-r--r--support/texlab/src/features/completion/user_environment.rs116
-rw-r--r--support/texlab/src/features/completion/util.rs66
-rw-r--r--support/texlab/src/features/cursor.rs252
-rw-r--r--support/texlab/src/features/definition.rs29
-rw-r--r--support/texlab/src/features/definition/command.rs131
-rw-r--r--support/texlab/src/features/definition/document.rs112
-rw-r--r--support/texlab/src/features/definition/entry.rs125
-rw-r--r--support/texlab/src/features/definition/label.rs80
-rw-r--r--support/texlab/src/features/definition/string.rs176
-rw-r--r--support/texlab/src/features/folding.rs237
-rw-r--r--support/texlab/src/features/formatting.rs24
-rw-r--r--support/texlab/src/features/formatting/bibtex_internal.rs381
-rw-r--r--support/texlab/src/features/formatting/latexindent.rs50
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__command.snap8
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__concatenation.snap8
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__insert_braces.snap8
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__multiple_entries.snap9
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__parens.snap7
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__preamble.snap6
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__string.snap6
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__trailing_comma.snap8
-rw-r--r--support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__wrap_long_lines.snap10
-rw-r--r--support/texlab/src/features/forward_search.rs124
-rw-r--r--support/texlab/src/features/highlight.rs15
-rw-r--r--support/texlab/src/features/highlight/label.rs167
-rw-r--r--support/texlab/src/features/hover.rs43
-rw-r--r--support/texlab/src/features/hover/citation.rs133
-rw-r--r--support/texlab/src/features/hover/component.rs105
-rw-r--r--support/texlab/src/features/hover/entry_type.rs128
-rw-r--r--support/texlab/src/features/hover/field.rs128
-rw-r--r--support/texlab/src/features/hover/label.rs79
-rw-r--r--support/texlab/src/features/hover/string_ref.rs141
-rw-r--r--support/texlab/src/features/link.rs115
-rw-r--r--support/texlab/src/features/lsp_kinds.rs (renamed from support/texlab/src/syntax/lsp_kind.rs)5
-rw-r--r--support/texlab/src/features/reference.rs25
-rw-r--r--support/texlab/src/features/reference/entry.rs198
-rw-r--r--support/texlab/src/features/reference/label.rs187
-rw-r--r--support/texlab/src/features/reference/string.rs206
-rw-r--r--support/texlab/src/features/rename.rs34
-rw-r--r--support/texlab/src/features/rename/command.rs98
-rw-r--r--support/texlab/src/features/rename/entry.rs161
-rw-r--r--support/texlab/src/features/rename/label.rs142
-rw-r--r--support/texlab/src/features/semantic.rs21
-rw-r--r--support/texlab/src/features/semantic/bibtex.rs289
-rw-r--r--support/texlab/src/features/semantic/legend.rs83
-rw-r--r--support/texlab/src/features/symbol.rs125
-rw-r--r--support/texlab/src/features/symbol/bibtex.rs88
-rw-r--r--support/texlab/src/features/symbol/latex.rs488
-rw-r--r--support/texlab/src/features/symbol/project_order.rs223
-rw-r--r--support/texlab/src/features/symbol/types.rs (renamed from support/texlab/src/symbol/types.rs)83
-rw-r--r--support/texlab/src/folding/bibtex_decl.rs159
-rw-r--r--support/texlab/src/folding/latex_env.rs80
-rw-r--r--support/texlab/src/folding/latex_section.rs111
-rw-r--r--support/texlab/src/folding/mod.rs45
-rw-r--r--support/texlab/src/forward_search.rs90
-rw-r--r--support/texlab/src/highlight/latex_label.rs109
-rw-r--r--support/texlab/src/highlight/mod.rs36
-rw-r--r--support/texlab/src/hover/bibtex/entry_type.rs116
-rw-r--r--support/texlab/src/hover/bibtex/field.rs111
-rw-r--r--support/texlab/src/hover/bibtex/mod.rs3
-rw-r--r--support/texlab/src/hover/bibtex/string_reference.rs165
-rw-r--r--support/texlab/src/hover/latex/citation.rs179
-rw-r--r--support/texlab/src/hover/latex/component.rs95
-rw-r--r--support/texlab/src/hover/latex/label.rs118
-rw-r--r--support/texlab/src/hover/latex/mod.rs6
-rw-r--r--support/texlab/src/hover/latex/preview.rs338
-rw-r--r--support/texlab/src/hover/mod.rs58
-rw-r--r--support/texlab/src/label.rs291
-rw-r--r--support/texlab/src/lang_data.rs67
-rw-r--r--support/texlab/src/language.rs33
-rw-r--r--support/texlab/src/lib.rs65
-rw-r--r--support/texlab/src/line_index.rs217
-rw-r--r--support/texlab/src/line_index_ext.rs42
-rw-r--r--support/texlab/src/link/latex_import.rs99
-rw-r--r--support/texlab/src/link/latex_include.rs101
-rw-r--r--support/texlab/src/link/mod.rs40
-rw-r--r--support/texlab/src/main.rs53
-rw-r--r--support/texlab/src/options.rs86
-rw-r--r--support/texlab/src/outline.rs437
-rw-r--r--support/texlab/src/protocol/client.rs27
-rw-r--r--support/texlab/src/protocol/codec.rs144
-rw-r--r--support/texlab/src/protocol/edit.rs12
-rw-r--r--support/texlab/src/protocol/mod.rs71
-rw-r--r--support/texlab/src/protocol/options.rs104
-rw-r--r--support/texlab/src/protocol/range.rs97
-rw-r--r--support/texlab/src/range.rs20
-rw-r--r--support/texlab/src/reference/bibtex_entry.rs218
-rw-r--r--support/texlab/src/reference/bibtex_string.rs253
-rw-r--r--support/texlab/src/reference/latex_label.rs211
-rw-r--r--support/texlab/src/reference/mod.rs45
-rw-r--r--support/texlab/src/rename/bibtex_entry.rs192
-rw-r--r--support/texlab/src/rename/latex_cmd.rs128
-rw-r--r--support/texlab/src/rename/latex_env.rs157
-rw-r--r--support/texlab/src/rename/latex_label.rs146
-rw-r--r--support/texlab/src/rename/mod.rs88
-rw-r--r--support/texlab/src/req_queue.rs13
-rw-r--r--support/texlab/src/server.rs1369
-rw-r--r--support/texlab/src/symbol/bibtex_entry.rs153
-rw-r--r--support/texlab/src/symbol/bibtex_string.rs102
-rw-r--r--support/texlab/src/symbol/latex_section/enumeration.rs79
-rw-r--r--support/texlab/src/symbol/latex_section/equation.rs41
-rw-r--r--support/texlab/src/symbol/latex_section/float.rs59
-rw-r--r--support/texlab/src/symbol/latex_section/mod.rs671
-rw-r--r--support/texlab/src/symbol/latex_section/theorem.rs70
-rw-r--r--support/texlab/src/symbol/mod.rs178
-rw-r--r--support/texlab/src/symbol/project_order.rs181
-rw-r--r--support/texlab/src/syntax.rs17
-rw-r--r--support/texlab/src/syntax/bibtex.rs34
-rw-r--r--support/texlab/src/syntax/bibtex/ast.rs431
-rw-r--r--support/texlab/src/syntax/bibtex/cst.rs212
-rw-r--r--support/texlab/src/syntax/bibtex/formatter.rs329
-rw-r--r--support/texlab/src/syntax/bibtex/kind.rs51
-rw-r--r--support/texlab/src/syntax/bibtex/lexer.rs215
-rw-r--r--support/texlab/src/syntax/bibtex/mod.rs396
-rw-r--r--support/texlab/src/syntax/bibtex/parser.rs706
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__empty.snap7
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap40
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap13
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap12
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap27
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap27
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap28
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap42
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap33
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__junk.snap11
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_casing.snap21
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_complete.snap21
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_missing_end.snap20
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_casing.snap23
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_complete.snap23
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_concatenation.snap43
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_incomplete.snap23
-rw-r--r--support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_missing_quote.snap23
-rw-r--r--support/texlab/src/syntax/build_log.rs (renamed from support/texlab/src/diagnostics/build.rs)694
-rw-r--r--support/texlab/src/syntax/generic_ast.rs51
-rw-r--r--support/texlab/src/syntax/lang_data.rs231
-rw-r--r--support/texlab/src/syntax/latex.rs36
-rw-r--r--support/texlab/src/syntax/latex/analysis.rs943
-rw-r--r--support/texlab/src/syntax/latex/analysis/command.rs12
-rw-r--r--support/texlab/src/syntax/latex/analysis/distro_file.rs71
-rw-r--r--support/texlab/src/syntax/latex/analysis/environment.rs11
-rw-r--r--support/texlab/src/syntax/latex/analysis/explicit_link.rs72
-rw-r--r--support/texlab/src/syntax/latex/analysis/implicit_link.rs41
-rw-r--r--support/texlab/src/syntax/latex/analysis/label_name.rs66
-rw-r--r--support/texlab/src/syntax/latex/analysis/label_number.rs22
-rw-r--r--support/texlab/src/syntax/latex/analysis/theorem.rs23
-rw-r--r--support/texlab/src/syntax/latex/analysis/types.rs73
-rw-r--r--support/texlab/src/syntax/latex/ast.rs414
-rw-r--r--support/texlab/src/syntax/latex/cst.rs639
-rw-r--r--support/texlab/src/syntax/latex/kind.rs180
-rw-r--r--support/texlab/src/syntax/latex/lexer.rs353
-rw-r--r--support/texlab/src/syntax/latex/mod.rs686
-rw-r--r--support/texlab/src/syntax/latex/parser.rs1809
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_parameter.snap47
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_star.snap23
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__comment.snap35
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__delimiters.snap79
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__empty.snap6
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__escape_sequence.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__formula.snap55
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__invalid_parameter.snap11
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap49
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap46
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap28
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap29
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap30
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_missing_end.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_simple.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption.snap26
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_error.snap26
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap28
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal.snap21
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal_error.snap21
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_empty.snap13
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap17
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap24
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap16
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_empty.snap13
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap37
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap27
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap29
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap22
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error4.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap32
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_argc.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl_error.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap24
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__empty.snap8
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap38
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap37
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap42
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap27
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation.snap17
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap30
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap31
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__escaped_brackets.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_args.snap20
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_empty.snap10
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_escape.snap10
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap33
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap32
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap25
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__hello_world.snap12
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap18
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap25
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline.snap26
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline_double_dollar.snap26
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap23
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap17
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap18
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap18
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_no_impl.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_simple.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_empty.snap13
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap17
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap37
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter.snap9
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter_error.snap9
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap45
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_invalid_nesting.snap23
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_nested.snap57
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_siblings.snap29
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap25
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap27
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap19
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap23
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap15
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap14
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_braces.snap13
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets.snap13
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets_with_group.snap16
-rw-r--r--support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap14
-rw-r--r--support/texlab/src/syntax/latexindent.rs21
-rw-r--r--support/texlab/src/syntax/mod.rs14
-rw-r--r--support/texlab/src/syntax/text.rs260
-rw-r--r--support/texlab/src/test/client.rs73
-rw-r--r--support/texlab/src/test/mod.rs632
-rw-r--r--support/texlab/src/test/server.rs87
-rw-r--r--support/texlab/src/tex/compile.rs97
-rw-r--r--support/texlab/src/tex/kpsewhich.rs112
-rw-r--r--support/texlab/src/tex/mod.rs154
-rw-r--r--support/texlab/src/tex/tectonic.rs36
-rw-r--r--support/texlab/src/tex/texlive.rs71
-rw-r--r--support/texlab/src/uri.rs (renamed from support/texlab/src/protocol/uri.rs)24
-rw-r--r--support/texlab/src/workspace.rs980
-rw-r--r--support/texlab/src/workspace/api.rs86
-rw-r--r--support/texlab/src/workspace/children_expand.rs92
-rw-r--r--support/texlab/src/workspace/document.rs127
-rw-r--r--support/texlab/src/workspace/parent_expand.rs123
-rw-r--r--support/texlab/src/workspace/storage.rs136
-rw-r--r--support/texlab/src/workspace/watch.rs107
-rw-r--r--support/texlab/tests/integration/common.rs318
-rw-r--r--support/texlab/tests/integration/completion.rs1927
-rw-r--r--support/texlab/tests/integration/definition.rs482
-rw-r--r--support/texlab/tests/integration/document_symbol.rs836
-rw-r--r--support/texlab/tests/integration/folding.rs126
-rw-r--r--support/texlab/tests/integration/highlight.rs83
-rw-r--r--support/texlab/tests/integration/hover.rs163
-rw-r--r--support/texlab/tests/integration/issues.rs389
-rw-r--r--support/texlab/tests/integration/link.rs173
-rw-r--r--support/texlab/tests/integration/main.rs9
-rw-r--r--support/texlab/tests/integration/prepare_rename.rs151
-rw-r--r--support/texlab/tests/integration/reference.rs150
-rw-r--r--support/texlab/tests/integration/rename.rs236
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_complete_entry.snap150
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_incomplete_entry.snap150
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__empty_document.snap9
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_complete.snap33
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name.snap159
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name_before.snap9
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_incomplete.snap79
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_complete_entry.snap171
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_incomplete_entry.snap171
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__bibtex__junk.snap9
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__begin_command.snap162
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__citation.snap54
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__citation_after.snap9
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__citation_open_brace.snap34
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__class_command.snap150
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__class_environment.snap30
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__class_import.snap171
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color.snap105
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color_set.snap67
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__color_name.snap143
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__empty_document.snap9
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command.snap30
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_environment.snap30
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_glyph.snap34
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__label.snap137
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__package_command.snap34
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__package_environment.snap150
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__package_import.snap102
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__pgf_library.snap143
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__preselect_environment.snap150
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__theorem_environment.snap130
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__user_command.snap30
-rw-r--r--support/texlab/tests/integration/snapshots/integration__completion__latex__user_environment.snap50
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_flat.snap97
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_nested.snap141
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__equation_flat.snap61
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__equation_nested.snap87
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__float_flat.snap61
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__float_nested.snap87
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__section_flat.snap61
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__section_nested.snap88
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_flat.snap79
-rw-r--r--support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_nested.snap114
-rw-r--r--support/texlab/tests/integration/snapshots/integration__hover__empty_bibtex_document.snap6
-rw-r--r--support/texlab/tests/integration/snapshots/integration__hover__empty_labtex_document.snap6
-rw-r--r--support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file.snap21
-rw-r--r--support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file_mumber.snap21
-rw-r--r--support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_bibtex.snap43
-rw-r--r--support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_figure.snap25
-rw-r--r--support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_item.snap61
-rw-r--r--support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_math.snap43
-rw-r--r--support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_section.snap79
-rw-r--r--support/texlab/tests/integration/workspace_symbol.rs323
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl8
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb260
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.md52
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha5122
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc14
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.xzbin2307008 -> 2307588 bytes
-rw-r--r--systems/win32/miktex/tm/packages/next/pr.ini8
-rw-r--r--systems/win32/miktex/tm/packages/pr.ini8
-rw-r--r--timestamp2
619 files changed, 57537 insertions, 28443 deletions
diff --git a/FILES.byname b/FILES.byname
index 53c6d237b1..bc8a8d6119 100644
--- a/FILES.byname
+++ b/FILES.byname
@@ -5087,7 +5087,7 @@
1990/10/02 | 5440 | dviware/vutex/vaxvms.hlp
1990/10/02 | 812 | dviware/vutex/vaxvms.ins
1990/10/02 | 127576 | dviware/vutex/vutex.web
-2021/05/21 | 164869 | FILES.last07days
+2021/05/22 | 173386 | FILES.last07days
2020/08/14 | 104065 | fonts/academicons/academicons.pdf
2020/08/14 | 17247 | fonts/academicons/academicons.sty
2020/08/14 | 6546 | fonts/academicons/academicons.tex
@@ -58152,40 +58152,40 @@
2006/09/05 | 335 | fonts/kpfonts/latex/ujkpsyd.fd
2008/11/11 | 345 | fonts/kpfonts/latex/ujkpsydw.fd
2009/04/19 | 14734 | fonts/kpfonts/map/kpfonts.map
-2021/03/16 | 30487 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx
-2021/03/16 | 187084 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf
-2021/03/16 | 33131 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx
-2021/03/16 | 188514 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf
-2021/03/16 | 16745 | fonts/kpfonts-otf/doc/unimath-kpfonts.ltx
-2021/03/16 | 1788053 | fonts/kpfonts-otf/doc/unimath-kpfonts.pdf
-2021/03/16 | 196892 | fonts/kpfonts-otf/fonts/KpMath-Bold.otf
-2021/03/16 | 455424 | fonts/kpfonts-otf/fonts/KpMath-Light.otf
-2021/03/16 | 428692 | fonts/kpfonts-otf/fonts/KpMath-Regular.otf
-2021/03/16 | 275556 | fonts/kpfonts-otf/fonts/KpMath-Sans.otf
-2021/03/16 | 198620 | fonts/kpfonts-otf/fonts/KpMath-Semibold.otf
-2021/03/16 | 64992 | fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf
-2021/03/16 | 57768 | fonts/kpfonts-otf/fonts/KpMono-Bold.otf
-2021/03/16 | 66300 | fonts/kpfonts-otf/fonts/KpMono-Italic.otf
-2021/03/16 | 58904 | fonts/kpfonts-otf/fonts/KpMono-Regular.otf
-2021/03/16 | 142704 | fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf
-2021/03/16 | 132080 | fonts/kpfonts-otf/fonts/KpRoman-Bold.otf
-2021/03/16 | 134260 | fonts/kpfonts-otf/fonts/KpRoman-Italic.otf
-2021/03/16 | 135176 | fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf
-2021/03/16 | 130328 | fonts/kpfonts-otf/fonts/KpRoman-Light.otf
-2021/03/16 | 130976 | fonts/kpfonts-otf/fonts/KpRoman-Regular.otf
-2021/03/16 | 140488 | fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf
-2021/03/16 | 129324 | fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf
-2021/03/16 | 110904 | fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf
-2021/03/16 | 102972 | fonts/kpfonts-otf/fonts/KpSans-Bold.otf
-2021/03/16 | 110936 | fonts/kpfonts-otf/fonts/KpSans-Italic.otf
-2021/03/16 | 102384 | fonts/kpfonts-otf/fonts/KpSans-Regular.otf
-2021/03/16 | 4818 | fonts/kpfonts-otf/README.md
-2021/03/16 | 18260 | fonts/kpfonts-otf/tex/kpfonts-otf.sty
-2021/03/16 | 434 | fonts/kpfonts-otf/tex/KpLight.fontspec
-2021/03/16 | 185 | fonts/kpfonts-otf/tex/KpMono.fontspec
-2021/03/16 | 423 | fonts/kpfonts-otf/tex/KpRoman.fontspec
-2021/03/16 | 241 | fonts/kpfonts-otf/tex/KpSans.fontspec
-2021/03/16 | 4260670 | fonts/kpfonts-otf.zip
+2021/05/22 | 31465 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx
+2021/05/22 | 189920 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf
+2021/05/22 | 33948 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx
+2021/05/22 | 191924 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf
+2021/05/22 | 16745 | fonts/kpfonts-otf/doc/unimath-kpfonts.ltx
+2021/05/22 | 1787182 | fonts/kpfonts-otf/doc/unimath-kpfonts.pdf
+2021/05/22 | 196892 | fonts/kpfonts-otf/fonts/KpMath-Bold.otf
+2021/05/22 | 456084 | fonts/kpfonts-otf/fonts/KpMath-Light.otf
+2021/05/22 | 429640 | fonts/kpfonts-otf/fonts/KpMath-Regular.otf
+2021/05/22 | 276440 | fonts/kpfonts-otf/fonts/KpMath-Sans.otf
+2021/05/22 | 198620 | fonts/kpfonts-otf/fonts/KpMath-Semibold.otf
+2021/05/22 | 64992 | fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf
+2021/05/22 | 57768 | fonts/kpfonts-otf/fonts/KpMono-Bold.otf
+2021/05/22 | 66300 | fonts/kpfonts-otf/fonts/KpMono-Italic.otf
+2021/05/22 | 58904 | fonts/kpfonts-otf/fonts/KpMono-Regular.otf
+2021/05/22 | 142704 | fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf
+2021/05/22 | 132080 | fonts/kpfonts-otf/fonts/KpRoman-Bold.otf
+2021/05/22 | 134260 | fonts/kpfonts-otf/fonts/KpRoman-Italic.otf
+2021/05/22 | 135176 | fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf
+2021/05/22 | 130328 | fonts/kpfonts-otf/fonts/KpRoman-Light.otf
+2021/05/22 | 130976 | fonts/kpfonts-otf/fonts/KpRoman-Regular.otf
+2021/05/22 | 140488 | fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf
+2021/05/22 | 129324 | fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf
+2021/05/22 | 110904 | fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf
+2021/05/22 | 102972 | fonts/kpfonts-otf/fonts/KpSans-Bold.otf
+2021/05/22 | 110936 | fonts/kpfonts-otf/fonts/KpSans-Italic.otf
+2021/05/22 | 102384 | fonts/kpfonts-otf/fonts/KpSans-Regular.otf
+2021/05/22 | 5289 | fonts/kpfonts-otf/README.md
+2021/05/22 | 18630 | fonts/kpfonts-otf/tex/kpfonts-otf.sty
+2021/05/22 | 434 | fonts/kpfonts-otf/tex/KpLight.fontspec
+2021/05/22 | 185 | fonts/kpfonts-otf/tex/KpMono.fontspec
+2021/05/22 | 423 | fonts/kpfonts-otf/tex/KpRoman.fontspec
+2021/05/22 | 241 | fonts/kpfonts-otf/tex/KpSans.fontspec
+2021/05/22 | 4267938 | fonts/kpfonts-otf.zip
2009/03/15 | 49269 | fonts/kpfonts/pfb/jkpbexa.pfb
2010/02/24 | 26301 | fonts/kpfonts/pfb/jkpbex.pfb
2010/02/24 | 37865 | fonts/kpfonts/pfb/jkpbit8a.pfb
@@ -81457,48 +81457,62 @@
2020/06/20 | 366881 | fonts/newpx/afm/TeXGyrePagellaX-Regular.afm
2020/06/21 | 357033 | fonts/newpx/afm/zplb.afm
2020/06/21 | 275834 | fonts/newpx/afm/zplbi.afm
+2021/05/20 | 357289 | fonts/newpx/afm/zplbsl.afm
2020/06/20 | 366881 | fonts/newpx/afm/zplr.afm
2020/06/20 | 358806 | fonts/newpx/afm/zplri.afm
+2021/05/20 | 367102 | fonts/newpx/afm/zplrsl.afm
2019/09/22 | 2226 | fonts/newpx/doc/ChangesInV1.4.txt
2015/04/20 | 635 | fonts/newpx/doc/MANIFEST-newpx.txt
-2021/03/24 | 804826 | fonts/newpx/doc/newpxdoc.pdf
-2021/03/24 | 41007 | fonts/newpx/doc/newpxdoc.tex
+2021/05/22 | 808489 | fonts/newpx/doc/newpxdoc.pdf
+2021/05/22 | 41930 | fonts/newpx/doc/newpxdoc.tex
2013/03/29 | 8118 | fonts/newpx/doc/newpxeg-crop.pdf
2013/03/27 | 8858 | fonts/newpx/doc/pxfontseg-crop.pdf
2018/10/07 | 3713 | fonts/newpx/enc/npxsups_ly1.enc
2018/10/07 | 2787 | fonts/newpx/enc/npxsups_ot1.enc
2018/10/07 | 3661 | fonts/newpx/enc/npxsups_t1.enc
2015/07/16 | 2578 | fonts/newpx/enc/tgpdiff.enc
-2019/10/23 | 17654 | fonts/newpx/map/newpx.map
+2021/05/20 | 23241 | fonts/newpx/map/newpx.map
2020/06/21 | 151820 | fonts/newpx/opentype/TeXGyrePagellaX-BoldItalic.otf
2020/06/21 | 152172 | fonts/newpx/opentype/TeXGyrePagellaX-Bold.otf
2020/06/20 | 159908 | fonts/newpx/opentype/TeXGyrePagellaX-Italic.otf
2020/06/20 | 151784 | fonts/newpx/opentype/TeXGyrePagellaX-Regular.otf
-2021/03/24 | 17307 | fonts/newpx/README
+2021/05/22 | 18233 | fonts/newpx/README
2016/07/06 | 694 | fonts/newpx/tex/lmsnpxsy.fd
2016/07/06 | 690 | fonts/newpx/tex/lmxnpxexx.fd
2015/05/01 | 1510 | fonts/newpx/tex/ly1npxtt.fd
-2015/05/01 | 1696 | fonts/newpx/tex/ly1zpllf.fd
-2015/05/01 | 1734 | fonts/newpx/tex/ly1zplosf.fd
+2021/05/21 | 2065 | fonts/newpx/tex/ly1zpllf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ly1zplosf.fd
2015/05/01 | 1881 | fonts/newpx/tex/ly1zplsups.fd
-2015/05/01 | 1734 | fonts/newpx/tex/ly1zpltlf.fd
-2015/05/01 | 1901 | fonts/newpx/tex/ly1zpltosf.fd
+2021/05/20 | 1532 | fonts/newpx/tex/ly1zplth-lf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ly1zplth-osf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ly1zplth-tlf.fd
+2021/05/20 | 1609 | fonts/newpx/tex/ly1zplth-tosf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ly1zpltlf.fd
+2021/05/21 | 2282 | fonts/newpx/tex/ly1zpltosf.fd
2021/03/24 | 114008 | fonts/newpx/tex/newpxmath.sty
2019/09/06 | 151 | fonts/newpx/tex/newpx-subs.tex
-2021/03/21 | 7219 | fonts/newpx/tex/newpxtext.sty
+2021/05/20 | 7967 | fonts/newpx/tex/newpxtext.sty
2013/04/01 | 1021 | fonts/newpx/tex/omlnpxmi.fd
2015/05/01 | 1510 | fonts/newpx/tex/ot1npxtt.fd
-2015/05/01 | 1696 | fonts/newpx/tex/ot1zpllf.fd
-2015/05/01 | 1734 | fonts/newpx/tex/ot1zplosf.fd
+2021/05/21 | 2065 | fonts/newpx/tex/ot1zpllf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ot1zplosf.fd
2015/05/01 | 1881 | fonts/newpx/tex/ot1zplsups.fd
-2015/05/01 | 1734 | fonts/newpx/tex/ot1zpltlf.fd
-2015/05/01 | 1901 | fonts/newpx/tex/ot1zpltosf.fd
+2021/05/20 | 1532 | fonts/newpx/tex/ot1zplth-lf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ot1zplth-osf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ot1zplth-tlf.fd
+2021/05/20 | 1608 | fonts/newpx/tex/ot1zplth-tosf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ot1zpltlf.fd
+2021/05/21 | 2282 | fonts/newpx/tex/ot1zpltosf.fd
2015/05/01 | 1516 | fonts/newpx/tex/t1npxtt.fd
-2015/05/01 | 1665 | fonts/newpx/tex/t1zpllf.fd
-2015/05/01 | 1704 | fonts/newpx/tex/t1zplosf.fd
+2021/05/21 | 2029 | fonts/newpx/tex/t1zpllf.fd
+2021/05/21 | 2075 | fonts/newpx/tex/t1zplosf.fd
2015/05/01 | 1857 | fonts/newpx/tex/t1zplsups.fd
-2015/05/01 | 1704 | fonts/newpx/tex/t1zpltlf.fd
-2015/05/01 | 1870 | fonts/newpx/tex/t1zpltosf.fd
+2021/05/20 | 1510 | fonts/newpx/tex/t1zplth-lf.fd
+2021/05/20 | 1549 | fonts/newpx/tex/t1zplth-osf.fd
+2021/05/20 | 1540 | fonts/newpx/tex/t1zplth-tlf.fd
+2021/05/20 | 1586 | fonts/newpx/tex/t1zplth-tosf.fd
+2021/05/21 | 2074 | fonts/newpx/tex/t1zpltlf.fd
+2021/05/21 | 2247 | fonts/newpx/tex/t1zpltosf.fd
2015/04/20 | 228 | fonts/newpx/tex/TeXGyrePagellaX.fontspec
2015/05/01 | 1501 | fonts/newpx/tex/ts1npxtt.fd
2015/05/01 | 1210 | fonts/newpx/tex/ts1zpllf.fd
@@ -81532,7 +81546,7 @@
2021/03/21 | 1720 | fonts/newpx/tfm/pxmiaX.tfm
2019/09/03 | 1584 | fonts/newpx/tfm/pxsys.tfm
2020/05/18 | 800 | fonts/newpx/tfm/zplbexa.tfm
-2021/03/24 | 1784 | fonts/newpx/tfm/zplbexx.tfm
+2021/05/22 | 1784 | fonts/newpx/tfm/zplbexx.tfm
2016/10/15 | 2156 | fonts/newpx/tfm/zplbmi0.tfm
2020/06/03 | 3324 | fonts/newpx/tfm/zplbmi1.tfm
2021/03/21 | 2288 | fonts/newpx/tfm/zplbmia.tfm
@@ -81591,6 +81605,30 @@
2020/06/21 | 3324 | fonts/newpx/tfm/zpl-Bold-osf-sc-ot1.tfm
2020/06/21 | 12940 | fonts/newpx/tfm/zpl-Bold-osf-sc-t1.tfm
2020/06/21 | 11676 | fonts/newpx/tfm/zpl-Bold-osf-t1.tfm
+2021/05/20 | 7540 | fonts/newpx/tfm/zpl-BoldSlanted-lf-ly1.tfm
+2021/05/20 | 3300 | fonts/newpx/tfm/zpl-BoldSlanted-lf-ot1.tfm
+2021/05/20 | 8224 | fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ly1.tfm
+2021/05/20 | 3552 | fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ot1.tfm
+2021/05/20 | 13164 | fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-t1.tfm
+2021/05/20 | 11892 | fonts/newpx/tfm/zpl-BoldSlanted-lf-t1.tfm
+2021/05/20 | 7528 | fonts/newpx/tfm/zpl-BoldSlanted-osf-ly1.tfm
+2021/05/20 | 3288 | fonts/newpx/tfm/zpl-BoldSlanted-osf-ot1.tfm
+2021/05/20 | 8212 | fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ly1.tfm
+2021/05/20 | 3536 | fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ot1.tfm
+2021/05/20 | 13152 | fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-t1.tfm
+2021/05/20 | 11876 | fonts/newpx/tfm/zpl-BoldSlanted-osf-t1.tfm
+2021/05/20 | 7496 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-ly1.tfm
+2021/05/20 | 3256 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-ot1.tfm
+2021/05/20 | 8180 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ly1.tfm
+2021/05/20 | 3504 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ot1.tfm
+2021/05/20 | 13120 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-t1.tfm
+2021/05/20 | 11844 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-t1.tfm
+2021/05/20 | 7496 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-ly1.tfm
+2021/05/20 | 3256 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-ot1.tfm
+2021/05/20 | 8180 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ly1.tfm
+2021/05/20 | 3508 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ot1.tfm
+2021/05/20 | 13120 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-t1.tfm
+2021/05/20 | 11844 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-t1.tfm
2020/06/21 | 7280 | fonts/newpx/tfm/zpl-Bold-tlf-ly1.tfm
2020/06/21 | 3028 | fonts/newpx/tfm/zpl-Bold-tlf-ot1.tfm
2020/06/21 | 13096 | fonts/newpx/tfm/zpl-Bold-tlf-scl-ly1.tfm
@@ -81614,7 +81652,7 @@
2021/03/21 | 2056 | fonts/newpx/tfm/zplbsy.tfm
2015/07/16 | 192 | fonts/newpx/tfm/zplb-x.tfm
2020/05/18 | 760 | fonts/newpx/tfm/zplexa.tfm
-2021/03/24 | 1772 | fonts/newpx/tfm/zplexx.tfm
+2021/05/22 | 1772 | fonts/newpx/tfm/zplexx.tfm
2020/06/21 | 7532 | fonts/newpx/tfm/zpl-Italic-lf-ly1.tfm
2020/06/21 | 3248 | fonts/newpx/tfm/zpl-Italic-lf-ot1.tfm
2020/06/21 | 13108 | fonts/newpx/tfm/zpl-Italic-lf-scl-ly1.tfm
@@ -81633,9 +81671,6 @@
2020/06/21 | 3460 | fonts/newpx/tfm/zpl-Italic-osf-sc-ot1.tfm
2020/06/21 | 12868 | fonts/newpx/tfm/zpl-Italic-osf-sc-t1.tfm
2020/06/21 | 11964 | fonts/newpx/tfm/zpl-Italic-osf-t1.tfm
-2020/06/21 | 7444 | fonts/newpx/tfm/zpl-Italic-osf-th-ly1.tfm
-2020/06/21 | 3176 | fonts/newpx/tfm/zpl-Italic-osf-th-ot1.tfm
-2020/06/21 | 11852 | fonts/newpx/tfm/zpl-Italic-osf-th-t1.tfm
2020/06/21 | 7472 | fonts/newpx/tfm/zpl-Italic-tlf-ly1.tfm
2020/06/21 | 3188 | fonts/newpx/tfm/zpl-Italic-tlf-ot1.tfm
2020/06/21 | 13048 | fonts/newpx/tfm/zpl-Italic-tlf-scl-ly1.tfm
@@ -81645,9 +81680,6 @@
2020/06/21 | 3416 | fonts/newpx/tfm/zpl-Italic-tlf-sc-ot1.tfm
2020/06/21 | 12828 | fonts/newpx/tfm/zpl-Italic-tlf-sc-t1.tfm
2020/06/21 | 11916 | fonts/newpx/tfm/zpl-Italic-tlf-t1.tfm
-2020/06/21 | 7404 | fonts/newpx/tfm/zpl-Italic-tlf-th-ly1.tfm
-2020/06/21 | 3136 | fonts/newpx/tfm/zpl-Italic-tlf-th-ot1.tfm
-2020/06/21 | 11812 | fonts/newpx/tfm/zpl-Italic-tlf-th-t1.tfm
2020/06/21 | 7468 | fonts/newpx/tfm/zpl-Italic-tosf-ly1.tfm
2020/06/21 | 3184 | fonts/newpx/tfm/zpl-Italic-tosf-ot1.tfm
2020/06/21 | 13044 | fonts/newpx/tfm/zpl-Italic-tosf-scl-ly1.tfm
@@ -81697,6 +81729,30 @@
2020/06/21 | 13072 | fonts/newpx/tfm/zpl-Regular-tosf-sc-t1.tfm
2020/06/21 | 12216 | fonts/newpx/tfm/zpl-Regular-tosf-t1.tfm
2015/07/16 | 196 | fonts/newpx/tfm/zplr-x.tfm
+2021/05/20 | 7944 | fonts/newpx/tfm/zpl-Slanted-lf-ly1.tfm
+2021/05/20 | 3548 | fonts/newpx/tfm/zpl-Slanted-lf-ot1.tfm
+2021/05/20 | 8296 | fonts/newpx/tfm/zpl-Slanted-lf-sc-ly1.tfm
+2021/05/20 | 3588 | fonts/newpx/tfm/zpl-Slanted-lf-sc-ot1.tfm
+2021/05/20 | 13344 | fonts/newpx/tfm/zpl-Slanted-lf-sc-t1.tfm
+2021/05/20 | 12476 | fonts/newpx/tfm/zpl-Slanted-lf-t1.tfm
+2021/05/20 | 7940 | fonts/newpx/tfm/zpl-Slanted-osf-ly1.tfm
+2021/05/20 | 3544 | fonts/newpx/tfm/zpl-Slanted-osf-ot1.tfm
+2021/05/20 | 8292 | fonts/newpx/tfm/zpl-Slanted-osf-sc-ly1.tfm
+2021/05/20 | 3584 | fonts/newpx/tfm/zpl-Slanted-osf-sc-ot1.tfm
+2021/05/20 | 13340 | fonts/newpx/tfm/zpl-Slanted-osf-sc-t1.tfm
+2021/05/20 | 12464 | fonts/newpx/tfm/zpl-Slanted-osf-t1.tfm
+2021/05/20 | 7904 | fonts/newpx/tfm/zpl-Slanted-tlf-ly1.tfm
+2021/05/20 | 3508 | fonts/newpx/tfm/zpl-Slanted-tlf-ot1.tfm
+2021/05/20 | 8252 | fonts/newpx/tfm/zpl-Slanted-tlf-sc-ly1.tfm
+2021/05/20 | 3544 | fonts/newpx/tfm/zpl-Slanted-tlf-sc-ot1.tfm
+2021/05/20 | 13300 | fonts/newpx/tfm/zpl-Slanted-tlf-sc-t1.tfm
+2021/05/20 | 12428 | fonts/newpx/tfm/zpl-Slanted-tlf-t1.tfm
+2021/05/20 | 7904 | fonts/newpx/tfm/zpl-Slanted-tosf-ly1.tfm
+2021/05/20 | 3508 | fonts/newpx/tfm/zpl-Slanted-tosf-ot1.tfm
+2021/05/20 | 8252 | fonts/newpx/tfm/zpl-Slanted-tosf-sc-ly1.tfm
+2021/05/20 | 3544 | fonts/newpx/tfm/zpl-Slanted-tosf-sc-ot1.tfm
+2021/05/20 | 13300 | fonts/newpx/tfm/zpl-Slanted-tosf-sc-t1.tfm
+2021/05/20 | 12428 | fonts/newpx/tfm/zpl-Slanted-tosf-t1.tfm
2020/06/03 | 2624 | fonts/newpx/tfm/zplsups-BoldItalic-ly1.tfm
2020/06/03 | 1288 | fonts/newpx/tfm/zplsups-BoldItalic-ot1.tfm
2020/06/03 | 4384 | fonts/newpx/tfm/zplsups-BoldItalic-t1.tfm
@@ -81712,6 +81768,12 @@
2020/05/18 | 1028 | fonts/newpx/tfm/zplsyc.tfm
2020/05/18 | 1572 | fonts/newpx/tfm/zplsym.tfm
2021/03/21 | 2004 | fonts/newpx/tfm/zplsy.tfm
+2021/05/20 | 7444 | fonts/newpx/tfm/zplth-Italic-osf-ly1.tfm
+2021/05/20 | 3176 | fonts/newpx/tfm/zplth-Italic-osf-ot1.tfm
+2021/05/20 | 11852 | fonts/newpx/tfm/zplth-Italic-osf-t1.tfm
+2021/05/20 | 7396 | fonts/newpx/tfm/zplth-Italic-tlf-ly1.tfm
+2021/05/20 | 3136 | fonts/newpx/tfm/zplth-Italic-tlf-ot1.tfm
+2021/05/20 | 11812 | fonts/newpx/tfm/zplth-Italic-tlf-t1.tfm
2019/09/10 | 18529 | fonts/newpx/type1/NewPXBMI_gnu.pfb
2020/06/03 | 24085 | fonts/newpx/type1/NewPXBMI.pfb
2019/09/10 | 16003 | fonts/newpx/type1/NewPXMI_gnu.pfb
@@ -81726,12 +81788,14 @@
2019/09/11 | 40353 | fonts/newpx/type1/pxsys.pfb
2020/06/21 | 190689 | fonts/newpx/type1/zplbi.pfb
2020/06/21 | 177438 | fonts/newpx/type1/zplb.pfb
+2021/05/20 | 213291 | fonts/newpx/type1/zplbsl.pfb
2020/06/21 | 189176 | fonts/newpx/type1/zplri.pfb
2020/06/21 | 177361 | fonts/newpx/type1/zplr.pfb
+2021/05/20 | 205748 | fonts/newpx/type1/zplrsl.pfb
2015/07/16 | 3542 | fonts/newpx/type1/zplx-bold.pfb
2015/07/16 | 3685 | fonts/newpx/type1/zplx-regular.pfb
2020/05/18 | 548 | fonts/newpx/vf/zplbexa.vf
-2021/03/24 | 1280 | fonts/newpx/vf/zplbexx.vf
+2021/05/22 | 1280 | fonts/newpx/vf/zplbexx.vf
2016/10/15 | 1364 | fonts/newpx/vf/zplbmi0.vf
2020/06/03 | 2668 | fonts/newpx/vf/zplbmi1.vf
2021/03/21 | 1760 | fonts/newpx/vf/zplbmia.vf
@@ -81764,7 +81828,7 @@
2020/05/18 | 1672 | fonts/newpx/vf/zplbsym.vf
2021/03/21 | 1796 | fonts/newpx/vf/zplbsy.vf
2020/05/18 | 544 | fonts/newpx/vf/zplexa.vf
-2021/03/24 | 1308 | fonts/newpx/vf/zplexx.vf
+2021/05/22 | 1308 | fonts/newpx/vf/zplexx.vf
2020/06/21 | 1764 | fonts/newpx/vf/zpl-Italic-lf-scl-ly1.vf
2020/06/21 | 912 | fonts/newpx/vf/zpl-Italic-lf-scl-ot1.vf
2020/06/21 | 1844 | fonts/newpx/vf/zpl-Italic-lf-scl-t1.vf
@@ -81795,7 +81859,7 @@
2020/05/18 | 980 | fonts/newpx/vf/zplsyc.vf
2020/05/18 | 1668 | fonts/newpx/vf/zplsym.vf
2021/03/21 | 1792 | fonts/newpx/vf/zplsy.vf
-2021/03/25 | 3197698 | fonts/newpx.zip
+2021/05/22 | 3922729 | fonts/newpx.zip
2019/06/17 | 524 | fonts/newtx/afm/LibertineI-5nu.afm
2019/10/26 | 7516 | fonts/newtx/afm/LibertineMathBMI5.afm
2019/10/26 | 7506 | fonts/newtx/afm/LibertineMathBMI7.afm
@@ -81917,7 +81981,7 @@
2020/02/29 | 179548 | fonts/newtx/opentype/TeXGyreTermesX-Bold.otf
2020/02/29 | 186612 | fonts/newtx/opentype/TeXGyreTermesX-Italic.otf
2020/03/01 | 185476 | fonts/newtx/opentype/TeXGyreTermesX-Regular.otf
-2021/05/20 | 38415 | fonts/newtx/README
+2021/05/22 | 38560 | fonts/newtx/README
2018/06/07 | 312975 | fonts/newtxsf/doc/newtxsf-doc.pdf
2018/06/07 | 6059 | fonts/newtxsf/doc/newtxsf-doc.tex
2014/09/30 | 43780 | fonts/newtxsf/doc/OFL-FAQ.txt
@@ -81948,21 +82012,21 @@
2016/07/04 | 549 | fonts/newtx/tex/lmxntxexx.fd
2013/10/13 | 593 | fonts/newtx/tex/ly1minlibertine.fd
2020/03/02 | 1908 | fonts/newtx/tex/ly1ntxdenoms.fd
-2021/05/20 | 2071 | fonts/newtx/tex/ly1ntxlf.fd
-2021/05/20 | 1828 | fonts/newtx/tex/ly1ntxosf.fd
+2021/05/22 | 2040 | fonts/newtx/tex/ly1ntxlf.fd
+2021/05/22 | 1797 | fonts/newtx/tex/ly1ntxosf.fd
2015/03/04 | 1874 | fonts/newtx/tex/ly1ntxsups.fd
2021/05/09 | 1532 | fonts/newtx/tex/ly1ntxth-lf.fd
2021/05/09 | 1570 | fonts/newtx/tex/ly1ntxth-osf.fd
2021/05/09 | 1570 | fonts/newtx/tex/ly1ntxth-tlf.fd
2021/05/09 | 1609 | fonts/newtx/tex/ly1ntxth-tosf.fd
-2021/05/20 | 2110 | fonts/newtx/tex/ly1ntxtlf.fd
-2021/05/20 | 2288 | fonts/newtx/tex/ly1ntxtosf.fd
+2021/05/22 | 2079 | fonts/newtx/tex/ly1ntxtlf.fd
+2021/05/22 | 2257 | fonts/newtx/tex/ly1ntxtosf.fd
2012/05/01 | 1516 | fonts/newtx/tex/ly1ntxtt.fd
2019/10/01 | 164 | fonts/newtx/tex/newtx-ebgaramond-subs.tex
2019/10/01 | 149 | fonts/newtx/tex/newtx-libertine-subs.tex
2021/03/27 | 135953 | fonts/newtx/tex/newtxmath.sty
2020/12/19 | 144 | fonts/newtx/tex/newtx-subs.tex
-2021/05/16 | 11424 | fonts/newtx/tex/newtxtext.sty
+2021/05/22 | 11425 | fonts/newtx/tex/newtxtext.sty
2019/10/23 | 818 | fonts/newtx/tex/omlntxebgmi.fd
2016/10/07 | 1919 | fonts/newtx/tex/omlntxmi.fd
2018/04/27 | 781 | fonts/newtx/tex/omlntxstx2mi.fd
@@ -81972,28 +82036,28 @@
2014/04/15 | 769 | fonts/newtx/tex/omlzutmi.fd
2013/10/13 | 593 | fonts/newtx/tex/ot1minlibertine.fd
2020/03/02 | 1908 | fonts/newtx/tex/ot1ntxdenoms.fd
-2021/05/20 | 2071 | fonts/newtx/tex/ot1ntxlf.fd
-2021/05/20 | 2115 | fonts/newtx/tex/ot1ntxosf.fd
+2021/05/22 | 2040 | fonts/newtx/tex/ot1ntxlf.fd
+2021/05/22 | 2084 | fonts/newtx/tex/ot1ntxosf.fd
2015/03/04 | 1874 | fonts/newtx/tex/ot1ntxsups.fd
2021/05/09 | 1532 | fonts/newtx/tex/ot1ntxth-lf.fd
2021/05/09 | 1570 | fonts/newtx/tex/ot1ntxth-osf.fd
2021/05/09 | 1570 | fonts/newtx/tex/ot1ntxth-tlf.fd
2021/05/09 | 1608 | fonts/newtx/tex/ot1ntxth-tosf.fd
-2021/05/20 | 2109 | fonts/newtx/tex/ot1ntxtlf.fd
-2021/05/20 | 2288 | fonts/newtx/tex/ot1ntxtosf.fd
+2021/05/22 | 2078 | fonts/newtx/tex/ot1ntxtlf.fd
+2021/05/22 | 2257 | fonts/newtx/tex/ot1ntxtosf.fd
2012/05/01 | 1494 | fonts/newtx/tex/ot1ntxtt.fd
2012/08/02 | 1435 | fonts/newtx/tex/t1fxl1.fd
2013/10/13 | 583 | fonts/newtx/tex/t1minlibertine.fd
2020/03/02 | 1887 | fonts/newtx/tex/t1ntxdenoms.fd
-2021/05/20 | 2037 | fonts/newtx/tex/t1ntxlf.fd
-2021/05/20 | 2081 | fonts/newtx/tex/t1ntxosf.fd
+2021/05/22 | 2007 | fonts/newtx/tex/t1ntxlf.fd
+2021/05/22 | 2050 | fonts/newtx/tex/t1ntxosf.fd
2015/03/04 | 1850 | fonts/newtx/tex/t1ntxsups.fd
2021/05/09 | 1510 | fonts/newtx/tex/t1ntxth-lf.fd
2021/05/09 | 1549 | fonts/newtx/tex/t1ntxth-osf.fd
2021/05/09 | 1540 | fonts/newtx/tex/t1ntxth-tlf.fd
2021/05/09 | 1586 | fonts/newtx/tex/t1ntxth-tosf.fd
-2021/05/20 | 2079 | fonts/newtx/tex/t1ntxtlf.fd
-2021/05/20 | 2254 | fonts/newtx/tex/t1ntxtosf.fd
+2021/05/22 | 2048 | fonts/newtx/tex/t1ntxtlf.fd
+2021/05/22 | 2223 | fonts/newtx/tex/t1ntxtosf.fd
2012/05/01 | 1500 | fonts/newtx/tex/t1ntxtt.fd
2016/10/16 | 223 | fonts/newtx/tex/TeXGyreTermesX.fontspec
2015/01/30 | 1129 | fonts/newtx/tex/ts1ntxlf.fd
@@ -82801,7 +82865,7 @@
2019/11/02 | 2656 | fonts/newtx/vf/zutbmi.vf
2021/03/22 | 2176 | fonts/newtx/vf/zutmia.vf
2019/11/02 | 2552 | fonts/newtx/vf/zutmi.vf
-2021/05/20 | 8397497 | fonts/newtx.zip
+2021/05/22 | 8397576 | fonts/newtx.zip
2005/10/24 | 6224 | fonts/niceframe/afm/bbding10.afm
2005/10/24 | 2299 | fonts/niceframe/afm/dingbat.afm
2005/10/24 | 9099 | fonts/niceframe/afm/karta15.afm
@@ -172012,10 +172076,10 @@
2014/05/15 | 266221 | info/tex-virtual-academy-pl/tex/tex_key.html
2014/05/05 | 17632 | info/tex-virtual-academy-pl/tex/tryby.html
2014/05/21 | 1415765 | info/tex-virtual-academy-pl.zip
-2021/05/08 | 144813 | info/tlmgrbasics/doc/tlmgr.pdf
-2021/05/08 | 22358 | info/tlmgrbasics/doc/tlmgr.tex
-2021/05/08 | 447 | info/tlmgrbasics/README
-2021/05/08 | 151039 | info/tlmgrbasics.zip
+2021/05/21 | 157582 | info/tlmgrbasics/doc/tlmgr.pdf
+2021/05/21 | 22984 | info/tlmgrbasics/doc/tlmgr.tex
+2021/05/22 | 447 | info/tlmgrbasics/README
+2021/05/22 | 163689 | info/tlmgrbasics.zip
2021/05/05 | 23941 | info/tlmgr-intro-zh-cn/body/actions.tex
2021/05/05 | 1030 | info/tlmgr-intro-zh-cn/body/examples.tex
2021/05/05 | 3020 | info/tlmgr-intro-zh-cn/body/mirrors.tex
@@ -186214,7 +186278,7 @@
2013/04/01 | 14776 | macros/context/contrib/context-visualcounter/tex/context/third/visualcounter/t-visualcounter.mkvi
2018/03/05 | 11 | macros/context/contrib/context-visualcounter/VERSION
2018/03/22 | 276789 | macros/context/contrib/context-visualcounter.zip
-2021/05/20 | 122787914 | macros/context/latest/cont-tmf.zip
+2021/05/21 | 122791173 | macros/context/latest/cont-tmf.zip
2016/04/21 | 32846 | macros/cstex/base/cmexb.tar.gz
2016/06/26 | 1728262 | macros/cstex/base/csfonts-t1.tar.gz
2007/03/01 | 187106 | macros/cstex/base/csfonts.tar.gz
@@ -193626,6 +193690,35 @@
2018/01/04 | 229251 | macros/latex/contrib/blowup/blowup.pdf
2018/01/04 | 312 | macros/latex/contrib/blowup/README.md
2018/01/04 | 377299 | macros/latex/contrib/blowup.zip
+2021/05/22 | 2145 | macros/latex/contrib/bmstu-iu8/BMSTU-IU8.cls
+2021/05/22 | 192899 | macros/latex/contrib/bmstu-iu8/example.pdf
+2021/05/22 | 1520 | macros/latex/contrib/bmstu-iu8/example.tex
+2021/05/22 | 53203 | macros/latex/contrib/bmstu-iu8/inc/bmstu.png
+2021/05/22 | 1106 | macros/latex/contrib/bmstu-iu8/LICENSE
+2021/05/22 | 175 | macros/latex/contrib/bmstu-iu8/README.md
+2021/05/22 | 2551 | macros/latex/contrib/bmstu-iu8/styles/01-IU8-base.sty
+2021/05/22 | 3854 | macros/latex/contrib/bmstu-iu8/styles/02-IU8-construction.sty
+2021/05/22 | 1315 | macros/latex/contrib/bmstu-iu8/styles/03-IU8-numbering.sty
+2021/05/22 | 3560 | macros/latex/contrib/bmstu-iu8/styles/04-IU8-section-numbering.sty
+2021/05/22 | 4073 | macros/latex/contrib/bmstu-iu8/styles/05-IU8-figures.sty
+2021/05/22 | 6222 | macros/latex/contrib/bmstu-iu8/styles/06-IU8-tables.sty
+2021/05/22 | 2985 | macros/latex/contrib/bmstu-iu8/styles/07-IU8-footnotes.sty
+2021/05/22 | 213 | macros/latex/contrib/bmstu-iu8/styles/08-IU8-formulas.sty
+2021/05/22 | 1614 | macros/latex/contrib/bmstu-iu8/styles/09-IU8-cites.sty
+2021/05/22 | 8409 | macros/latex/contrib/bmstu-iu8/styles/10-IU8-titlepage.sty
+2021/05/22 | 243 | macros/latex/contrib/bmstu-iu8/styles/11-IU8-performers.sty
+2021/05/22 | 1720 | macros/latex/contrib/bmstu-iu8/styles/12-IU8-abstract.sty
+2021/05/22 | 1694 | macros/latex/contrib/bmstu-iu8/styles/13-IU8-contents.sty
+2021/05/22 | 1101 | macros/latex/contrib/bmstu-iu8/styles/14-IU8-terms-and-definitions.sty
+2021/05/22 | 740 | macros/latex/contrib/bmstu-iu8/styles/15-IU8-list-of-abbreviations.sty
+2021/05/22 | 1139 | macros/latex/contrib/bmstu-iu8/styles/16-IU8-references.sty
+2021/05/22 | 797 | macros/latex/contrib/bmstu-iu8/styles/17-IU8-appendices.sty
+2021/05/22 | 781 | macros/latex/contrib/bmstu-iu8/styles/18-IU8-extra.sty
+2021/05/22 | 668 | macros/latex/contrib/bmstu-iu8/styles/19-IU8-counters.sty
+2021/05/22 | 1236 | macros/latex/contrib/bmstu-iu8/styles/20-IU8-listing.sty
+2021/05/22 | 422 | macros/latex/contrib/bmstu-iu8/styles/21-IU8-math.sty
+2021/05/22 | 1437 | macros/latex/contrib/bmstu-iu8/styles/22-IU8-algorithms.sty
+2021/05/22 | 252401 | macros/latex/contrib/bmstu-iu8.zip
2021/05/17 | 79556 | macros/latex/contrib/bnumexpr/bnumexpr.dtx
2021/05/17 | 131719 | macros/latex/contrib/bnumexpr/bnumexpr.pdf
2021/05/17 | 3182 | macros/latex/contrib/bnumexpr/README.md
@@ -205592,11 +205685,11 @@
2016/07/03 | 1176 | macros/latex/contrib/milog/README.md
2016/07/03 | 488253 | macros/latex/contrib/milog.zip
2021/03/10 | 19106 | macros/latex/contrib/mindflow/LICENSE
-2021/05/07 | 11474 | macros/latex/contrib/mindflow/mindflow.dtx
+2021/05/22 | 13446 | macros/latex/contrib/mindflow/mindflow.dtx
2021/03/12 | 1705 | macros/latex/contrib/mindflow/mindflow.ins
-2021/05/07 | 179867 | macros/latex/contrib/mindflow/mindflow.pdf
+2021/05/22 | 187098 | macros/latex/contrib/mindflow/mindflow.pdf
2021/03/17 | 396 | macros/latex/contrib/mindflow/README.md
-2021/05/08 | 190031 | macros/latex/contrib/mindflow.zip
+2021/05/22 | 197754 | macros/latex/contrib/mindflow.zip
2013/06/21 | 72 | macros/latex/contrib/minibox/minibox.ins
2013/06/21 | 280644 | macros/latex/contrib/minibox/minibox.pdf
2013/06/21 | 7633 | macros/latex/contrib/minibox/minibox.tex
@@ -259149,13 +259242,13 @@
2015/10/16 | 37575 | support/ltxfileinfo/ltxfileinfo.pdf
2015/10/16 | 590 | support/ltxfileinfo/README
2015/10/16 | 42423 | support/ltxfileinfo.zip
-2021/01/24 | 10599 | support/ltximg/ltximg.1
-2021/01/24 | 316588 | support/ltximg/ltximg-doc.pdf
-2021/01/24 | 88633 | support/ltximg/ltximg-doc.tex
-2021/01/24 | 27866 | support/ltximg/ltximg.man1.pdf
-2021/01/24 | 134800 | support/ltximg/ltximg.pl
-2021/01/24 | 6390 | support/ltximg/README.md
-2021/01/25 | 280081 | support/ltximg.zip
+2021/05/21 | 10599 | support/ltximg/ltximg.1
+2021/05/21 | 319369 | support/ltximg/ltximg-doc.pdf
+2021/05/21 | 90192 | support/ltximg/ltximg-doc.tex
+2021/05/21 | 27866 | support/ltximg/ltximg.man1.pdf
+2021/05/21 | 134852 | support/ltximg/ltximg.pl
+2021/05/21 | 6390 | support/ltximg/README.md
+2021/05/22 | 283291 | support/ltximg.zip
1996/11/22 | 25535 | support/ltxinput/ltxinput.zip
1996/11/10 | 971 | support/ltxinput/readme.txt
2010/03/15 | 4720 | support/lualibs/lua-alt-getopt/lua-alt-getopt-0.7.0.tar.gz
@@ -261857,160 +261950,340 @@
1994/01/18 | 7272 | support/tex-it/texitrc.unx
1994/01/18 | 25068 | support/tex-it/texit.tex
2006/03/12 | 50172 | support/tex-it.zip
-2021/01/06 | 105 | support/texlab/benches/bench_main.rs
-2021/01/06 | 4769 | support/texlab/benches/benchmarks/completion.rs
-2021/01/06 | 20 | support/texlab/benches/benchmarks/mod.rs
-2021/01/06 | 159 | support/texlab/build.rs
-2021/01/06 | 77849 | support/texlab/Cargo.lock
-2021/01/06 | 2728 | support/texlab/Cargo.toml
-2021/01/06 | 10718 | support/texlab/CHANGELOG.md
-2021/01/06 | 183 | support/texlab/CONTRIBUTING.md
-2021/01/06 | 428 | support/texlab/crates/jsonrpc/Cargo.toml
-2021/01/06 | 267 | support/texlab/crates/jsonrpc_derive/Cargo.toml
-2021/01/06 | 6243 | support/texlab/crates/jsonrpc_derive/src/lib.rs
-2021/01/06 | 2200 | support/texlab/crates/jsonrpc/src/client.rs
-2021/01/06 | 2137 | support/texlab/crates/jsonrpc/src/lib.rs
-2021/01/06 | 3530 | support/texlab/crates/jsonrpc/src/server.rs
-2021/01/06 | 3370 | support/texlab/crates/jsonrpc/src/types.rs
-2021/01/06 | 24234835 | support/texlab/data/components.json
-2021/01/06 | 75525 | support/texlab/data/lang_data.json
-2021/01/06 | 35149 | support/texlab/LICENSE
-2021/01/06 | 3001 | support/texlab/README.md
-2021/01/06 | 6 | support/texlab/rust-toolchain
-2021/01/06 | 6732 | support/texlab/src/build.rs
-2021/01/06 | 56296 | support/texlab/src/citeproc/apa.csl
-2021/01/06 | 4641 | support/texlab/src/citeproc/bibutils.rs
-2021/01/06 | 6076 | support/texlab/src/citeproc/mod.rs
-2021/01/06 | 8329 | support/texlab/src/citeproc/name/mod.rs
-2021/01/06 | 4294 | support/texlab/src/citeproc/name/parser.lalrpop
-2021/01/06 | 16187 | support/texlab/src/citeproc/ris.rs
-2021/01/06 | 4948 | support/texlab/src/completion/bibtex/cmd.rs
-2021/01/06 | 4797 | support/texlab/src/completion/bibtex/entry_type.rs
-2021/01/06 | 5401 | support/texlab/src/completion/bibtex/field_name.rs
-2021/01/06 | 53 | support/texlab/src/completion/bibtex/mod.rs
-2021/01/06 | 6097 | support/texlab/src/completion/latex/argument.rs
-2021/01/06 | 1887 | support/texlab/src/completion/latex/begin_cmd.rs
-2021/01/06 | 7406 | support/texlab/src/completion/latex/citation.rs
-2021/01/06 | 2787 | support/texlab/src/completion/latex/color_model.rs
-2021/01/06 | 2533 | support/texlab/src/completion/latex/color.rs
-2021/01/06 | 4630 | support/texlab/src/completion/latex/combinators.rs
-2021/01/06 | 10102 | support/texlab/src/completion/latex/component.rs
-2021/01/06 | 3304 | support/texlab/src/completion/latex/glossary.rs
-2021/01/06 | 5339 | support/texlab/src/completion/latex/import.rs
-2021/01/06 | 4095 | support/texlab/src/completion/latex/include.rs
-2021/01/06 | 7418 | support/texlab/src/completion/latex/label.rs
-2021/01/06 | 242 | support/texlab/src/completion/latex/mod.rs
-2021/01/06 | 3142 | support/texlab/src/completion/latex/theorem.rs
-2021/01/06 | 3743 | support/texlab/src/completion/latex/tikz_lib.rs
-2021/01/06 | 5973 | support/texlab/src/completion/latex/user.rs
-2021/01/06 | 18149 | support/texlab/src/completion/mod.rs
-2021/01/06 | 3374 | support/texlab/src/completion/types.rs
-2021/01/06 | 4258 | support/texlab/src/completion/util.rs
-2021/01/06 | 2715 | support/texlab/src/components.rs
-2021/01/06 | 3201 | support/texlab/src/config.rs
-2021/01/06 | 5268 | support/texlab/src/definition/bibtex_string.rs
-2021/01/06 | 3814 | support/texlab/src/definition/latex_citation.rs
-2021/01/06 | 5328 | support/texlab/src/definition/latex_cmd.rs
-2021/01/06 | 5402 | support/texlab/src/definition/latex_label.rs
-2021/01/06 | 1315 | support/texlab/src/definition/mod.rs
-2021/01/06 | 10469 | support/texlab/src/diagnostics/bibtex.rs
-2021/01/06 | 55964 | support/texlab/src/diagnostics/build.rs
-2021/01/06 | 3390 | support/texlab/src/diagnostics/latex.rs
-2021/01/06 | 773 | support/texlab/src/diagnostics/mod.rs
-2021/01/06 | 11900 | support/texlab/src/feature.rs
-2021/01/06 | 4828 | support/texlab/src/folding/bibtex_decl.rs
-2021/01/06 | 2423 | support/texlab/src/folding/latex_env.rs
-2021/01/06 | 3512 | support/texlab/src/folding/latex_section.rs
-2021/01/06 | 1155 | support/texlab/src/folding/mod.rs
-2021/01/06 | 2519 | support/texlab/src/forward_search.rs
-2021/01/06 | 3484 | support/texlab/src/highlight/latex_label.rs
-2021/01/06 | 912 | support/texlab/src/highlight/mod.rs
-2021/01/06 | 3440 | support/texlab/src/hover/bibtex/entry_type.rs
-2021/01/06 | 3282 | support/texlab/src/hover/bibtex/field.rs
-2021/01/06 | 61 | support/texlab/src/hover/bibtex/mod.rs
-2021/01/06 | 4829 | support/texlab/src/hover/bibtex/string_reference.rs
-2021/01/06 | 5443 | support/texlab/src/hover/latex/citation.rs
-2021/01/06 | 2884 | support/texlab/src/hover/latex/component.rs
-2021/01/06 | 3756 | support/texlab/src/hover/latex/label.rs
-2021/01/06 | 99 | support/texlab/src/hover/latex/mod.rs
-2021/01/06 | 11015 | support/texlab/src/hover/latex/preview.rs
-2021/01/06 | 1631 | support/texlab/src/hover/mod.rs
-2021/01/06 | 536 | support/texlab/src/lib.rs
-2021/01/06 | 2737 | support/texlab/src/link/latex_import.rs
-2021/01/06 | 2854 | support/texlab/src/link/latex_include.rs
-2021/01/06 | 992 | support/texlab/src/link/mod.rs
-2021/01/06 | 2808 | support/texlab/src/main.rs
-2021/01/06 | 13772 | support/texlab/src/outline.rs
-2021/01/06 | 4767 | support/texlab/src/protocol/capabilities.rs
-2021/01/06 | 1172 | support/texlab/src/protocol/client.rs
-2021/01/06 | 4426 | support/texlab/src/protocol/codec.rs
-2021/01/06 | 308 | support/texlab/src/protocol/edit.rs
-2021/01/06 | 1520 | support/texlab/src/protocol/mod.rs
-2021/01/06 | 2846 | support/texlab/src/protocol/options.rs
-2021/01/06 | 2446 | support/texlab/src/protocol/range.rs
-2021/01/06 | 2088 | support/texlab/src/protocol/uri.rs
-2021/01/06 | 7013 | support/texlab/src/reference/bibtex_entry.rs
-2021/01/06 | 8063 | support/texlab/src/reference/bibtex_string.rs
-2021/01/06 | 6291 | support/texlab/src/reference/latex_label.rs
-2021/01/06 | 1136 | support/texlab/src/reference/mod.rs
-2021/01/06 | 6225 | support/texlab/src/rename/bibtex_entry.rs
-2021/01/06 | 4000 | support/texlab/src/rename/latex_cmd.rs
-2021/01/06 | 4624 | support/texlab/src/rename/latex_env.rs
-2021/01/06 | 4399 | support/texlab/src/rename/latex_label.rs
-2021/01/06 | 2378 | support/texlab/src/rename/mod.rs
-2021/01/06 | 28849 | support/texlab/src/server.rs
-2021/01/06 | 5112 | support/texlab/src/symbol/bibtex_entry.rs
-2021/01/06 | 3082 | support/texlab/src/symbol/bibtex_string.rs
-2021/01/06 | 2463 | support/texlab/src/symbol/latex_section/enumeration.rs
-2021/01/06 | 1254 | support/texlab/src/symbol/latex_section/equation.rs
-2021/01/06 | 1870 | support/texlab/src/symbol/latex_section/float.rs
-2021/01/06 | 20796 | support/texlab/src/symbol/latex_section/mod.rs
-2021/01/06 | 2574 | support/texlab/src/symbol/latex_section/theorem.rs
-2021/01/06 | 5232 | support/texlab/src/symbol/mod.rs
-2021/01/06 | 6358 | support/texlab/src/symbol/project_order.rs
-2021/01/06 | 3467 | support/texlab/src/symbol/types.rs
-2021/01/06 | 9921 | support/texlab/src/syntax/bibtex/ast.rs
-2021/01/06 | 10189 | support/texlab/src/syntax/bibtex/formatter.rs
-2021/01/06 | 5702 | support/texlab/src/syntax/bibtex/lexer.rs
-2021/01/06 | 10692 | support/texlab/src/syntax/bibtex/mod.rs
-2021/01/06 | 12792 | support/texlab/src/syntax/bibtex/parser.rs
-2021/01/06 | 1268 | support/texlab/src/syntax/generic_ast.rs
-2021/01/06 | 6858 | support/texlab/src/syntax/lang_data.rs
-2021/01/06 | 27466 | support/texlab/src/syntax/latex/analysis.rs
-2021/01/06 | 9884 | support/texlab/src/syntax/latex/ast.rs
-2021/01/06 | 631 | support/texlab/src/syntax/latexindent.rs
-2021/01/06 | 5177 | support/texlab/src/syntax/latex/lexer.rs
-2021/01/06 | 18266 | support/texlab/src/syntax/latex/mod.rs
-2021/01/06 | 5618 | support/texlab/src/syntax/latex/parser.rs
-2021/01/06 | 4009 | support/texlab/src/syntax/lsp_kind.rs
-2021/01/06 | 251 | support/texlab/src/syntax/mod.rs
-2021/01/06 | 6655 | support/texlab/src/syntax/text.rs
-2021/01/06 | 3203 | support/texlab/src/test/client.rs
-2021/01/06 | 20013 | support/texlab/src/test/mod.rs
-2021/01/06 | 3079 | support/texlab/src/test/server.rs
-2021/01/06 | 2333 | support/texlab/src/tex/compile.rs
-2021/01/06 | 3019 | support/texlab/src/tex/kpsewhich.rs
-2021/01/06 | 3453 | support/texlab/src/tex/miktex.rs
-2021/01/06 | 4225 | support/texlab/src/tex/mod.rs
-2021/01/06 | 936 | support/texlab/src/tex/tectonic.rs
-2021/01/06 | 1932 | support/texlab/src/tex/texlive.rs
-2021/01/06 | 31524 | support/texlab/src/workspace.rs
-2021/01/06 | 33433 | support/texlab/tests/integration/completion.rs
-2021/01/06 | 13919 | support/texlab/tests/integration/definition.rs
-2021/01/06 | 11552 | support/texlab/tests/integration/document_symbol.rs
-2021/01/06 | 3328 | support/texlab/tests/integration/folding.rs
-2021/01/06 | 2260 | support/texlab/tests/integration/highlight.rs
-2021/01/06 | 2282 | support/texlab/tests/integration/hover.rs
-2021/01/06 | 9627 | support/texlab/tests/integration/issues.rs
-2021/01/06 | 4663 | support/texlab/tests/integration/link.rs
-2021/01/06 | 183 | support/texlab/tests/integration/main.rs
-2021/01/06 | 3771 | support/texlab/tests/integration/prepare_rename.rs
-2021/01/06 | 3890 | support/texlab/tests/integration/reference.rs
-2021/01/06 | 6021 | support/texlab/tests/integration/rename.rs
-2021/01/06 | 6532 | support/texlab/tests/integration/workspace_symbol.rs
-2021/01/06 | 643 | support/texlab/texlab.1
-2021/01/06 | 84894 | support/texlab/texlab.pdf
-2021/01/06 | 7307447 | support/texlab.zip
+2021/05/22 | 159 | support/texlab/build.rs
+2021/05/22 | 65697 | support/texlab/Cargo.lock
+2021/05/22 | 2217 | support/texlab/Cargo.toml
+2021/05/22 | 13757 | support/texlab/CHANGELOG.md
+2021/05/22 | 183 | support/texlab/CONTRIBUTING.md
+2021/05/22 | 24234835 | support/texlab/data/components.json
+2021/05/22 | 57018 | support/texlab/data/lang_data.json
+2021/05/22 | 2021 | support/texlab/docs/custom_messages.md
+2021/05/22 | 380190 | support/texlab/docs/demo.gif
+2021/05/22 | 2250 | support/texlab/docs/lsp_kinds.md
+2021/05/22 | 2988 | support/texlab/docs/options.md
+2021/05/22 | 6092 | support/texlab/docs/previewing.md
+2021/05/22 | 745 | support/texlab/docs/tectonic.md
+2021/05/22 | 35149 | support/texlab/LICENSE
+2021/05/22 | 4533 | support/texlab/README.md
+2021/05/22 | 6 | support/texlab/rust-toolchain
+2021/05/22 | 4994 | support/texlab/src/capabilities.rs
+2021/05/22 | 56296 | support/texlab/src/citation/apa.csl
+2021/05/22 | 4729 | support/texlab/src/citation/bibutils.rs
+2021/05/22 | 4294 | support/texlab/src/citation/name/parser.lalrpop
+2021/05/22 | 8414 | support/texlab/src/citation/name.rs
+2021/05/22 | 16188 | support/texlab/src/citation/ris.rs
+2021/05/22 | 4587 | support/texlab/src/citation.rs
+2021/05/22 | 1593 | support/texlab/src/client.rs
+2021/05/22 | 4218 | support/texlab/src/component_db.rs
+2021/05/22 | 2801 | support/texlab/src/config.rs
+2021/05/22 | 883 | support/texlab/src/context.rs
+2021/05/22 | 4561 | support/texlab/src/diagnostics/bibtex.rs
+2021/05/22 | 2070 | support/texlab/src/diagnostics/build_log.rs
+2021/05/22 | 3167 | support/texlab/src/diagnostics/chktex.rs
+2021/05/22 | 2240 | support/texlab/src/diagnostics/debouncer.rs
+2021/05/22 | 4195 | support/texlab/src/diagnostics/latex.rs
+2021/05/22 | 1780 | support/texlab/src/diagnostics.rs
+2021/05/22 | 2084 | support/texlab/src/dispatch.rs
+2021/05/22 | 2019 | support/texlab/src/distro/kpsewhich.rs
+2021/05/22 | 2620 | support/texlab/src/distro/miktex.rs
+2021/05/22 | 2108 | support/texlab/src/distro.rs
+2021/05/22 | 1074 | support/texlab/src/distro/texlive.rs
+2021/05/22 | 3627 | support/texlab/src/features/build.rs
+2021/05/22 | 5204 | support/texlab/src/features/completion/acronym_ref.rs
+2021/05/22 | 5650 | support/texlab/src/features/completion/argument.rs
+2021/05/22 | 2337 | support/texlab/src/features/completion/begin_command.rs
+2021/05/22 | 7200 | support/texlab/src/features/completion/citation.rs
+2021/05/22 | 5640 | support/texlab/src/features/completion/color_model.rs
+2021/05/22 | 3389 | support/texlab/src/features/completion/color.rs
+2021/05/22 | 5361 | support/texlab/src/features/completion/component_command.rs
+2021/05/22 | 5190 | support/texlab/src/features/completion/component_environment.rs
+2021/05/22 | 6955 | support/texlab/src/features/completion/entry_type.rs
+2021/05/22 | 5895 | support/texlab/src/features/completion/field.rs
+2021/05/22 | 4496 | support/texlab/src/features/completion/glossary_ref.rs
+2021/05/22 | 5917 | support/texlab/src/features/completion/import.rs
+2021/05/22 | 5485 | support/texlab/src/features/completion/include.rs
+2021/05/22 | 6850 | support/texlab/src/features/completion/label.rs
+2021/05/22 | 23209 | support/texlab/src/features/completion.rs
+2021/05/22 | 4482 | support/texlab/src/features/completion/theorem.rs
+2021/05/22 | 5051 | support/texlab/src/features/completion/tikz_library.rs
+2021/05/22 | 3471 | support/texlab/src/features/completion/types.rs
+2021/05/22 | 2874 | support/texlab/src/features/completion/user_command.rs
+2021/05/22 | 3308 | support/texlab/src/features/completion/user_environment.rs
+2021/05/22 | 1789 | support/texlab/src/features/completion/util.rs
+2021/05/22 | 7230 | support/texlab/src/features/cursor.rs
+2021/05/22 | 3982 | support/texlab/src/features/definition/command.rs
+2021/05/22 | 3615 | support/texlab/src/features/definition/document.rs
+2021/05/22 | 3856 | support/texlab/src/features/definition/entry.rs
+2021/05/22 | 2688 | support/texlab/src/features/definition/label.rs
+2021/05/22 | 1084 | support/texlab/src/features/definition.rs
+2021/05/22 | 5296 | support/texlab/src/features/definition/string.rs
+2021/05/22 | 7067 | support/texlab/src/features/folding.rs
+2021/05/22 | 12483 | support/texlab/src/features/formatting/bibtex_internal.rs
+2021/05/22 | 1457 | support/texlab/src/features/formatting/latexindent.rs
+2021/05/22 | 745 | support/texlab/src/features/formatting.rs
+2021/05/22 | 117 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__command.snap
+2021/05/22 | 124 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__concatenation.snap
+2021/05/22 | 114 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__insert_braces.snap
+2021/05/22 | 565 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__multiple_entries.snap
+2021/05/22 | 102 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__parens.snap
+2021/05/22 | 111 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__preamble.snap
+2021/05/22 | 107 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__string.snap
+2021/05/22 | 114 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__trailing_comma.snap
+2021/05/22 | 299 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__wrap_long_lines.snap
+2021/05/22 | 3317 | support/texlab/src/features/forward_search.rs
+2021/05/22 | 5131 | support/texlab/src/features/highlight/label.rs
+2021/05/22 | 381 | support/texlab/src/features/highlight.rs
+2021/05/22 | 4010 | support/texlab/src/features/hover/citation.rs
+2021/05/22 | 3043 | support/texlab/src/features/hover/component.rs
+2021/05/22 | 3670 | support/texlab/src/features/hover/entry_type.rs
+2021/05/22 | 3693 | support/texlab/src/features/hover/field.rs
+2021/05/22 | 2246 | support/texlab/src/features/hover/label.rs
+2021/05/22 | 1265 | support/texlab/src/features/hover.rs
+2021/05/22 | 4060 | support/texlab/src/features/hover/string_ref.rs
+2021/05/22 | 3409 | support/texlab/src/features/link.rs
+2021/05/22 | 3993 | support/texlab/src/features/lsp_kinds.rs
+2021/05/22 | 6832 | support/texlab/src/features/reference/entry.rs
+2021/05/22 | 6188 | support/texlab/src/features/reference/label.rs
+2021/05/22 | 821 | support/texlab/src/features/reference.rs
+2021/05/22 | 6618 | support/texlab/src/features/reference/string.rs
+2021/05/22 | 3072 | support/texlab/src/features/rename/command.rs
+2021/05/22 | 5460 | support/texlab/src/features/rename/entry.rs
+2021/05/22 | 4912 | support/texlab/src/features/rename/label.rs
+2021/05/22 | 1138 | support/texlab/src/features/rename.rs
+2021/05/22 | 9399 | support/texlab/src/features.rs
+2021/05/22 | 10438 | support/texlab/src/features/semantic/bibtex.rs
+2021/05/22 | 2361 | support/texlab/src/features/semantic/legend.rs
+2021/05/22 | 559 | support/texlab/src/features/semantic.rs
+2021/05/22 | 3370 | support/texlab/src/features/symbol/bibtex.rs
+2021/05/22 | 14204 | support/texlab/src/features/symbol/latex.rs
+2021/05/22 | 6888 | support/texlab/src/features/symbol/project_order.rs
+2021/05/22 | 3553 | support/texlab/src/features/symbol.rs
+2021/05/22 | 3707 | support/texlab/src/features/symbol/types.rs
+2021/05/22 | 8660 | support/texlab/src/label.rs
+2021/05/22 | 1998 | support/texlab/src/lang_data.rs
+2021/05/22 | 923 | support/texlab/src/language.rs
+2021/05/22 | 688 | support/texlab/src/lib.rs
+2021/05/22 | 1270 | support/texlab/src/line_index_ext.rs
+2021/05/22 | 6484 | support/texlab/src/line_index.rs
+2021/05/22 | 1914 | support/texlab/src/main.rs
+2021/05/22 | 2045 | support/texlab/src/options.rs
+2021/05/22 | 488 | support/texlab/src/range.rs
+2021/05/22 | 361 | support/texlab/src/req_queue.rs
+2021/05/22 | 29437 | support/texlab/src/server.rs
+2021/05/22 | 5847 | support/texlab/src/syntax/bibtex/cst.rs
+2021/05/22 | 846 | support/texlab/src/syntax/bibtex/kind.rs
+2021/05/22 | 1662 | support/texlab/src/syntax/bibtex/lexer.rs
+2021/05/22 | 10375 | support/texlab/src/syntax/bibtex/parser.rs
+2021/05/22 | 802 | support/texlab/src/syntax/bibtex.rs
+2021/05/22 | 85 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__empty.snap
+2021/05/22 | 989 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap
+2021/05/22 | 209 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap
+2021/05/22 | 231 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap
+2021/05/22 | 640 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap
+2021/05/22 | 632 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap
+2021/05/22 | 654 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap
+2021/05/22 | 769 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap
+2021/05/22 | 1061 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap
+2021/05/22 | 181 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__junk.snap
+2021/05/22 | 480 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_casing.snap
+2021/05/22 | 480 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_complete.snap
+2021/05/22 | 446 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_missing_end.snap
+2021/05/22 | 519 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_casing.snap
+2021/05/22 | 519 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_complete.snap
+2021/05/22 | 1038 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_concatenation.snap
+2021/05/22 | 517 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_incomplete.snap
+2021/05/22 | 517 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_missing_quote.snap
+2021/05/22 | 51420 | support/texlab/src/syntax/build_log.rs
+2021/05/22 | 341 | support/texlab/src/syntax/latex/analysis/command.rs
+2021/05/22 | 2171 | support/texlab/src/syntax/latex/analysis/distro_file.rs
+2021/05/22 | 362 | support/texlab/src/syntax/latex/analysis/environment.rs
+2021/05/22 | 2335 | support/texlab/src/syntax/latex/analysis/explicit_link.rs
+2021/05/22 | 1578 | support/texlab/src/syntax/latex/analysis/implicit_link.rs
+2021/05/22 | 1910 | support/texlab/src/syntax/latex/analysis/label_name.rs
+2021/05/22 | 637 | support/texlab/src/syntax/latex/analysis/label_number.rs
+2021/05/22 | 1141 | support/texlab/src/syntax/latex/analysis.rs
+2021/05/22 | 586 | support/texlab/src/syntax/latex/analysis/theorem.rs
+2021/05/22 | 1862 | support/texlab/src/syntax/latex/analysis/types.rs
+2021/05/22 | 16759 | support/texlab/src/syntax/latex/cst.rs
+2021/05/22 | 4380 | support/texlab/src/syntax/latex/kind.rs
+2021/05/22 | 6927 | support/texlab/src/syntax/latex/lexer.rs
+2021/05/22 | 45753 | support/texlab/src/syntax/latex/parser.rs
+2021/05/22 | 833 | support/texlab/src/syntax/latex.rs
+2021/05/22 | 575 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_parameter.snap
+2021/05/22 | 277 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_star.snap
+2021/05/22 | 425 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__comment.snap
+2021/05/22 | 901 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__delimiters.snap
+2021/05/22 | 76 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__empty.snap
+2021/05/22 | 234 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__escape_sequence.snap
+2021/05/22 | 614 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__formula.snap
+2021/05/22 | 123 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__invalid_parameter.snap
+2021/05/22 | 1454 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap
+2021/05/22 | 1353 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap
+2021/05/22 | 721 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap
+2021/05/22 | 765 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap
+2021/05/22 | 310 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap
+2021/05/22 | 822 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap
+2021/05/22 | 334 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap
+2021/05/22 | 318 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap
+2021/05/22 | 281 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_missing_end.snap
+2021/05/22 | 283 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_simple.snap
+2021/05/22 | 621 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_error.snap
+2021/05/22 | 727 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap
+2021/05/22 | 489 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal_error.snap
+2021/05/22 | 491 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal.snap
+2021/05/22 | 623 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption.snap
+2021/05/22 | 243 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_empty.snap
+2021/05/22 | 268 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap
+2021/05/22 | 361 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap
+2021/05/22 | 537 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap
+2021/05/22 | 405 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap
+2021/05/22 | 327 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap
+2021/05/22 | 275 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap
+2021/05/22 | 275 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap
+2021/05/22 | 281 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_empty.snap
+2021/05/22 | 1029 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap
+2021/05/22 | 318 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap
+2021/05/22 | 668 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap
+2021/05/22 | 292 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap
+2021/05/22 | 750 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap
+2021/05/22 | 546 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap
+2021/05/22 | 455 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap
+2021/05/22 | 302 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error4.snap
+2021/05/22 | 841 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap
+2021/05/22 | 464 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_argc.snap
+2021/05/22 | 354 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl_error.snap
+2021/05/22 | 356 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl.snap
+2021/05/22 | 595 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap
+2021/05/22 | 100 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__empty.snap
+2021/05/22 | 1073 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap
+2021/05/22 | 1191 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap
+2021/05/22 | 1041 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap
+2021/05/22 | 682 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap
+2021/05/22 | 293 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap
+2021/05/22 | 764 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap
+2021/05/22 | 795 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap
+2021/05/22 | 360 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation.snap
+2021/05/22 | 354 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__escaped_brackets.snap
+2021/05/22 | 425 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_args.snap
+2021/05/22 | 170 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_empty.snap
+2021/05/22 | 166 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_escape.snap
+2021/05/22 | 923 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap
+2021/05/22 | 854 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap
+2021/05/22 | 295 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap
+2021/05/22 | 675 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap
+2021/05/22 | 336 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap
+2021/05/22 | 205 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__hello_world.snap
+2021/05/22 | 294 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap
+2021/05/22 | 387 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap
+2021/05/22 | 647 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap
+2021/05/22 | 308 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap
+2021/05/22 | 630 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline_double_dollar.snap
+2021/05/22 | 624 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline.snap
+2021/05/22 | 290 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap
+2021/05/22 | 537 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap
+2021/05/22 | 371 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap
+2021/05/22 | 426 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap
+2021/05/22 | 337 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap
+2021/05/22 | 428 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap
+2021/05/22 | 282 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap
+2021/05/22 | 301 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap
+2021/05/22 | 305 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap
+2021/05/22 | 364 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_no_impl.snap
+2021/05/22 | 472 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_simple.snap
+2021/05/22 | 279 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_empty.snap
+2021/05/22 | 408 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap
+2021/05/22 | 1027 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap
+2021/05/22 | 316 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap
+2021/05/22 | 124 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter_error.snap
+2021/05/22 | 126 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter.snap
+2021/05/22 | 322 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap
+2021/05/22 | 1237 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap
+2021/05/22 | 521 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_invalid_nesting.snap
+2021/05/22 | 1791 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_nested.snap
+2021/05/22 | 677 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_siblings.snap
+2021/05/22 | 655 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap
+2021/05/22 | 316 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap
+2021/05/22 | 671 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap
+2021/05/22 | 448 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap
+2021/05/22 | 556 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap
+2021/05/22 | 441 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap
+2021/05/22 | 333 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap
+2021/05/22 | 324 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap
+2021/05/22 | 206 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_braces.snap
+2021/05/22 | 206 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets.snap
+2021/05/22 | 285 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets_with_group.snap
+2021/05/22 | 332 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap
+2021/05/22 | 342 | support/texlab/src/syntax.rs
+2021/05/22 | 1886 | support/texlab/src/uri.rs
+2021/05/22 | 2209 | support/texlab/src/workspace/api.rs
+2021/05/22 | 2564 | support/texlab/src/workspace/children_expand.rs
+2021/05/22 | 3243 | support/texlab/src/workspace/document.rs
+2021/05/22 | 3596 | support/texlab/src/workspace/parent_expand.rs
+2021/05/22 | 869 | support/texlab/src/workspace.rs
+2021/05/22 | 3994 | support/texlab/src/workspace/storage.rs
+2021/05/22 | 2984 | support/texlab/src/workspace/watch.rs
+2021/05/22 | 11495 | support/texlab/tests/integration/common.rs
+2021/05/22 | 21810 | support/texlab/tests/integration/completion.rs
+2021/05/22 | 11519 | support/texlab/tests/integration/document_symbol.rs
+2021/05/22 | 2218 | support/texlab/tests/integration/hover.rs
+2021/05/22 | 1243 | support/texlab/tests/integration/issues.rs
+2021/05/22 | 125 | support/texlab/tests/integration/main.rs
+2021/05/22 | 2906 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_complete_entry.snap
+2021/05/22 | 2906 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_incomplete_entry.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__empty_document.snap
+2021/05/22 | 1080 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_complete.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name_before.snap
+2021/05/22 | 4165 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name.snap
+2021/05/22 | 2221 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_incomplete.snap
+2021/05/22 | 4190 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_complete_entry.snap
+2021/05/22 | 4190 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_incomplete_entry.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__junk.snap
+2021/05/22 | 9420 | support/texlab/tests/integration/snapshots/integration__completion__latex__begin_command.snap
+2021/05/22 | 152 | support/texlab/tests/integration/snapshots/integration__completion__latex__citation_after.snap
+2021/05/22 | 763 | support/texlab/tests/integration/snapshots/integration__completion__latex__citation_open_brace.snap
+2021/05/22 | 1210 | support/texlab/tests/integration/snapshots/integration__completion__latex__citation.snap
+2021/05/22 | 2897 | support/texlab/tests/integration/snapshots/integration__completion__latex__class_command.snap
+2021/05/22 | 540 | support/texlab/tests/integration/snapshots/integration__completion__latex__class_environment.snap
+2021/05/22 | 4948 | support/texlab/tests/integration/snapshots/integration__completion__latex__class_import.snap
+2021/05/22 | 1209 | support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color_set.snap
+2021/05/22 | 1917 | support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color.snap
+2021/05/22 | 2658 | support/texlab/tests/integration/snapshots/integration__completion__latex__color_name.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__latex__empty_document.snap
+2021/05/22 | 540 | support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_environment.snap
+2021/05/22 | 3400 | support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_glyph.snap
+2021/05/22 | 549 | support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command.snap
+2021/05/22 | 2903 | support/texlab/tests/integration/snapshots/integration__completion__latex__label.snap
+2021/05/22 | 2773 | support/texlab/tests/integration/snapshots/integration__completion__latex__package_command.snap
+2021/05/22 | 2873 | support/texlab/tests/integration/snapshots/integration__completion__latex__package_environment.snap
+2021/05/22 | 4053 | support/texlab/tests/integration/snapshots/integration__completion__latex__package_import.snap
+2021/05/22 | 2825 | support/texlab/tests/integration/snapshots/integration__completion__latex__pgf_library.snap
+2021/05/22 | 2863 | support/texlab/tests/integration/snapshots/integration__completion__latex__preselect_environment.snap
+2021/05/22 | 2478 | support/texlab/tests/integration/snapshots/integration__completion__latex__theorem_environment.snap
+2021/05/22 | 538 | support/texlab/tests/integration/snapshots/integration__completion__latex__user_command.snap
+2021/05/22 | 928 | support/texlab/tests/integration/snapshots/integration__completion__latex__user_environment.snap
+2021/05/22 | 1687 | support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_flat.snap
+2021/05/22 | 2657 | support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_nested.snap
+2021/05/22 | 1074 | support/texlab/tests/integration/snapshots/integration__document_symbol__equation_flat.snap
+2021/05/22 | 1405 | support/texlab/tests/integration/snapshots/integration__document_symbol__equation_nested.snap
+2021/05/22 | 1078 | support/texlab/tests/integration/snapshots/integration__document_symbol__float_flat.snap
+2021/05/22 | 1413 | support/texlab/tests/integration/snapshots/integration__document_symbol__float_nested.snap
+2021/05/22 | 1051 | support/texlab/tests/integration/snapshots/integration__document_symbol__section_flat.snap
+2021/05/22 | 1494 | support/texlab/tests/integration/snapshots/integration__document_symbol__section_nested.snap
+2021/05/22 | 1398 | support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_flat.snap
+2021/05/22 | 1854 | support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_nested.snap
+2021/05/22 | 88 | support/texlab/tests/integration/snapshots/integration__hover__empty_bibtex_document.snap
+2021/05/22 | 88 | support/texlab/tests/integration/snapshots/integration__hover__empty_labtex_document.snap
+2021/05/22 | 297 | support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file_mumber.snap
+2021/05/22 | 289 | support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file.snap
+2021/05/22 | 721 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_bibtex.snap
+2021/05/22 | 416 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_figure.snap
+2021/05/22 | 1035 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_item.snap
+2021/05/22 | 741 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_math.snap
+2021/05/22 | 1365 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_section.snap
+2021/05/22 | 3181 | support/texlab/tests/integration/workspace_symbol.rs
+2021/05/22 | 643 | support/texlab/texlab.1
+2021/05/22 | 84894 | support/texlab/texlab.pdf
+2021/05/22 | 7691144 | support/texlab.zip
2011/11/27 | 456 | support/texlipse/plugin/1.5.0/README.TXT
2011/11/27 | 1726937 | support/texlipse/plugin/1.5.0/texlipse_1.5.0 src.zip
1999/01/30 | 6077 | support/texlist/README
@@ -265022,9 +265295,9 @@
2019/02/28 | 91652 | systems/texlive/tlnet/archive/a5comb.doc.r17020.tar.xz
2019/02/28 | 968 | systems/texlive/tlnet/archive/a5comb.r17020.tar.xz
2019/10/22 | 5172 | systems/texlive/tlnet/archive/aaai-named.r52470.tar.xz
-2021/02/14 | 186892 | systems/texlive/tlnet/archive/aalok.doc.r57728.tar.xz
-2021/02/14 | 6312 | systems/texlive/tlnet/archive/aalok.r57728.tar.xz
-2021/02/14 | 18448 | systems/texlive/tlnet/archive/aalok.source.r57728.tar.xz
+2021/05/22 | 163720 | systems/texlive/tlnet/archive/aalok.doc.r59300.tar.xz
+2021/05/22 | 6288 | systems/texlive/tlnet/archive/aalok.r59300.tar.xz
+2021/05/22 | 18652 | systems/texlive/tlnet/archive/aalok.source.r59300.tar.xz
2021/03/03 | 1166168 | systems/texlive/tlnet/archive/aastex.doc.r58057.tar.xz
2021/03/03 | 50208 | systems/texlive/tlnet/archive/aastex.r58057.tar.xz
2019/02/28 | 852 | systems/texlive/tlnet/archive/abbr.doc.r15878.tar.xz
@@ -265076,9 +265349,9 @@
2021/01/21 | 860228 | systems/texlive/tlnet/archive/achemso.doc.r57479.tar.xz
2021/01/21 | 19268 | systems/texlive/tlnet/archive/achemso.r57479.tar.xz
2021/01/21 | 31504 | systems/texlive/tlnet/archive/achemso.source.r57479.tar.xz
-2021/04/18 | 3532112 | systems/texlive/tlnet/archive/acmart.doc.r58893.tar.xz
-2021/04/18 | 38456 | systems/texlive/tlnet/archive/acmart.r58893.tar.xz
-2021/04/18 | 53824 | systems/texlive/tlnet/archive/acmart.source.r58893.tar.xz
+2021/05/22 | 3535496 | systems/texlive/tlnet/archive/acmart.doc.r59294.tar.xz
+2021/05/22 | 38568 | systems/texlive/tlnet/archive/acmart.r59294.tar.xz
+2021/05/22 | 54416 | systems/texlive/tlnet/archive/acmart.source.r59294.tar.xz
2019/02/28 | 89944 | systems/texlive/tlnet/archive/acmconf.doc.r15878.tar.xz
2019/02/28 | 4192 | systems/texlive/tlnet/archive/acmconf.r15878.tar.xz
2019/02/28 | 18700 | systems/texlive/tlnet/archive/acmconf.source.r15878.tar.xz
@@ -269473,9 +269746,9 @@
2020/09/16 | 1610164 | systems/texlive/tlnet/archive/fonts-churchslavonic.r56350.tar.xz
2021/05/05 | 456368 | systems/texlive/tlnet/archive/fontsetup.doc.r59079.tar.xz
2021/05/05 | 6008 | systems/texlive/tlnet/archive/fontsetup.r59079.tar.xz
-2021/04/19 | 398936 | systems/texlive/tlnet/archive/fontsize.doc.r58906.tar.xz
-2021/04/19 | 4976 | systems/texlive/tlnet/archive/fontsize.r58906.tar.xz
-2021/04/19 | 14868 | systems/texlive/tlnet/archive/fontsize.source.r58906.tar.xz
+2021/05/22 | 372128 | systems/texlive/tlnet/archive/fontsize.doc.r59295.tar.xz
+2021/05/22 | 4980 | systems/texlive/tlnet/archive/fontsize.r59295.tar.xz
+2021/05/22 | 15108 | systems/texlive/tlnet/archive/fontsize.source.r59295.tar.xz
2020/10/08 | 1189088 | systems/texlive/tlnet/archive/fontspec.doc.r56594.tar.xz
2020/10/08 | 26788 | systems/texlive/tlnet/archive/fontspec.r56594.tar.xz
2020/10/08 | 83048 | systems/texlive/tlnet/archive/fontspec.source.r56594.tar.xz
@@ -271816,9 +272089,9 @@
2019/02/28 | 62752 | systems/texlive/tlnet/archive/lualatex-truncate.doc.r48469.tar.xz
2019/02/28 | 1932 | systems/texlive/tlnet/archive/lualatex-truncate.r48469.tar.xz
2019/02/28 | 5392 | systems/texlive/tlnet/archive/lualatex-truncate.source.r48469.tar.xz
-2021/01/01 | 87696 | systems/texlive/tlnet/archive/lualibs.doc.r57277.tar.xz
-2021/01/01 | 121836 | systems/texlive/tlnet/archive/lualibs.r57277.tar.xz
-2021/01/01 | 8572 | systems/texlive/tlnet/archive/lualibs.source.r57277.tar.xz
+2021/05/22 | 87876 | systems/texlive/tlnet/archive/lualibs.doc.r59298.tar.xz
+2021/05/22 | 121952 | systems/texlive/tlnet/archive/lualibs.r59298.tar.xz
+2021/05/22 | 8560 | systems/texlive/tlnet/archive/lualibs.source.r59298.tar.xz
2020/06/08 | 226344 | systems/texlive/tlnet/archive/luamesh.doc.r55475.tar.xz
2020/06/08 | 12096 | systems/texlive/tlnet/archive/luamesh.r55475.tar.xz
2021/03/12 | 152604 | systems/texlive/tlnet/archive/luamplib.doc.r58279.tar.xz
@@ -271828,14 +272101,14 @@
2019/02/28 | 352 | systems/texlive/tlnet/archive/luaotfload.amd64-freebsd.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.amd64-netbsd.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.armhf-linux.r34647.tar.xz
-2021/01/17 | 627576 | systems/texlive/tlnet/archive/luaotfload.doc.r57443.tar.xz
+2021/05/22 | 624416 | systems/texlive/tlnet/archive/luaotfload.doc.r59293.tar.xz
2019/02/28 | 344 | systems/texlive/tlnet/archive/luaotfload.i386-cygwin.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.i386-freebsd.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.i386-linux.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.i386-netbsd.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.i386-solaris.r34647.tar.xz
-2021/01/17 | 595852 | systems/texlive/tlnet/archive/luaotfload.r57443.tar.xz
-2021/01/17 | 7292 | systems/texlive/tlnet/archive/luaotfload.source.r57443.tar.xz
+2021/05/22 | 597604 | systems/texlive/tlnet/archive/luaotfload.r59293.tar.xz
+2021/05/22 | 7296 | systems/texlive/tlnet/archive/luaotfload.source.r59293.tar.xz
2021/02/25 | 348 | systems/texlive/tlnet/archive/luaotfload.universal-darwin.r57908.tar.xz
2019/02/28 | 692 | systems/texlive/tlnet/archive/luaotfload.win32.r34647.tar.xz
2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.x86_64-cygwin.r34647.tar.xz
@@ -271870,9 +272143,9 @@
2021/04/13 | 1857504 | systems/texlive/tlnet/archive/luatex.i386-linux.r58850.tar.xz
2021/04/14 | 1449908 | systems/texlive/tlnet/archive/luatex.i386-netbsd.r58866.tar.xz
2021/04/13 | 1615968 | systems/texlive/tlnet/archive/luatex.i386-solaris.r58850.tar.xz
-2021/05/18 | 3206268 | systems/texlive/tlnet/archive/luatexja.doc.r59248.tar.xz
-2021/05/18 | 189956 | systems/texlive/tlnet/archive/luatexja.r59248.tar.xz
-2021/05/18 | 83288 | systems/texlive/tlnet/archive/luatexja.source.r59248.tar.xz
+2021/05/22 | 3206200 | systems/texlive/tlnet/archive/luatexja.doc.r59299.tar.xz
+2021/05/22 | 190056 | systems/texlive/tlnet/archive/luatexja.r59299.tar.xz
+2021/05/22 | 83292 | systems/texlive/tlnet/archive/luatexja.source.r59299.tar.xz
2021/04/21 | 336848 | systems/texlive/tlnet/archive/luatexko.doc.r58928.tar.xz
2021/04/21 | 22400 | systems/texlive/tlnet/archive/luatexko.r58928.tar.xz
2021/04/12 | 12912 | systems/texlive/tlnet/archive/luatex.r58822.tar.xz
@@ -274078,9 +274351,9 @@
2019/02/28 | 2324 | systems/texlive/tlnet/archive/progressbar.r33822.tar.xz
2019/02/28 | 80808 | systems/texlive/tlnet/archive/progress.doc.r19519.tar.xz
2019/02/28 | 4192 | systems/texlive/tlnet/archive/progress.r19519.tar.xz
-2021/05/20 | 346208 | systems/texlive/tlnet/archive/projlib.doc.r59271.tar.xz
-2021/05/20 | 9248 | systems/texlive/tlnet/archive/projlib.r59271.tar.xz
-2021/05/20 | 9348 | systems/texlive/tlnet/archive/projlib.source.r59271.tar.xz
+2021/05/22 | 345608 | systems/texlive/tlnet/archive/projlib.doc.r59296.tar.xz
+2021/05/22 | 9384 | systems/texlive/tlnet/archive/projlib.r59296.tar.xz
+2021/05/22 | 9484 | systems/texlive/tlnet/archive/projlib.source.r59296.tar.xz
2019/05/23 | 372132 | systems/texlive/tlnet/archive/proof-at-the-end.doc.r51194.tar.xz
2019/05/23 | 4440 | systems/texlive/tlnet/archive/proof-at-the-end.r51194.tar.xz
2019/05/23 | 12500 | systems/texlive/tlnet/archive/proof-at-the-end.source.r51194.tar.xz
@@ -275260,9 +275533,9 @@
2019/02/28 | 250180 | systems/texlive/tlnet/archive/SIunits.doc.r15878.tar.xz
2019/02/28 | 6064 | systems/texlive/tlnet/archive/SIunits.r15878.tar.xz
2019/02/28 | 34544 | systems/texlive/tlnet/archive/SIunits.source.r15878.tar.xz
-2021/05/20 | 2362424 | systems/texlive/tlnet/archive/siunitx.doc.r59279.tar.xz
-2021/05/20 | 60252 | systems/texlive/tlnet/archive/siunitx.r59279.tar.xz
-2021/05/20 | 101336 | systems/texlive/tlnet/archive/siunitx.source.r59279.tar.xz
+2021/05/22 | 1958700 | systems/texlive/tlnet/archive/siunitx.doc.r59292.tar.xz
+2021/05/22 | 60464 | systems/texlive/tlnet/archive/siunitx.r59292.tar.xz
+2021/05/22 | 102144 | systems/texlive/tlnet/archive/siunitx.source.r59292.tar.xz
2019/02/28 | 200108 | systems/texlive/tlnet/archive/skak.doc.r46259.tar.xz
2019/02/28 | 316212 | systems/texlive/tlnet/archive/skaknew.doc.r20031.tar.xz
2019/02/28 | 160064 | systems/texlive/tlnet/archive/skaknew.r20031.tar.xz
@@ -276121,7 +276394,7 @@
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.amd64-freebsd.r55172.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.amd64-netbsd.r55172.tar.xz
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.armhf-linux.r55172.tar.xz
-2021/05/20 | 397364 | systems/texlive/tlnet/archive/texlive-scripts.doc.r59286.tar.xz
+2021/05/22 | 397364 | systems/texlive/tlnet/archive/texlive-scripts.doc.r59290.tar.xz
2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.aarch64-linux.r53577.tar.xz
2020/01/27 | 924 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-freebsd.r53577.tar.xz
2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-netbsd.r53577.tar.xz
@@ -276145,7 +276418,7 @@
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-linux.r55172.tar.xz
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.i386-netbsd.r55172.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-solaris.r55172.tar.xz
-2021/05/20 | 108004 | systems/texlive/tlnet/archive/texlive-scripts.r59286.tar.xz
+2021/05/22 | 107996 | systems/texlive/tlnet/archive/texlive-scripts.r59290.tar.xz
2021/02/25 | 572 | systems/texlive/tlnet/archive/texlive-scripts.universal-darwin.r57908.tar.xz
2021/04/12 | 36308 | systems/texlive/tlnet/archive/texlive-scripts.win32.r58829.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.x86_64-cygwin.r55172.tar.xz
@@ -276561,8 +276834,8 @@
2021/04/28 | 10100 | systems/texlive/tlnet/archive/tipauni.source.r59009.tar.xz
2019/02/28 | 381176 | systems/texlive/tlnet/archive/tipfr.doc.r38646.tar.xz
2019/02/28 | 5880 | systems/texlive/tlnet/archive/tipfr.r38646.tar.xz
-2021/05/18 | 123964 | systems/texlive/tlnet/archive/tiscreen.doc.r59247.tar.xz
-2021/05/18 | 912 | systems/texlive/tlnet/archive/tiscreen.r59247.tar.xz
+2021/05/22 | 123776 | systems/texlive/tlnet/archive/tiscreen.doc.r59297.tar.xz
+2021/05/22 | 1072 | systems/texlive/tlnet/archive/tiscreen.r59297.tar.xz
2019/02/28 | 261184 | systems/texlive/tlnet/archive/titlecaps.doc.r36170.tar.xz
2019/02/28 | 4148 | systems/texlive/tlnet/archive/titlecaps.r36170.tar.xz
2019/02/28 | 2928 | systems/texlive/tlnet/archive/titlefoot.r15878.tar.xz
@@ -277847,16 +278120,16 @@
2020/07/18 | 47816 | systems/texlive/tlnet/archive/zztex.doc.r55862.tar.xz
2020/07/18 | 101724 | systems/texlive/tlnet/archive/zztex.r55862.tar.xz
2021/05/02 | 105152 | systems/texlive/tlnet/install-tl
-2021/05/21 | 6812825 | systems/texlive/tlnet/install-tl-unx.tar.gz
-2021/05/21 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2021/05/21 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2021/05/22 | 6812477 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/05/22 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2021/05/22 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2021/04/11 | 4945 | systems/texlive/tlnet/install-tl-windows.bat
-2021/05/21 | 20810464 | systems/texlive/tlnet/install-tl-windows.exe
-2021/05/21 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2021/05/21 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2021/05/21 | 25584691 | systems/texlive/tlnet/install-tl.zip
-2021/05/21 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
-2021/05/21 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2021/05/22 | 20808632 | systems/texlive/tlnet/install-tl-windows.exe
+2021/05/22 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2021/05/22 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2021/05/22 | 25584700 | systems/texlive/tlnet/install-tl.zip
+2021/05/22 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2021/05/22 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
2021/04/01 | 1229 | systems/texlive/tlnet/README.md
2021/04/01 | 0 | systems/texlive/tlnet/TEXLIVE_2021
2021/03/15 | 6571 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg
@@ -277866,7 +278139,7 @@
2021/03/15 | 1280 | systems/texlive/tlnet/tlpkg/gpg/trustdb.gpg
2021/05/07 | 49598 | systems/texlive/tlnet/tlpkg/installer/config.guess
2010/11/11 | 11651 | systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt
-2021/05/20 | 6946 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
+2021/05/21 | 6901 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2020/04/15 | 223687 | systems/texlive/tlnet/tlpkg/installer/curl/curl-ca-bundle.crt
2020/04/15 | 2606592 | systems/texlive/tlnet/tlpkg/installer/curl/curl.exe
2017/04/16 | 2629 | systems/texlive/tlnet/tlpkg/installer/installer-options.txt
@@ -277908,12 +278181,12 @@
2021/05/16 | 20371 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm
2021/05/16 | 5402 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm
2021/05/16 | 27555 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm
-2021/05/21 | 17243572 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2021/05/21 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2021/05/22 | 17243428 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2021/05/22 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
2021/05/16 | 86511 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm
-2021/05/21 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2021/05/21 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2021/05/21 | 2308404 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/05/22 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2021/05/22 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2021/05/22 | 2307008 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
2021/05/16 | 58801 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm
2021/05/16 | 42084 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm
2021/05/16 | 16103 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm
@@ -282602,7 +282875,7 @@
2020/10/03 | 318630 | systems/win32/miktex/tm/packages/filehook.tar.lzma
2012/12/04 | 924573 | systems/win32/miktex/tm/packages/fileinfo.tar.lzma
2011/09/21 | 281409 | systems/win32/miktex/tm/packages/filemod.tar.lzma
-2021/05/21 | 576615 | systems/win32/miktex/tm/packages/files.csv.lzma
+2021/05/22 | 576615 | systems/win32/miktex/tm/packages/files.csv.lzma
2001/05/14 | 5617 | systems/win32/miktex/tm/packages/finbib.tar.lzma
2015/10/20 | 44379 | systems/win32/miktex/tm/packages/findhyph.tar.lzma
2011/10/21 | 89323 | systems/win32/miktex/tm/packages/fink.tar.lzma
@@ -283803,9 +284076,9 @@
2018/01/12 | 157226 | systems/win32/miktex/tm/packages/miktex-zip-bin-x64.tar.lzma
2021/03/15 | 39247 | systems/win32/miktex/tm/packages/miktex-zlib-bin-2.9.tar.lzma
2021/03/15 | 43386 | systems/win32/miktex/tm/packages/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/05/21 | 209603 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2021/05/21 | 1272452 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2021/05/21 | 1187128 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2021/05/22 | 209667 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2021/05/22 | 1272534 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2021/05/22 | 1188645 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
2021/03/15 | 13447 | systems/win32/miktex/tm/packages/miktex-zzip-bin-2.9.tar.lzma
2021/03/15 | 14320 | systems/win32/miktex/tm/packages/miktex-zzip-bin-x64-2.9.tar.lzma
2016/07/15 | 35914 | systems/win32/miktex/tm/packages/mil3.tar.lzma
@@ -283966,190 +284239,190 @@
2018/04/09 | 400132 | systems/win32/miktex/tm/packages/newunicodechar.tar.lzma
2011/09/19 | 101312 | systems/win32/miktex/tm/packages/newvbtm.tar.lzma
2021/03/17 | 232249 | systems/win32/miktex/tm/packages/newverbs.tar.lzma
-2021/05/21 | 576226 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2021/05/21 | 50847 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
-2021/05/21 | 56457 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/05/21 | 968696 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
-2021/05/21 | 1078878 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
-2021/05/21 | 29055 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
-2021/05/21 | 31343 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2021/05/21 | 29868 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
-2021/05/21 | 34634 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2021/05/21 | 49971 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
-2021/05/21 | 57599 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2021/05/21 | 84774 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
-2021/05/21 | 94735 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
-2021/05/21 | 67679 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
-2021/05/21 | 75417 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
-2021/05/21 | 27183 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
-2021/05/21 | 30884 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
-2021/05/21 | 330233 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
-2021/05/21 | 392597 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
-2021/05/21 | 32745 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
-2021/05/21 | 36679 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
-2021/05/21 | 51432 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
-2021/05/21 | 56719 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/05/21 | 4707 | systems/win32/miktex/tm/packages/next/miktex-config-2.9.tar.lzma
-2021/05/21 | 239478 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
-2021/05/21 | 261962 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2021/05/21 | 179379 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
-2021/05/21 | 195664 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
-2021/05/21 | 52475 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
-2021/05/21 | 59144 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
-2021/05/21 | 21128 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
-2021/05/21 | 23291 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2021/05/21 | 461399 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2021/05/21 | 45649 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
-2021/05/21 | 51159 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/05/21 | 282107 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
-2021/05/21 | 321895 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
-2021/05/21 | 41103 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
-2021/05/21 | 45278 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
-2021/05/21 | 116930 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
-2021/05/21 | 131489 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/05/21 | 1281102 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
-2021/05/21 | 1425981 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2021/05/21 | 87638 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
-2021/05/21 | 99604 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2021/05/21 | 43057 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
-2021/05/21 | 47877 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
-2021/05/21 | 25156 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
-2021/05/21 | 28009 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2021/05/21 | 55822 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
-2021/05/21 | 62801 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/05/21 | 135006 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
-2021/05/21 | 152762 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2021/05/21 | 73181 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
-2021/05/21 | 77857 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
-2021/05/21 | 71568 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
-2021/05/21 | 80661 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
-2021/05/21 | 258663 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
-2021/05/21 | 295555 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
-2021/05/21 | 22040 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
-2021/05/21 | 25002 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/05/21 | 97490 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
-2021/05/21 | 112250 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
-2021/05/21 | 63836 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
-2021/05/21 | 72859 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
-2021/05/21 | 96145 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
-2021/05/21 | 115470 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/05/21 | 38069 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
-2021/05/21 | 42626 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/05/21 | 484055 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
-2021/05/21 | 567627 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/05/21 | 147140 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
-2021/05/21 | 159969 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
-2021/05/21 | 94802 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
-2021/05/21 | 109274 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/05/21 | 16327 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
-2021/05/21 | 17957 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2021/05/21 | 28119 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
-2021/05/21 | 30038 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
-2021/05/21 | 625283 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
-2021/05/21 | 680048 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/05/21 | 532038 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
-2021/05/21 | 594869 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
-2021/05/21 | 475936 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
-2021/05/21 | 511634 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/05/21 | 94269 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
-2021/05/21 | 103322 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
-2021/05/21 | 1725549 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
-2021/05/21 | 2009491 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
-2021/05/21 | 67650 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
-2021/05/21 | 74163 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2021/05/21 | 27362 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
-2021/05/21 | 31593 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
-2021/05/21 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
-2021/05/21 | 8774 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
-2021/05/21 | 195566 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
-2021/05/21 | 214104 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
-2021/05/21 | 250213 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
-2021/05/21 | 283977 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
-2021/05/21 | 97135 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
-2021/05/21 | 101763 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
-2021/05/21 | 60551 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
-2021/05/21 | 67929 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/05/21 | 124973 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
-2021/05/21 | 136427 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
-2021/05/21 | 147151 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
-2021/05/21 | 163656 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2021/05/21 | 199701 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
-2021/05/21 | 180048 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/05/21 | 67450 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
-2021/05/21 | 77487 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2021/05/21 | 31191 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
-2021/05/21 | 35064 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2021/05/21 | 38066 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
-2021/05/21 | 42573 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/05/21 | 42923 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
-2021/05/21 | 47007 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
-2021/05/21 | 45937 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
-2021/05/21 | 52454 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
-2021/05/21 | 193717 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
-2021/05/21 | 211055 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
-2021/05/21 | 35463 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
-2021/05/21 | 39690 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
-2021/05/21 | 748362 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
-2021/05/21 | 816071 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
-2021/05/21 | 198131 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
-2021/05/21 | 202558 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
-2021/05/21 | 208180 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
-2021/05/21 | 243478 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
-2021/05/21 | 78746 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
-2021/05/21 | 87704 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2021/05/21 | 1171731 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
-2021/05/21 | 1307723 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/05/21 | 20120 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
-2021/05/21 | 23881 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
-2021/05/21 | 31543 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
-2021/05/21 | 37242 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
-2021/05/21 | 64017 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
-2021/05/21 | 72150 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/05/21 | 43677 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
-2021/05/21 | 51979 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/05/21 | 1295415 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
-2021/05/21 | 1424811 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
-2021/05/21 | 42388 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
-2021/05/21 | 51798 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/05/21 | 56223 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
-2021/05/21 | 59831 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
-2021/05/21 | 25342 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
-2021/05/21 | 27274 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/05/21 | 16113 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
-2021/05/21 | 18096 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2021/05/21 | 63674 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
-2021/05/21 | 70109 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
-2021/05/21 | 153890 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
-2021/05/21 | 167908 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
-2021/05/21 | 56909 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
-2021/05/21 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
-2021/05/21 | 98518 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
-2021/05/21 | 104625 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
-2021/05/21 | 2499401 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
-2021/05/21 | 2616931 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
-2021/05/21 | 55219 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
-2021/05/21 | 62226 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2021/05/21 | 33441 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
-2021/05/21 | 37293 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2021/05/21 | 27197 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
-2021/05/21 | 33151 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
-2021/05/21 | 65733 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
-2021/05/21 | 70325 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2021/05/21 | 311191 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
-2021/05/21 | 345367 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
-2021/05/21 | 55563 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
-2021/05/21 | 57066 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
-2021/05/21 | 583627 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
-2021/05/21 | 618763 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2021/05/21 | 39563 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
-2021/05/21 | 43390 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/05/21 | 209568 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2021/05/21 | 1271700 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
-2021/05/21 | 1187934 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2021/05/21 | 13470 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
-2021/05/21 | 14353 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2021/05/22 | 576226 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2021/05/22 | 50847 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
+2021/05/22 | 56457 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2021/05/22 | 968700 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/05/22 | 1078878 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2021/05/22 | 29050 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
+2021/05/22 | 31343 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2021/05/22 | 29867 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
+2021/05/22 | 34635 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2021/05/22 | 49972 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
+2021/05/22 | 57598 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2021/05/22 | 84774 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
+2021/05/22 | 94738 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2021/05/22 | 67679 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
+2021/05/22 | 75419 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2021/05/22 | 27182 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
+2021/05/22 | 30886 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2021/05/22 | 330235 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
+2021/05/22 | 392596 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2021/05/22 | 32744 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
+2021/05/22 | 36679 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2021/05/22 | 51432 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
+2021/05/22 | 56717 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2021/05/22 | 4707 | systems/win32/miktex/tm/packages/next/miktex-config-2.9.tar.lzma
+2021/05/22 | 239479 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/05/22 | 261961 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2021/05/22 | 179379 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
+2021/05/22 | 195664 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2021/05/22 | 52476 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
+2021/05/22 | 59145 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/05/22 | 21132 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
+2021/05/22 | 23292 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2021/05/22 | 461400 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2021/05/22 | 45649 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
+2021/05/22 | 51160 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2021/05/22 | 282108 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
+2021/05/22 | 321894 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2021/05/22 | 41102 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
+2021/05/22 | 45278 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/05/22 | 116930 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
+2021/05/22 | 131490 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2021/05/22 | 1281106 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
+2021/05/22 | 1425981 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2021/05/22 | 87638 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/05/22 | 99605 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/05/22 | 43059 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
+2021/05/22 | 47879 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/05/22 | 25155 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
+2021/05/22 | 28009 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/05/22 | 55823 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
+2021/05/22 | 62801 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2021/05/22 | 135005 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
+2021/05/22 | 152762 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2021/05/22 | 73181 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
+2021/05/22 | 77859 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2021/05/22 | 71570 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
+2021/05/22 | 80661 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/05/22 | 258666 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
+2021/05/22 | 295554 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2021/05/22 | 22040 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
+2021/05/22 | 25001 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2021/05/22 | 97491 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
+2021/05/22 | 112253 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2021/05/22 | 63836 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
+2021/05/22 | 72861 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2021/05/22 | 96148 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
+2021/05/22 | 115470 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2021/05/22 | 38069 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
+2021/05/22 | 42627 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2021/05/22 | 484055 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
+2021/05/22 | 567627 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2021/05/22 | 147139 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
+2021/05/22 | 159969 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2021/05/22 | 94803 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
+2021/05/22 | 109273 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2021/05/22 | 16328 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
+2021/05/22 | 17958 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2021/05/22 | 28121 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
+2021/05/22 | 30038 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2021/05/22 | 625284 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
+2021/05/22 | 680049 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2021/05/22 | 532039 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
+2021/05/22 | 594869 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2021/05/22 | 475936 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
+2021/05/22 | 511634 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2021/05/22 | 94266 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
+2021/05/22 | 103323 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/05/22 | 1725546 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
+2021/05/22 | 2009493 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2021/05/22 | 67649 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
+2021/05/22 | 74164 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2021/05/22 | 27362 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
+2021/05/22 | 31594 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2021/05/22 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
+2021/05/22 | 8774 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2021/05/22 | 195567 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/05/22 | 214105 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/05/22 | 250214 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
+2021/05/22 | 283978 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2021/05/22 | 97135 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
+2021/05/22 | 101764 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2021/05/22 | 60553 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
+2021/05/22 | 67931 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
+2021/05/22 | 124972 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
+2021/05/22 | 136429 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2021/05/22 | 147150 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
+2021/05/22 | 163656 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2021/05/22 | 199700 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
+2021/05/22 | 180048 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2021/05/22 | 67452 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
+2021/05/22 | 77487 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/05/22 | 31192 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
+2021/05/22 | 35064 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2021/05/22 | 38066 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
+2021/05/22 | 42574 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2021/05/22 | 42925 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
+2021/05/22 | 47009 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2021/05/22 | 45937 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
+2021/05/22 | 52454 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/05/22 | 193716 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
+2021/05/22 | 211056 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2021/05/22 | 35462 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
+2021/05/22 | 39689 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2021/05/22 | 748364 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
+2021/05/22 | 816072 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2021/05/22 | 198131 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
+2021/05/22 | 202558 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2021/05/22 | 208182 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
+2021/05/22 | 243479 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2021/05/22 | 78747 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
+2021/05/22 | 87704 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2021/05/22 | 1171731 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
+2021/05/22 | 1307725 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2021/05/22 | 20121 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
+2021/05/22 | 23881 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2021/05/22 | 31544 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
+2021/05/22 | 37242 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2021/05/22 | 64017 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
+2021/05/22 | 72151 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2021/05/22 | 43678 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
+2021/05/22 | 51980 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2021/05/22 | 1295415 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
+2021/05/22 | 1424814 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2021/05/22 | 42388 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
+2021/05/22 | 51797 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2021/05/22 | 56223 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
+2021/05/22 | 59832 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2021/05/22 | 25341 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
+2021/05/22 | 27275 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2021/05/22 | 16115 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
+2021/05/22 | 18097 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2021/05/22 | 63675 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/05/22 | 70110 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2021/05/22 | 153890 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
+2021/05/22 | 167907 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/05/22 | 56910 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
+2021/05/22 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2021/05/22 | 98518 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
+2021/05/22 | 104624 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2021/05/22 | 2499401 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
+2021/05/22 | 2616929 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2021/05/22 | 55219 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
+2021/05/22 | 62226 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2021/05/22 | 33442 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/05/22 | 37293 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2021/05/22 | 27197 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
+2021/05/22 | 33153 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2021/05/22 | 65730 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
+2021/05/22 | 70326 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2021/05/22 | 311192 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
+2021/05/22 | 345367 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2021/05/22 | 55564 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
+2021/05/22 | 57066 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
+2021/05/22 | 583627 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
+2021/05/22 | 618766 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2021/05/22 | 39565 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
+2021/05/22 | 43392 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2021/05/22 | 209550 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2021/05/22 | 1271317 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/05/22 | 1187112 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2021/05/22 | 13469 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/05/22 | 14355 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
2019/03/12 | 1412 | systems/win32/miktex/tm/packages/nextpage.tar.lzma
-2021/05/21 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
+2021/05/22 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
2018/07/06 | 145915 | systems/win32/miktex/tm/packages/nexus-otf.tar.lzma
2017/03/30 | 191149 | systems/win32/miktex/tm/packages/nfssext-cfr.tar.lzma
2012/12/20 | 612251 | systems/win32/miktex/tm/packages/nicefilelist.tar.lzma
@@ -284485,7 +284758,7 @@
2020/10/20 | 342254 | systems/win32/miktex/tm/packages/preview.tar.lzma
2019/06/20 | 375963 | systems/win32/miktex/tm/packages/prftree.tar.lzma
2021/04/23 | 274028 | systems/win32/miktex/tm/packages/principia.tar.lzma
-2021/05/21 | 839 | systems/win32/miktex/tm/packages/pr.ini
+2021/05/22 | 839 | systems/win32/miktex/tm/packages/pr.ini
2010/09/27 | 248469 | systems/win32/miktex/tm/packages/printlen.tar.lzma
2008/06/17 | 77313 | systems/win32/miktex/tm/packages/proba.tar.lzma
2017/07/12 | 988486 | systems/win32/miktex/tm/packages/probsoln.tar.lzma
@@ -285896,7 +286169,7 @@
2004/06/04 | 404 | tds/tds.sed
2004/06/23 | 65418 | tds/tds.tex
2019/05/29 | 304264 | tds.zip
-2021/05/22 | 186 | timestamp
+2021/05/23 | 186 | timestamp
2002/08/26 | 61898 | usergrps/dante/antrag.pdf
2002/08/26 | 118217 | usergrps/dante/antrag.ps
2017/06/30 | 917 | usergrps/dante/dtk/doc/beispiel.bib
diff --git a/FILES.byname.gz b/FILES.byname.gz
index 20c6a185ce..b5075baa2d 100644
--- a/FILES.byname.gz
+++ b/FILES.byname.gz
Binary files differ
diff --git a/FILES.last07days b/FILES.last07days
index a024aa3293..32d8eac420 100644
--- a/FILES.last07days
+++ b/FILES.last07days
@@ -1,31 +1,676 @@
-2021/05/21 | 99604 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/05/22 | 99605 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/05/22 | 989 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap
+2021/05/22 | 98518 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
+2021/05/22 | 97491 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
+2021/05/22 | 97135 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
+2021/05/22 | 968700 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/05/22 | 96148 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
+2021/05/22 | 9484 | systems/texlive/tlnet/archive/projlib.source.r59296.tar.xz
+2021/05/22 | 94803 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
+2021/05/22 | 94738 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2021/05/22 | 94266 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
+2021/05/22 | 9420 | support/texlab/tests/integration/snapshots/integration__completion__latex__begin_command.snap
+2021/05/22 | 9399 | support/texlab/src/features.rs
+2021/05/22 | 9384 | systems/texlive/tlnet/archive/projlib.r59296.tar.xz
+2021/05/22 | 928 | support/texlab/tests/integration/snapshots/integration__completion__latex__user_environment.snap
+2021/05/22 | 923 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap
+2021/05/22 | 923 | support/texlab/src/language.rs
+2021/05/22 | 901 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__delimiters.snap
+2021/05/22 | 88 | support/texlab/tests/integration/snapshots/integration__hover__empty_labtex_document.snap
+2021/05/22 | 88 | support/texlab/tests/integration/snapshots/integration__hover__empty_bibtex_document.snap
+2021/05/22 | 883 | support/texlab/src/context.rs
+2021/05/22 | 87876 | systems/texlive/tlnet/archive/lualibs.doc.r59298.tar.xz
+2021/05/22 | 8774 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2021/05/22 | 87704 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2021/05/22 | 87638 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/05/22 | 869 | support/texlab/src/workspace.rs
+2021/05/22 | 8660 | support/texlab/src/label.rs
+2021/05/22 | 85 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__empty.snap
+2021/05/22 | 8560 | systems/texlive/tlnet/archive/lualibs.source.r59298.tar.xz
+2021/05/22 | 854 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap
+2021/05/22 | 84894 | support/texlab/texlab.pdf
+2021/05/22 | 84774 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
+2021/05/22 | 846 | support/texlab/src/syntax/bibtex/kind.rs
+2021/05/22 | 841 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap
+2021/05/22 | 8414 | support/texlab/src/citation/name.rs
+2021/05/22 | 8409 | macros/latex/contrib/bmstu-iu8/styles/10-IU8-titlepage.sty
+2021/05/22 | 839 | systems/win32/miktex/tm/packages/pr.ini
+2021/05/22 | 8397576 | fonts/newtx.zip
+2021/05/22 | 833 | support/texlab/src/syntax/latex.rs
+2021/05/22 | 83292 | systems/texlive/tlnet/archive/luatexja.source.r59299.tar.xz
+2021/05/22 | 822 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap
+2021/05/22 | 821 | support/texlab/src/features/reference.rs
+2021/05/22 | 816072 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2021/05/22 | 808489 | fonts/newpx/doc/newpxdoc.pdf
+2021/05/22 | 80661 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/05/22 | 802 | support/texlab/src/syntax/bibtex.rs
+2021/05/22 | 797 | macros/latex/contrib/bmstu-iu8/styles/17-IU8-appendices.sty
+2021/05/22 | 795 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap
+2021/05/22 | 78747 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
+2021/05/22 | 781 | macros/latex/contrib/bmstu-iu8/styles/18-IU8-extra.sty
+2021/05/22 | 77859 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2021/05/22 | 77487 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/05/22 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
+2021/05/22 | 76 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__empty.snap
+2021/05/22 | 769 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap
+2021/05/22 | 7691144 | support/texlab.zip
+2021/05/22 | 765 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap
+2021/05/22 | 764 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap
+2021/05/22 | 763 | support/texlab/tests/integration/snapshots/integration__completion__latex__citation_open_brace.snap
+2021/05/22 | 75419 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2021/05/22 | 750 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap
+2021/05/22 | 748364 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
+2021/05/22 | 745 | support/texlab/src/features/formatting.rs
+2021/05/22 | 745 | support/texlab/docs/tectonic.md
+2021/05/22 | 741 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_math.snap
+2021/05/22 | 74164 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2021/05/22 | 740 | macros/latex/contrib/bmstu-iu8/styles/15-IU8-list-of-abbreviations.sty
+2021/05/22 | 73181 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
+2021/05/22 | 7296 | systems/texlive/tlnet/archive/luaotfload.source.r59293.tar.xz
+2021/05/22 | 72861 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2021/05/22 | 727 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap
+2021/05/22 | 7230 | support/texlab/src/features/cursor.rs
+2021/05/22 | 721 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_bibtex.snap
+2021/05/22 | 721 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap
+2021/05/22 | 72151 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2021/05/22 | 7200 | support/texlab/src/features/completion/citation.rs
+2021/05/22 | 71570 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
+2021/05/22 | 7067 | support/texlab/src/features/folding.rs
+2021/05/22 | 70326 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2021/05/22 | 70110 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2021/05/22 | 6 | support/texlab/rust-toolchain
+2021/05/22 | 6955 | support/texlab/src/features/completion/entry_type.rs
+2021/05/22 | 6927 | support/texlab/src/syntax/latex/lexer.rs
+2021/05/22 | 688 | support/texlab/src/lib.rs
+2021/05/22 | 6888 | support/texlab/src/features/symbol/project_order.rs
+2021/05/22 | 6850 | support/texlab/src/features/completion/label.rs
+2021/05/22 | 6832 | support/texlab/src/features/reference/entry.rs
+2021/05/22 | 682 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap
+2021/05/22 | 6812477 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/05/22 | 680049 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2021/05/22 | 67931 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
+2021/05/22 | 677 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_siblings.snap
+2021/05/22 | 67679 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
+2021/05/22 | 67649 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
+2021/05/22 | 675 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap
+2021/05/22 | 67452 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
+2021/05/22 | 671 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap
+2021/05/22 | 668 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap
+2021/05/22 | 668 | macros/latex/contrib/bmstu-iu8/styles/19-IU8-counters.sty
+2021/05/22 | 66300 | fonts/kpfonts-otf/fonts/KpMono-Italic.otf
+2021/05/22 | 6618 | support/texlab/src/features/reference/string.rs
+2021/05/22 | 65730 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
+2021/05/22 | 65697 | support/texlab/Cargo.lock
+2021/05/22 | 655 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap
+2021/05/22 | 654 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap
+2021/05/22 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2021/05/22 | 64992 | fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf
+2021/05/22 | 6484 | support/texlab/src/line_index.rs
+2021/05/22 | 647 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap
+2021/05/22 | 643 | support/texlab/texlab.1
+2021/05/22 | 640 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap
+2021/05/22 | 64017 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
+2021/05/22 | 63836 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
+2021/05/22 | 637 | support/texlab/src/syntax/latex/analysis/label_number.rs
+2021/05/22 | 63675 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/05/22 | 632 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap
+2021/05/22 | 630 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline_double_dollar.snap
+2021/05/22 | 6288 | systems/texlive/tlnet/archive/aalok.r59300.tar.xz
+2021/05/22 | 62801 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2021/05/22 | 625284 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
+2021/05/22 | 624 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline.snap
+2021/05/22 | 624416 | systems/texlive/tlnet/archive/luaotfload.doc.r59293.tar.xz
+2021/05/22 | 623 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption.snap
+2021/05/22 | 6222 | macros/latex/contrib/bmstu-iu8/styles/06-IU8-tables.sty
+2021/05/22 | 62226 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2021/05/22 | 621 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_error.snap
+2021/05/22 | 6188 | support/texlab/src/features/reference/label.rs
+2021/05/22 | 618766 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2021/05/22 | 614 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__formula.snap
+2021/05/22 | 6092 | support/texlab/docs/previewing.md
+2021/05/22 | 60553 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
+2021/05/22 | 60464 | systems/texlive/tlnet/archive/siunitx.r59292.tar.xz
+2021/05/22 | 59832 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2021/05/22 | 597604 | systems/texlive/tlnet/archive/luaotfload.r59293.tar.xz
+2021/05/22 | 595 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap
+2021/05/22 | 594869 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2021/05/22 | 5917 | support/texlab/src/features/completion/import.rs
+2021/05/22 | 59145 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/05/22 | 5895 | support/texlab/src/features/completion/field.rs
+2021/05/22 | 58904 | fonts/kpfonts-otf/fonts/KpMono-Regular.otf
+2021/05/22 | 586 | support/texlab/src/syntax/latex/analysis/theorem.rs
+2021/05/22 | 5847 | support/texlab/src/syntax/bibtex/cst.rs
+2021/05/22 | 583627 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
+2021/05/22 | 57768 | fonts/kpfonts-otf/fonts/KpMono-Bold.otf
+2021/05/22 | 576615 | systems/win32/miktex/tm/packages/files.csv.lzma
+2021/05/22 | 576226 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2021/05/22 | 575 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_parameter.snap
+2021/05/22 | 57598 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2021/05/22 | 57066 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
+2021/05/22 | 57018 | support/texlab/data/lang_data.json
+2021/05/22 | 56910 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
+2021/05/22 | 567627 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2021/05/22 | 56717 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2021/05/22 | 565 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__multiple_entries.snap
+2021/05/22 | 5650 | support/texlab/src/features/completion/argument.rs
+2021/05/22 | 56457 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2021/05/22 | 5640 | support/texlab/src/features/completion/color_model.rs
+2021/05/22 | 56296 | support/texlab/src/citation/apa.csl
+2021/05/22 | 56223 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
+2021/05/22 | 559 | support/texlab/src/features/semantic.rs
+2021/05/22 | 55823 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
+2021/05/22 | 556 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap
+2021/05/22 | 55564 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
+2021/05/22 | 55219 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
+2021/05/22 | 549 | support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command.snap
+2021/05/22 | 5485 | support/texlab/src/features/completion/include.rs
+2021/05/22 | 546 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap
+2021/05/22 | 5460 | support/texlab/src/features/rename/entry.rs
+2021/05/22 | 54416 | systems/texlive/tlnet/archive/acmart.source.r59294.tar.xz
+2021/05/22 | 540 | support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_environment.snap
+2021/05/22 | 540 | support/texlab/tests/integration/snapshots/integration__completion__latex__class_environment.snap
+2021/05/22 | 538 | support/texlab/tests/integration/snapshots/integration__completion__latex__user_command.snap
+2021/05/22 | 537 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap
+2021/05/22 | 537 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap
+2021/05/22 | 5361 | support/texlab/src/features/completion/component_command.rs
+2021/05/22 | 53203 | macros/latex/contrib/bmstu-iu8/inc/bmstu.png
+2021/05/22 | 532039 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
+2021/05/22 | 5296 | support/texlab/src/features/definition/string.rs
+2021/05/22 | 5289 | fonts/kpfonts-otf/README.md
+2021/05/22 | 52476 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
+2021/05/22 | 52454 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/05/22 | 521 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_invalid_nesting.snap
+2021/05/22 | 5204 | support/texlab/src/features/completion/acronym_ref.rs
+2021/05/22 | 519 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_complete.snap
+2021/05/22 | 519 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_casing.snap
+2021/05/22 | 51980 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2021/05/22 | 5190 | support/texlab/src/features/completion/component_environment.rs
+2021/05/22 | 517 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_missing_quote.snap
+2021/05/22 | 517 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_incomplete.snap
+2021/05/22 | 51797 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2021/05/22 | 51432 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
+2021/05/22 | 51420 | support/texlab/src/syntax/build_log.rs
+2021/05/22 | 5131 | support/texlab/src/features/highlight/label.rs
+2021/05/22 | 511634 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2021/05/22 | 51160 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2021/05/22 | 50847 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
+2021/05/22 | 5051 | support/texlab/src/features/completion/tikz_library.rs
+2021/05/22 | 49972 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
+2021/05/22 | 4994 | support/texlab/src/capabilities.rs
+2021/05/22 | 4980 | systems/texlive/tlnet/archive/fontsize.r59295.tar.xz
+2021/05/22 | 4948 | support/texlab/tests/integration/snapshots/integration__completion__latex__class_import.snap
+2021/05/22 | 491 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal.snap
+2021/05/22 | 4912 | support/texlab/src/features/rename/label.rs
+2021/05/22 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2021/05/22 | 489 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal_error.snap
+2021/05/22 | 488 | support/texlab/src/range.rs
+2021/05/22 | 484055 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
+2021/05/22 | 480 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_complete.snap
+2021/05/22 | 480 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_casing.snap
+2021/05/22 | 47879 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/05/22 | 475936 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
+2021/05/22 | 472 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_simple.snap
+2021/05/22 | 4729 | support/texlab/src/citation/bibutils.rs
+2021/05/22 | 4707 | systems/win32/miktex/tm/packages/next/miktex-config-2.9.tar.lzma
+2021/05/22 | 47009 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2021/05/22 | 464 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_argc.snap
+2021/05/22 | 461400 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2021/05/22 | 45937 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
+2021/05/22 | 4587 | support/texlab/src/citation.rs
+2021/05/22 | 45753 | support/texlab/src/syntax/latex/parser.rs
+2021/05/22 | 45649 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
+2021/05/22 | 4561 | support/texlab/src/diagnostics/bibtex.rs
+2021/05/22 | 456084 | fonts/kpfonts-otf/fonts/KpMath-Light.otf
+2021/05/22 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2021/05/22 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2021/05/22 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2021/05/22 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2021/05/22 | 455 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap
+2021/05/22 | 4533 | support/texlab/README.md
+2021/05/22 | 45278 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/05/22 | 4496 | support/texlab/src/features/completion/glossary_ref.rs
+2021/05/22 | 448 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap
+2021/05/22 | 4482 | support/texlab/src/features/completion/theorem.rs
+2021/05/22 | 447 | info/tlmgrbasics/README
+2021/05/22 | 446 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_missing_end.snap
+2021/05/22 | 441 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap
+2021/05/22 | 4380 | support/texlab/src/syntax/latex/kind.rs
+2021/05/22 | 43678 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
+2021/05/22 | 434 | fonts/kpfonts-otf/tex/KpLight.fontspec
+2021/05/22 | 43392 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2021/05/22 | 43059 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
+2021/05/22 | 429640 | fonts/kpfonts-otf/fonts/KpMath-Regular.otf
+2021/05/22 | 4294 | support/texlab/src/citation/name/parser.lalrpop
+2021/05/22 | 42925 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
+2021/05/22 | 428 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap
+2021/05/22 | 426 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap
+2021/05/22 | 4267938 | fonts/kpfonts-otf.zip
+2021/05/22 | 42627 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2021/05/22 | 425 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_args.snap
+2021/05/22 | 425 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__comment.snap
+2021/05/22 | 42574 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2021/05/22 | 423 | fonts/kpfonts-otf/tex/KpRoman.fontspec
+2021/05/22 | 42388 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
+2021/05/22 | 422 | macros/latex/contrib/bmstu-iu8/styles/21-IU8-math.sty
+2021/05/22 | 4218 | support/texlab/src/component_db.rs
+2021/05/22 | 4195 | support/texlab/src/diagnostics/latex.rs
+2021/05/22 | 41930 | fonts/newpx/doc/newpxdoc.tex
+2021/05/22 | 4190 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_incomplete_entry.snap
+2021/05/22 | 4190 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_complete_entry.snap
+2021/05/22 | 416 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_figure.snap
+2021/05/22 | 4165 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name.snap
+2021/05/22 | 41102 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
+2021/05/22 | 408 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap
+2021/05/22 | 4073 | macros/latex/contrib/bmstu-iu8/styles/05-IU8-figures.sty
+2021/05/22 | 4060 | support/texlab/src/features/hover/string_ref.rs
+2021/05/22 | 405 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap
+2021/05/22 | 4053 | support/texlab/tests/integration/snapshots/integration__completion__latex__package_import.snap
+2021/05/22 | 4010 | support/texlab/src/features/hover/citation.rs
+2021/05/22 | 3994 | support/texlab/src/workspace/storage.rs
+2021/05/22 | 3993 | support/texlab/src/features/lsp_kinds.rs
+2021/05/22 | 3982 | support/texlab/src/features/definition/command.rs
+2021/05/22 | 397364 | systems/texlive/tlnet/archive/texlive-scripts.doc.r59290.tar.xz
+2021/05/22 | 39689 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2021/05/22 | 39565 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
+2021/05/22 | 392596 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2021/05/22 | 3922729 | fonts/newpx.zip
+2021/05/22 | 387 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap
+2021/05/22 | 3856 | support/texlab/src/features/definition/entry.rs
+2021/05/22 | 38568 | systems/texlive/tlnet/archive/acmart.r59294.tar.xz
+2021/05/22 | 38560 | fonts/newtx/README
+2021/05/22 | 3854 | macros/latex/contrib/bmstu-iu8/styles/02-IU8-construction.sty
+2021/05/22 | 381 | support/texlab/src/features/highlight.rs
+2021/05/22 | 38069 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
+2021/05/22 | 38066 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
+2021/05/22 | 380190 | support/texlab/docs/demo.gif
+2021/05/22 | 37293 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2021/05/22 | 37242 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2021/05/22 | 372128 | systems/texlive/tlnet/archive/fontsize.doc.r59295.tar.xz
+2021/05/22 | 371 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap
+2021/05/22 | 3707 | support/texlab/src/features/symbol/types.rs
+2021/05/22 | 3693 | support/texlab/src/features/hover/field.rs
+2021/05/22 | 3670 | support/texlab/src/features/hover/entry_type.rs
+2021/05/22 | 36679 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2021/05/22 | 364 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_no_impl.snap
+2021/05/22 | 362 | support/texlab/src/syntax/latex/analysis/environment.rs
+2021/05/22 | 3627 | support/texlab/src/features/build.rs
+2021/05/22 | 361 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap
+2021/05/22 | 361 | support/texlab/src/req_queue.rs
+2021/05/22 | 3615 | support/texlab/src/features/definition/document.rs
+2021/05/22 | 360 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation.snap
+2021/05/22 | 3596 | support/texlab/src/workspace/parent_expand.rs
+2021/05/22 | 356 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl.snap
+2021/05/22 | 3560 | macros/latex/contrib/bmstu-iu8/styles/04-IU8-section-numbering.sty
+2021/05/22 | 3553 | support/texlab/src/features/symbol.rs
+2021/05/22 | 354 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__escaped_brackets.snap
+2021/05/22 | 354 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl_error.snap
+2021/05/22 | 35462 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
+2021/05/22 | 3535496 | systems/texlive/tlnet/archive/acmart.doc.r59294.tar.xz
+2021/05/22 | 35149 | support/texlab/LICENSE
+2021/05/22 | 35064 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2021/05/22 | 3471 | support/texlab/src/features/completion/types.rs
+2021/05/22 | 34635 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2021/05/22 | 345608 | systems/texlive/tlnet/archive/projlib.doc.r59296.tar.xz
+2021/05/22 | 345367 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2021/05/22 | 342 | support/texlab/src/syntax.rs
+2021/05/22 | 341 | support/texlab/src/syntax/latex/analysis/command.rs
+2021/05/22 | 3409 | support/texlab/src/features/link.rs
+2021/05/22 | 3400 | support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_glyph.snap
+2021/05/22 | 33948 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx
+2021/05/22 | 3389 | support/texlab/src/features/completion/color.rs
+2021/05/22 | 337 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap
+2021/05/22 | 3370 | support/texlab/src/features/symbol/bibtex.rs
+2021/05/22 | 336 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap
+2021/05/22 | 334 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap
+2021/05/22 | 33442 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/05/22 | 333 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap
+2021/05/22 | 332 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap
+2021/05/22 | 3317 | support/texlab/src/features/forward_search.rs
+2021/05/22 | 33153 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2021/05/22 | 3308 | support/texlab/src/features/completion/user_environment.rs
+2021/05/22 | 330235 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
+2021/05/22 | 327 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap
+2021/05/22 | 32744 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
+2021/05/22 | 324 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap
+2021/05/22 | 3243 | support/texlab/src/workspace/document.rs
+2021/05/22 | 322 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap
+2021/05/22 | 321894 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2021/05/22 | 3206200 | systems/texlive/tlnet/archive/luatexja.doc.r59299.tar.xz
+2021/05/22 | 318 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap
+2021/05/22 | 318 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap
+2021/05/22 | 3181 | support/texlab/tests/integration/workspace_symbol.rs
+2021/05/22 | 316 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap
+2021/05/22 | 316 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap
+2021/05/22 | 3167 | support/texlab/src/diagnostics/chktex.rs
+2021/05/22 | 31594 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2021/05/22 | 31544 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
+2021/05/22 | 31465 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx
+2021/05/22 | 31343 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2021/05/22 | 31192 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
+2021/05/22 | 311192 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
+2021/05/22 | 310 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap
+2021/05/22 | 308 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap
+2021/05/22 | 30886 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2021/05/22 | 3072 | support/texlab/src/features/rename/command.rs
+2021/05/22 | 305 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap
+2021/05/22 | 3043 | support/texlab/src/features/hover/component.rs
+2021/05/22 | 302 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error4.snap
+2021/05/22 | 301 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap
+2021/05/22 | 30038 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2021/05/22 | 299 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__wrap_long_lines.snap
+2021/05/22 | 2988 | support/texlab/docs/options.md
+2021/05/22 | 29867 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
+2021/05/22 | 2985 | macros/latex/contrib/bmstu-iu8/styles/07-IU8-footnotes.sty
+2021/05/22 | 2984 | support/texlab/src/workspace/watch.rs
+2021/05/22 | 297 | support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file_mumber.snap
+2021/05/22 | 295 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap
+2021/05/22 | 295554 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2021/05/22 | 294 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap
+2021/05/22 | 29437 | support/texlab/src/server.rs
+2021/05/22 | 293 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap
+2021/05/22 | 292 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap
+2021/05/22 | 290 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap
+2021/05/22 | 2906 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_incomplete_entry.snap
+2021/05/22 | 2906 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_complete_entry.snap
+2021/05/22 | 29050 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
+2021/05/22 | 2903 | support/texlab/tests/integration/snapshots/integration__completion__latex__label.snap
+2021/05/22 | 289 | support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file.snap
+2021/05/22 | 2897 | support/texlab/tests/integration/snapshots/integration__completion__latex__class_command.snap
+2021/05/22 | 2874 | support/texlab/src/features/completion/user_command.rs
+2021/05/22 | 2873 | support/texlab/tests/integration/snapshots/integration__completion__latex__package_environment.snap
+2021/05/22 | 2863 | support/texlab/tests/integration/snapshots/integration__completion__latex__preselect_environment.snap
+2021/05/22 | 285 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets_with_group.snap
+2021/05/22 | 283 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_simple.snap
+2021/05/22 | 283978 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2021/05/22 | 283291 | support/ltximg.zip
+2021/05/22 | 282 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap
+2021/05/22 | 2825 | support/texlab/tests/integration/snapshots/integration__completion__latex__pgf_library.snap
+2021/05/22 | 282108 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
+2021/05/22 | 281 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_empty.snap
+2021/05/22 | 281 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_missing_end.snap
+2021/05/22 | 28121 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
+2021/05/22 | 2801 | support/texlab/src/config.rs
+2021/05/22 | 28009 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/05/22 | 279 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_empty.snap
+2021/05/22 | 277 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_star.snap
+2021/05/22 | 2773 | support/texlab/tests/integration/snapshots/integration__completion__latex__package_command.snap
+2021/05/22 | 276440 | fonts/kpfonts-otf/fonts/KpMath-Sans.otf
+2021/05/22 | 275 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap
+2021/05/22 | 275 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap
+2021/05/22 | 27362 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
+2021/05/22 | 27275 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2021/05/22 | 27197 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
+2021/05/22 | 27182 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
+2021/05/22 | 268 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap
+2021/05/22 | 2688 | support/texlab/src/features/definition/label.rs
+2021/05/22 | 2658 | support/texlab/tests/integration/snapshots/integration__completion__latex__color_name.snap
+2021/05/22 | 2657 | support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_nested.snap
+2021/05/22 | 2620 | support/texlab/src/distro/miktex.rs
+2021/05/22 | 261961 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2021/05/22 | 2616929 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2021/05/22 | 258666 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
+2021/05/22 | 2564 | support/texlab/src/workspace/children_expand.rs
+2021/05/22 | 25584700 | systems/texlive/tlnet/install-tl.zip
+2021/05/22 | 2551 | macros/latex/contrib/bmstu-iu8/styles/01-IU8-base.sty
+2021/05/22 | 25341 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
+2021/05/22 | 252401 | macros/latex/contrib/bmstu-iu8.zip
+2021/05/22 | 25155 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
+2021/05/22 | 250214 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
+2021/05/22 | 25001 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2021/05/22 | 2499401 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
+2021/05/22 | 2478 | support/texlab/tests/integration/snapshots/integration__completion__latex__theorem_environment.snap
+2021/05/22 | 243 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_empty.snap
+2021/05/22 | 243 | macros/latex/contrib/bmstu-iu8/styles/11-IU8-performers.sty
+2021/05/22 | 243479 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2021/05/22 | 24234835 | support/texlab/data/components.json
+2021/05/22 | 241 | fonts/kpfonts-otf/tex/KpSans.fontspec
+2021/05/22 | 239479 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/05/22 | 23881 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2021/05/22 | 2361 | support/texlab/src/features/semantic/legend.rs
+2021/05/22 | 234 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__escape_sequence.snap
+2021/05/22 | 2337 | support/texlab/src/features/completion/begin_command.rs
+2021/05/22 | 2335 | support/texlab/src/syntax/latex/analysis/explicit_link.rs
+2021/05/22 | 23292 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2021/05/22 | 23209 | support/texlab/src/features/completion.rs
+2021/05/22 | 231 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap
+2021/05/22 | 2307008 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/05/22 | 2257 | fonts/newtx/tex/ot1ntxtosf.fd
+2021/05/22 | 2257 | fonts/newtx/tex/ly1ntxtosf.fd
+2021/05/22 | 2250 | support/texlab/docs/lsp_kinds.md
+2021/05/22 | 2246 | support/texlab/src/features/hover/label.rs
+2021/05/22 | 2240 | support/texlab/src/diagnostics/debouncer.rs
+2021/05/22 | 2223 | fonts/newtx/tex/t1ntxtosf.fd
+2021/05/22 | 2221 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_incomplete.snap
+2021/05/22 | 2218 | support/texlab/tests/integration/hover.rs
+2021/05/22 | 2217 | support/texlab/Cargo.toml
+2021/05/22 | 2209 | support/texlab/src/workspace/api.rs
+2021/05/22 | 22040 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
+2021/05/22 | 21810 | support/texlab/tests/integration/completion.rs
+2021/05/22 | 2171 | support/texlab/src/syntax/latex/analysis/distro_file.rs
+2021/05/22 | 2145 | macros/latex/contrib/bmstu-iu8/BMSTU-IU8.cls
+2021/05/22 | 214105 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/05/22 | 213 | macros/latex/contrib/bmstu-iu8/styles/08-IU8-formulas.sty
+2021/05/22 | 21132 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
+2021/05/22 | 211056 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2021/05/22 | 2108 | support/texlab/src/distro.rs
+2021/05/22 | 209 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap
+2021/05/22 | 209667 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2021/05/22 | 209550 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2021/05/22 | 2084 | support/texlab/src/dispatch.rs
+2021/05/22 | 2084 | fonts/newtx/tex/ot1ntxosf.fd
+2021/05/22 | 208182 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
+2021/05/22 | 20808632 | systems/texlive/tlnet/install-tl-windows.exe
+2021/05/22 | 2079 | fonts/newtx/tex/ly1ntxtlf.fd
+2021/05/22 | 2078 | fonts/newtx/tex/ot1ntxtlf.fd
+2021/05/22 | 2070 | support/texlab/src/diagnostics/build_log.rs
+2021/05/22 | 206 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets.snap
+2021/05/22 | 206 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_braces.snap
+2021/05/22 | 205 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__hello_world.snap
+2021/05/22 | 2050 | fonts/newtx/tex/t1ntxosf.fd
+2021/05/22 | 2048 | fonts/newtx/tex/t1ntxtlf.fd
+2021/05/22 | 2045 | support/texlab/src/options.rs
+2021/05/22 | 2040 | fonts/newtx/tex/ot1ntxlf.fd
+2021/05/22 | 2040 | fonts/newtx/tex/ly1ntxlf.fd
+2021/05/22 | 202558 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2021/05/22 | 2021 | support/texlab/docs/custom_messages.md
+2021/05/22 | 2019 | support/texlab/src/distro/kpsewhich.rs
+2021/05/22 | 20121 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
+2021/05/22 | 2009493 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2021/05/22 | 2007 | fonts/newtx/tex/t1ntxlf.fd
+2021/05/22 | 1998 | support/texlab/src/lang_data.rs
+2021/05/22 | 199700 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
+2021/05/22 | 198620 | fonts/kpfonts-otf/fonts/KpMath-Semibold.otf
+2021/05/22 | 198131 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
+2021/05/22 | 197754 | macros/latex/contrib/mindflow.zip
+2021/05/22 | 196892 | fonts/kpfonts-otf/fonts/KpMath-Bold.otf
+2021/05/22 | 1958700 | systems/texlive/tlnet/archive/siunitx.doc.r59292.tar.xz
+2021/05/22 | 195664 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2021/05/22 | 195567 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/05/22 | 193716 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
+2021/05/22 | 192899 | macros/latex/contrib/bmstu-iu8/example.pdf
+2021/05/22 | 191924 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf
+2021/05/22 | 1917 | support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color.snap
+2021/05/22 | 1914 | support/texlab/src/main.rs
+2021/05/22 | 1910 | support/texlab/src/syntax/latex/analysis/label_name.rs
+2021/05/22 | 190056 | systems/texlive/tlnet/archive/luatexja.r59299.tar.xz
+2021/05/22 | 189920 | fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf
+2021/05/22 | 1886 | support/texlab/src/uri.rs
+2021/05/22 | 187098 | macros/latex/contrib/mindflow/mindflow.pdf
+2021/05/22 | 18652 | systems/texlive/tlnet/archive/aalok.source.r59300.tar.xz
+2021/05/22 | 18630 | fonts/kpfonts-otf/tex/kpfonts-otf.sty
+2021/05/22 | 1862 | support/texlab/src/syntax/latex/analysis/types.rs
+2021/05/22 | 185 | fonts/kpfonts-otf/tex/KpMono.fontspec
+2021/05/22 | 1854 | support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_nested.snap
+2021/05/22 | 183 | support/texlab/CONTRIBUTING.md
+2021/05/22 | 18233 | fonts/newpx/README
+2021/05/22 | 181 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__junk.snap
+2021/05/22 | 18097 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2021/05/22 | 180048 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2021/05/22 | 1797 | fonts/newtx/tex/ly1ntxosf.fd
+2021/05/22 | 17958 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2021/05/22 | 179379 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
+2021/05/22 | 1791 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_nested.snap
+2021/05/22 | 1789 | support/texlab/src/features/completion/util.rs
+2021/05/22 | 1787182 | fonts/kpfonts-otf/doc/unimath-kpfonts.pdf
+2021/05/22 | 1784 | fonts/newpx/tfm/zplbexx.tfm
+2021/05/22 | 1780 | support/texlab/src/diagnostics.rs
+2021/05/22 | 1772 | fonts/newpx/tfm/zplexx.tfm
+2021/05/22 | 175 | macros/latex/contrib/bmstu-iu8/README.md
+2021/05/22 | 1725546 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
+2021/05/22 | 17243428 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2021/05/22 | 1720 | macros/latex/contrib/bmstu-iu8/styles/12-IU8-abstract.sty
+2021/05/22 | 170 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_empty.snap
+2021/05/22 | 1694 | macros/latex/contrib/bmstu-iu8/styles/13-IU8-contents.sty
+2021/05/22 | 1687 | support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_flat.snap
+2021/05/22 | 167907 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/05/22 | 16759 | support/texlab/src/syntax/latex/cst.rs
+2021/05/22 | 16745 | fonts/kpfonts-otf/doc/unimath-kpfonts.ltx
+2021/05/22 | 166 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_escape.snap
+2021/05/22 | 1662 | support/texlab/src/syntax/bibtex/lexer.rs
+2021/05/22 | 163720 | systems/texlive/tlnet/archive/aalok.doc.r59300.tar.xz
+2021/05/22 | 163689 | info/tlmgrbasics.zip
+2021/05/22 | 163656 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2021/05/22 | 16328 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
+2021/05/22 | 16188 | support/texlab/src/citation/ris.rs
+2021/05/22 | 1614 | macros/latex/contrib/bmstu-iu8/styles/09-IU8-cites.sty
+2021/05/22 | 16115 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
+2021/05/22 | 159 | support/texlab/build.rs
+2021/05/22 | 159969 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2021/05/22 | 1593 | support/texlab/src/client.rs
+2021/05/22 | 1578 | support/texlab/src/syntax/latex/analysis/implicit_link.rs
+2021/05/22 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2021/05/22 | 153890 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
+2021/05/22 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2021/05/22 | 152 | support/texlab/tests/integration/snapshots/integration__completion__latex__citation_after.snap
+2021/05/22 | 152762 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2021/05/22 | 1520 | macros/latex/contrib/bmstu-iu8/example.tex
+2021/05/22 | 15108 | systems/texlive/tlnet/archive/fontsize.source.r59295.tar.xz
+2021/05/22 | 1494 | support/texlab/tests/integration/snapshots/integration__document_symbol__section_nested.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__latex__empty_document.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__junk.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name_before.snap
+2021/05/22 | 148 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__empty_document.snap
+2021/05/22 | 147150 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
+2021/05/22 | 147139 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
+2021/05/22 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2021/05/22 | 1457 | support/texlab/src/features/formatting/latexindent.rs
+2021/05/22 | 1454 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap
+2021/05/22 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2021/05/22 | 1437 | macros/latex/contrib/bmstu-iu8/styles/22-IU8-algorithms.sty
+2021/05/22 | 14355 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2021/05/22 | 142704 | fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf
+2021/05/22 | 1425981 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2021/05/22 | 1424814 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2021/05/22 | 14204 | support/texlab/src/features/symbol/latex.rs
+2021/05/22 | 1413 | support/texlab/tests/integration/snapshots/integration__document_symbol__float_nested.snap
+2021/05/22 | 1405 | support/texlab/tests/integration/snapshots/integration__document_symbol__equation_nested.snap
+2021/05/22 | 140488 | fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf
+2021/05/22 | 1398 | support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_flat.snap
+2021/05/22 | 13757 | support/texlab/CHANGELOG.md
+2021/05/22 | 1365 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_section.snap
+2021/05/22 | 136429 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2021/05/22 | 1353 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap
+2021/05/22 | 135176 | fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf
+2021/05/22 | 135005 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
+2021/05/22 | 13469 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/05/22 | 13446 | macros/latex/contrib/mindflow/mindflow.dtx
+2021/05/22 | 134260 | fonts/kpfonts-otf/fonts/KpRoman-Italic.otf
+2021/05/22 | 132080 | fonts/kpfonts-otf/fonts/KpRoman-Bold.otf
+2021/05/22 | 1315 | macros/latex/contrib/bmstu-iu8/styles/03-IU8-numbering.sty
+2021/05/22 | 131490 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2021/05/22 | 130976 | fonts/kpfonts-otf/fonts/KpRoman-Regular.otf
+2021/05/22 | 1308 | fonts/newpx/vf/zplexx.vf
+2021/05/22 | 1307725 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2021/05/22 | 130328 | fonts/kpfonts-otf/fonts/KpRoman-Light.otf
+2021/05/22 | 1295415 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
+2021/05/22 | 129324 | fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf
+2021/05/22 | 1281106 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
+2021/05/22 | 1280 | fonts/newpx/vf/zplbexx.vf
+2021/05/22 | 1272534 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2021/05/22 | 1271317 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/05/22 | 1270 | support/texlab/src/line_index_ext.rs
+2021/05/22 | 126 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter.snap
+2021/05/22 | 1265 | support/texlab/src/features/hover.rs
+2021/05/22 | 125 | support/texlab/tests/integration/main.rs
+2021/05/22 | 124 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter_error.snap
+2021/05/22 | 124 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__concatenation.snap
+2021/05/22 | 124972 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
+2021/05/22 | 12483 | support/texlab/src/features/formatting/bibtex_internal.rs
+2021/05/22 | 1243 | support/texlab/tests/integration/issues.rs
+2021/05/22 | 123 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__invalid_parameter.snap
+2021/05/22 | 1237 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap
+2021/05/22 | 123776 | systems/texlive/tlnet/archive/tiscreen.doc.r59297.tar.xz
+2021/05/22 | 1236 | macros/latex/contrib/bmstu-iu8/styles/20-IU8-listing.sty
+2021/05/22 | 121952 | systems/texlive/tlnet/archive/lualibs.r59298.tar.xz
+2021/05/22 | 1210 | support/texlab/tests/integration/snapshots/integration__completion__latex__citation.snap
+2021/05/22 | 1209 | support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color_set.snap
+2021/05/22 | 1191 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap
+2021/05/22 | 1188645 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2021/05/22 | 1187112 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2021/05/22 | 117 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__command.snap
+2021/05/22 | 1171731 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
+2021/05/22 | 116930 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
+2021/05/22 | 115470 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2021/05/22 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
+2021/05/22 | 11519 | support/texlab/tests/integration/document_symbol.rs
+2021/05/22 | 114 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__trailing_comma.snap
+2021/05/22 | 114 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__insert_braces.snap
+2021/05/22 | 11495 | support/texlab/tests/integration/common.rs
+2021/05/22 | 11425 | fonts/newtx/tex/newtxtext.sty
+2021/05/22 | 1141 | support/texlab/src/syntax/latex/analysis.rs
+2021/05/22 | 1139 | macros/latex/contrib/bmstu-iu8/styles/16-IU8-references.sty
+2021/05/22 | 1138 | support/texlab/src/features/rename.rs
+2021/05/22 | 112253 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2021/05/22 | 111 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__preamble.snap
+2021/05/22 | 110936 | fonts/kpfonts-otf/fonts/KpSans-Italic.otf
+2021/05/22 | 110904 | fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf
+2021/05/22 | 1106 | macros/latex/contrib/bmstu-iu8/LICENSE
+2021/05/22 | 1101 | macros/latex/contrib/bmstu-iu8/styles/14-IU8-terms-and-definitions.sty
+2021/05/22 | 109273 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2021/05/22 | 1084 | support/texlab/src/features/definition.rs
+2021/05/22 | 1080 | support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_complete.snap
+2021/05/22 | 107 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__string.snap
+2021/05/22 | 107996 | systems/texlive/tlnet/archive/texlive-scripts.r59290.tar.xz
+2021/05/22 | 1078 | support/texlab/tests/integration/snapshots/integration__document_symbol__float_flat.snap
+2021/05/22 | 1078878 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2021/05/22 | 1074 | support/texlab/tests/integration/snapshots/integration__document_symbol__equation_flat.snap
+2021/05/22 | 1074 | support/texlab/src/distro/texlive.rs
+2021/05/22 | 1073 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap
+2021/05/22 | 1072 | systems/texlive/tlnet/archive/tiscreen.r59297.tar.xz
+2021/05/22 | 1061 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap
+2021/05/22 | 1051 | support/texlab/tests/integration/snapshots/integration__document_symbol__section_flat.snap
+2021/05/22 | 104624 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2021/05/22 | 10438 | support/texlab/src/features/semantic/bibtex.rs
+2021/05/22 | 1041 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap
+2021/05/22 | 1038 | support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_concatenation.snap
+2021/05/22 | 10375 | support/texlab/src/syntax/bibtex/parser.rs
+2021/05/22 | 1035 | support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_item.snap
+2021/05/22 | 103323 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/05/22 | 102 | support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__parens.snap
+2021/05/22 | 1029 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap
+2021/05/22 | 102972 | fonts/kpfonts-otf/fonts/KpSans-Bold.otf
+2021/05/22 | 1027 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap
+2021/05/22 | 102384 | fonts/kpfonts-otf/fonts/KpSans-Regular.otf
+2021/05/22 | 102144 | systems/texlive/tlnet/archive/siunitx.source.r59292.tar.xz
+2021/05/22 | 101764 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2021/05/22 | 100 | support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__empty.snap
2021/05/21 | 99215 | macros/luatex/generic/luaotfload/luaotfload-main.tex
2021/05/21 | 9901036 | macros/latex/contrib/acmart.zip
2021/05/21 | 9881 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua
-2021/05/21 | 98518 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
2021/05/21 | 9765 | macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
-2021/05/21 | 97490 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
2021/05/21 | 9740 | macros/luatex/generic/lualibs/lualibs-trac-inf.lua
-2021/05/21 | 97135 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
-2021/05/21 | 968696 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
2021/05/21 | 96848 | macros/latex/contrib/siunitx/siunitx-unit.dtx
2021/05/21 | 966557 | macros/luatex/generic/luaotfload/fontloader-reference.lua
2021/05/21 | 964 | macros/latex/contrib/siunitx/README.md
-2021/05/21 | 96145 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
-2021/05/21 | 94802 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
-2021/05/21 | 94735 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
2021/05/21 | 945 | macros/luatex/generic/luatexja/tool/table_ivd_aj1.lua
2021/05/21 | 945 | macros/luatex/generic/luatexja/doc/jfm-testf.lua
2021/05/21 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua
-2021/05/21 | 94269 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
2021/05/21 | 91892 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua
2021/05/21 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua
+2021/05/21 | 90192 | support/ltximg/ltximg-doc.tex
2021/05/21 | 896 | macros/luatex/generic/luatexja/tool/otf-KozMinPr6N-Regular.txt
2021/05/21 | 885 | macros/luatex/generic/luatexja/src/patches/lltjp-stfloats.sty
2021/05/21 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua
-2021/05/21 | 8774 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
-2021/05/21 | 87704 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2021/05/21 | 87638 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
2021/05/21 | 8762 | macros/latex/contrib/siunitx/siunitx-command.dtx
2021/05/21 | 864936 | macros/luatex/generic/luaotfload/fontloader-2021-05-20.lua
2021/05/21 | 8609 | macros/luatex/generic/luatexja/src/ltj-otf.lua
@@ -33,97 +678,50 @@
2021/05/21 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex
2021/05/21 | 8559 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
2021/05/21 | 8479 | macros/luatex/generic/luaotfload/shaper-demo.pdf
-2021/05/21 | 84774 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
-2021/05/21 | 839 | systems/win32/miktex/tm/packages/pr.ini
2021/05/21 | 825 | macros/luatex/generic/luatexja/src/patches/lltjp-collcell.sty
2021/05/21 | 81627 | macros/luatex/generic/lualibs/lualibs.pdf
-2021/05/21 | 816071 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
2021/05/21 | 8106 | macros/luatex/generic/luatexja/src/jfm-min.lua
-2021/05/21 | 80661 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
2021/05/21 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua
-2021/05/21 | 78746 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
2021/05/21 | 78171 | macros/unicodetex/latex/aalok/aalok.dtx
2021/05/21 | 7790 | macros/luatex/generic/luatexja/tool/jfm-convert.lua
-2021/05/21 | 77857 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
2021/05/21 | 77497 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf
-2021/05/21 | 77487 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2021/05/21 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
2021/05/21 | 77067 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf
2021/05/21 | 7661 | macros/luatex/generic/luatexja/src/ltj-unicode-ccfix.lua
2021/05/21 | 75912 | macros/latex/contrib/fontsize/fontsize.dtx
2021/05/21 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua
-2021/05/21 | 75417 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
2021/05/21 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
-2021/05/21 | 748362 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
-2021/05/21 | 74163 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
2021/05/21 | 7370 | macros/luatex/generic/luatexja/src/ltj-math.lua
2021/05/21 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example
-2021/05/21 | 73181 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
-2021/05/21 | 72859 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
2021/05/21 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua
-2021/05/21 | 72150 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/05/21 | 71568 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
-2021/05/21 | 70325 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
2021/05/21 | 7026 | macros/luatex/generic/luatexja/src/ltj-pretreat.lua
-2021/05/21 | 70109 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
2021/05/21 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex
2021/05/21 | 69366 | macros/luatex/generic/luatexja/doc/ltjltxdoc.pdf
2021/05/21 | 693535 | macros/luatex/generic/luatexja/doc/luatexja-en.pdf
+2021/05/21 | 6901 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2021/05/21 | 6891 | macros/luatex/generic/luatexja/src/addons/luatexja-otf.sty
2021/05/21 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua
-2021/05/21 | 6812825 | systems/texlive/tlnet/install-tl-unx.tar.gz
2021/05/21 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua
-2021/05/21 | 680048 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/05/21 | 67929 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/05/21 | 67679 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
-2021/05/21 | 67650 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
-2021/05/21 | 67450 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
2021/05/21 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua
-2021/05/21 | 65733 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
-2021/05/21 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
2021/05/21 | 65279 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua
2021/05/21 | 6497 | macros/luatex/generic/luatexja/src/patches/lltjdefs.sty
2021/05/21 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua
-2021/05/21 | 64017 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
-2021/05/21 | 63836 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
-2021/05/21 | 63674 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/05/21 | 6390 | support/ltximg/README.md
2021/05/21 | 63211 | macros/luatex/generic/luaotfload/fontloader-font-con.lua
2021/05/21 | 6317 | macros/luatex/generic/luaotfload/luaotfload-status.lua
2021/05/21 | 6309 | macros/luatex/generic/luaotfload/luaotfload-szss.lua
-2021/05/21 | 62801 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/05/21 | 625283 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
-2021/05/21 | 62226 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
2021/05/21 | 6203 | macros/luatex/generic/luatexja/src/ltj-base.sty
-2021/05/21 | 618763 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
2021/05/21 | 617 | macros/luatex/generic/luatexja/src/patches/lltjp-array.sty
2021/05/21 | 6060 | macros/luatex/generic/luatexja/tool/kyoikukanjiChars.tex
-2021/05/21 | 60551 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
2021/05/21 | 605308 | macros/latex/contrib/siunitx/siunitx.pdf
-2021/05/21 | 59831 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
-2021/05/21 | 594869 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
2021/05/21 | 5940 | macros/luatex/generic/luatexja/src/ltj-lotf_aux.lua
2021/05/21 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
-2021/05/21 | 59144 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
2021/05/21 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex
2021/05/21 | 5850 | macros/luatex/generic/luatexja/src/patches/lltjp-fontspec.sty
-2021/05/21 | 583627 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
2021/05/21 | 580 | macros/luatex/generic/luatexja/tool/blocks2defcharrange.rb
-2021/05/21 | 576615 | systems/win32/miktex/tm/packages/files.csv.lzma
-2021/05/21 | 576226 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2021/05/21 | 57599 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
2021/05/21 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua
-2021/05/21 | 57066 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
-2021/05/21 | 56909 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
2021/05/21 | 5682 | macros/luatex/generic/luatexja/src/patches/lltjp-tascmac.sty
-2021/05/21 | 567627 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/05/21 | 56719 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/05/21 | 56457 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/05/21 | 56223 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
-2021/05/21 | 55822 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
-2021/05/21 | 55563 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
2021/05/21 | 5544 | macros/luatex/generic/luatexja/src/ltj-latex.sty
2021/05/21 | 55333 | macros/luatex/generic/luatexja/src/ltj-jfmglue.lua
-2021/05/21 | 55219 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
2021/05/21 | 551 | macros/luatex/generic/luatexja/tool/jfm-readable.rb
2021/05/21 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua
2021/05/21 | 549 | macros/latex/contrib/tiscreen/README
@@ -131,76 +729,41 @@
2021/05/21 | 54080 | macros/luatex/generic/luaotfload/luaotfload-tool.lua
2021/05/21 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua
2021/05/21 | 534065 | macros/luatex/generic/luatexja/doc/luatexja.dtx
-2021/05/21 | 532038 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
2021/05/21 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf
2021/05/21 | 5297 | macros/unicodetex/latex/aalok/aalok.ins
-2021/05/21 | 52475 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
-2021/05/21 | 52454 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
2021/05/21 | 5222 | macros/luatex/generic/luatexja/src/ltj-debug.lua
2021/05/21 | 52002 | macros/luatex/generic/luatexja/doc/luatexja-ruby.tex
-2021/05/21 | 51979 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/05/21 | 51798 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/05/21 | 51432 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
-2021/05/21 | 511634 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/05/21 | 51159 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/05/21 | 50847 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
-2021/05/21 | 49971 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
2021/05/21 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua
2021/05/21 | 49501 | macros/luatex/generic/luatexja/src/patches/lltjfont.sty
2021/05/21 | 494977 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf
-2021/05/21 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
2021/05/21 | 4871 | macros/luatex/generic/luatexja/src/ltj-stack.lua
-2021/05/21 | 484055 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
2021/05/21 | 48217 | macros/luatex/generic/luatexja/src/ltj-jfont.lua
2021/05/21 | 4808 | macros/luatex/generic/luatexja/src/jfm-tmin.lua
-2021/05/21 | 47877 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
-2021/05/21 | 475936 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
2021/05/21 | 47497 | macros/latex/contrib/siunitx/siunitx-table.dtx
2021/05/21 | 4748 | macros/latex/contrib/siunitx/siunitx-abbreviations.cfg
2021/05/21 | 4740 | macros/luatex/generic/lualibs/README.md
-2021/05/21 | 4707 | systems/win32/miktex/tm/packages/next/miktex-config-2.9.tar.lzma
-2021/05/21 | 47007 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
2021/05/21 | 4629 | macros/latex/contrib/siunitx/siunitx-locale.dtx
-2021/05/21 | 461399 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
2021/05/21 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua
-2021/05/21 | 45937 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
2021/05/21 | 4588 | macros/luatex/generic/lualibs/lualibs-number.lua
2021/05/21 | 457434 | macros/luatex/generic/luatexja/doc/ltjsclasses.pdf
-2021/05/21 | 45649 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
-2021/05/21 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2021/05/21 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
-2021/05/21 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2021/05/21 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2021/05/21 | 4559 | macros/luatex/generic/luatexja/src/addons/luatexja-adjust.sty
-2021/05/21 | 45278 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
2021/05/21 | 45129 | macros/luatex/generic/luaotfload/fontloader-util-str.lua
2021/05/21 | 45129 | macros/luatex/generic/lualibs/lualibs-util-str.lua
2021/05/21 | 4452 | macros/luatex/generic/luatexja/doc/jfm-ujisc33.lua
2021/05/21 | 4408 | macros/luatex/generic/luatexja/src/ltj-plain.sty
2021/05/21 | 44027 | macros/latex/contrib/projlib/ProjLib.dtx
-2021/05/21 | 43677 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
-2021/05/21 | 43390 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/05/21 | 43057 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
-2021/05/21 | 42923 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
2021/05/21 | 4262 | macros/luatex/generic/luatexja/tool/kyoikukanji.txt
-2021/05/21 | 42626 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/05/21 | 42573 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/05/21 | 42388 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
2021/05/21 | 4196 | macros/luatex/generic/luatexja/src/patches/lltjp-atbegshi.sty
2021/05/21 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua
2021/05/21 | 41594 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
2021/05/21 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua
-2021/05/21 | 41103 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
2021/05/21 | 405 | macros/luatex/generic/luatexja/src/patches/lltjp-everyshi.sty
2021/05/21 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua
2021/05/21 | 400691 | macros/luatex/generic/luatexja/doc/ltjclasses.pdf
2021/05/21 | 40024 | macros/luatex/generic/luaotfload/filegraph.pdf
2021/05/21 | 39711 | macros/luatex/generic/luatexja/src/ltj-direction.lua
-2021/05/21 | 39690 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
2021/05/21 | 3961 | macros/luatex/generic/luatexja/src/ltj-charrange.lua
-2021/05/21 | 39563 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
2021/05/21 | 39406 | macros/latex/contrib/siunitx/CHANGELOG.md
-2021/05/21 | 392597 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
2021/05/21 | 388666 | macros/latex/contrib/projlib.zip
2021/05/21 | 387444 | macros/latex/contrib/fontsize.zip
2021/05/21 | 38735 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua
@@ -208,155 +771,108 @@
2021/05/21 | 385 | macros/luatex/generic/luatexja/src/ltjsclasses.ins
2021/05/21 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua
2021/05/21 | 381339 | macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf
-2021/05/21 | 38069 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
-2021/05/21 | 38066 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
2021/05/21 | 3797 | macros/luatex/generic/luatexja/README
2021/05/21 | 378517 | macros/latex/contrib/fontsize/fontsize.pdf
2021/05/21 | 3784 | macros/luatex/generic/luaotfload/README.md
2021/05/21 | 3782606 | macros/luatex/generic/luatexja.zip
2021/05/21 | 3755 | macros/luatex/generic/luatexja/src/ltj-lineskip.lua
2021/05/21 | 3748 | macros/luatex/generic/luatexja/src/ltj-compat.lua
-2021/05/21 | 37293 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2021/05/21 | 37242 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
2021/05/21 | 3693 | macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty
2021/05/21 | 3693 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
2021/05/21 | 3687 | macros/latex/contrib/siunitx/siunitx.ins
2021/05/21 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua
-2021/05/21 | 36679 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
2021/05/21 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua
2021/05/21 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
2021/05/21 | 355 | macros/luatex/generic/luatexja/tool/otf-AdobeMingStd-Light.txt
2021/05/21 | 355 | macros/luatex/generic/luatexja/doc/luatexja.ins
-2021/05/21 | 35463 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
-2021/05/21 | 35064 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
2021/05/21 | 34922 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua
-2021/05/21 | 34634 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2021/05/21 | 345367 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
2021/05/21 | 3451 | macros/luatex/generic/luatexja/src/luatexja-compat.sty
2021/05/21 | 343784 | macros/latex/contrib/easybook.zip
2021/05/21 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
2021/05/21 | 3371 | macros/luatex/generic/luatexja/src/patches/lltjp-xunicode.sty
2021/05/21 | 33461 | macros/luatex/generic/luatexja/src/addons/luatexja-ajmacros.sty
-2021/05/21 | 33441 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
-2021/05/21 | 33151 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
2021/05/21 | 3313 | macros/luatex/generic/luatexja/tool/ltj-unicode-ccfix_make2.pl
2021/05/21 | 33086 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua
-2021/05/21 | 330233 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
2021/05/21 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua
-2021/05/21 | 32745 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
2021/05/21 | 326 | macros/luatex/generic/luatexja/tool/otf-AdobeMyungjoStd-Medium.txt
2021/05/21 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
2021/05/21 | 3238 | macros/luatex/generic/luatexja/doc/jfm-test.lua
-2021/05/21 | 321895 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
2021/05/21 | 32099 | macros/luatex/generic/luatexja/src/ltj-ruby.lua
+2021/05/21 | 319369 | support/ltximg/ltximg-doc.pdf
2021/05/21 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua
2021/05/21 | 317 | macros/luatex/generic/luatexja/tool/otf-AdobeSongStd-Light.txt
2021/05/21 | 31738 | macros/latex/contrib/siunitx/siunitx-version-1.cfg
-2021/05/21 | 31593 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
-2021/05/21 | 31543 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
2021/05/21 | 3141 | macros/luatex/generic/lualibs/NEWS
2021/05/21 | 31368 | macros/latex/contrib/siunitx/siunitx-compound.dtx
2021/05/21 | 31349 | macros/luatex/generic/luaotfload/fontloader-font-one.lua
-2021/05/21 | 31343 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
2021/05/21 | 31335 | macros/latex/contrib/siunitx/siunitx-print.dtx
2021/05/21 | 312353 | macros/latex/contrib/easybook/easybook.pdf
-2021/05/21 | 31191 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
2021/05/21 | 31152 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua
-2021/05/21 | 311191 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
2021/05/21 | 3100 | macros/luatex/generic/luatexja/tool/table_jisx0208.tex
2021/05/21 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua
-2021/05/21 | 30884 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
-2021/05/21 | 30038 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
-2021/05/21 | 29868 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
2021/05/21 | 2964 | macros/latex/contrib/tiscreen/doc/tiscreen-doc.tex
2021/05/21 | 29580 | macros/luatex/generic/luaotfload/luaotfload-features.lua
-2021/05/21 | 295555 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
2021/05/21 | 29536 | macros/luatex/generic/luatexja/src/luatexja-core.sty
2021/05/21 | 29181 | macros/luatex/generic/luatexja/src/addons/luatexja-preset.sty
-2021/05/21 | 29055 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
2021/05/21 | 2883 | macros/latex/contrib/siunitx/siunitx-binary.dtx
-2021/05/21 | 283977 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
-2021/05/21 | 282107 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
-2021/05/21 | 28119 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
-2021/05/21 | 28009 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/05/21 | 27866 | support/ltximg/ltximg.man1.pdf
2021/05/21 | 27823 | macros/luatex/generic/lualibs/lualibs.dtx
2021/05/21 | 27620 | macros/latex/contrib/siunitx/siunitx-emulation.dtx
2021/05/21 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua
2021/05/21 | 273734 | install/macros/luatex/generic/lualibs.tds.zip
-2021/05/21 | 27362 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
2021/05/21 | 273398 | macros/latex/contrib/siunitx/siunitx-v2.sty
-2021/05/21 | 27274 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/05/21 | 27197 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
-2021/05/21 | 27183 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
2021/05/21 | 26934 | macros/luatex/generic/luatexja/src/lltjext.sty
2021/05/21 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua
2021/05/21 | 266042 | macros/luatex/generic/lualibs.zip
-2021/05/21 | 261962 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2021/05/21 | 2616931 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
2021/05/21 | 2601 | macros/luatex/generic/luatexja/src/jfm-banjiao.lua
2021/05/21 | 2586 | macros/luatex/generic/luatexja/src/jfm-kaiming.lua
-2021/05/21 | 258663 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
2021/05/21 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua
2021/05/21 | 2575 | macros/luatex/generic/luatexja/src/jfm-quanjiao.lua
2021/05/21 | 25719 | macros/latex/contrib/siunitx/siunitx-complex.dtx
-2021/05/21 | 25584691 | systems/texlive/tlnet/install-tl.zip
2021/05/21 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua
-2021/05/21 | 25342 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
2021/05/21 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua
2021/05/21 | 25264 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
-2021/05/21 | 25156 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
2021/05/21 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua
-2021/05/21 | 250213 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
-2021/05/21 | 25002 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/05/21 | 2499401 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
-2021/05/21 | 243478 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
2021/05/21 | 2426 | macros/latex/contrib/siunitx/siunitx-code.tex
-2021/05/21 | 239478 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
-2021/05/21 | 23881 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
2021/05/21 | 2374 | macros/luatex/generic/luatexja/src/patches/lltjp-unicode-math.sty
2021/05/21 | 2342 | macros/luatex/generic/luatexja/src/jfm-jis.lua
2021/05/21 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua
-2021/05/21 | 23291 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
2021/05/21 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua
-2021/05/21 | 2308404 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/05/21 | 22984 | info/tlmgrbasics/doc/tlmgr.tex
2021/05/21 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua
+2021/05/21 | 2282 | fonts/newpx/tex/ot1zpltosf.fd
+2021/05/21 | 2282 | fonts/newpx/tex/ly1zpltosf.fd
+2021/05/21 | 2247 | fonts/newpx/tex/t1zpltosf.fd
2021/05/21 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua
2021/05/21 | 2207 | macros/luatex/generic/luatexja/src/jfm-CCT.lua
-2021/05/21 | 22040 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
2021/05/21 | 2199205 | install/macros/latex/contrib/siunitx.tds.zip
2021/05/21 | 2193 | macros/luatex/generic/luatexja/src/addons/luatexja-zhfonts.sty
2021/05/21 | 21858 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
2021/05/21 | 21837 | macros/luatex/generic/luaotfload/scripts-demo.pdf
2021/05/21 | 2161925 | macros/latex/contrib/siunitx.zip
-2021/05/21 | 214104 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
2021/05/21 | 21136 | macros/luatex/generic/luatexja/src/luatexja.lua
-2021/05/21 | 21128 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
-2021/05/21 | 211055 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
-2021/05/21 | 209603 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2021/05/21 | 209568 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2021/05/21 | 208180 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
-2021/05/21 | 20810464 | systems/texlive/tlnet/install-tl-windows.exe
+2021/05/21 | 2109 | fonts/newpx/tex/ot1zpltlf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ot1zplosf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ly1zpltlf.fd
+2021/05/21 | 2109 | fonts/newpx/tex/ly1zplosf.fd
+2021/05/21 | 2075 | fonts/newpx/tex/t1zplosf.fd
+2021/05/21 | 2074 | fonts/newpx/tex/t1zpltlf.fd
+2021/05/21 | 2065 | fonts/newpx/tex/ot1zpllf.fd
+2021/05/21 | 2065 | fonts/newpx/tex/ly1zpllf.fd
2021/05/21 | 2057 | macros/luatex/generic/luatexja/src/patches/lltjp-microtype.sty
+2021/05/21 | 2029 | fonts/newpx/tex/t1zpllf.fd
2021/05/21 | 20294 | macros/luatex/generic/luaotfload/NEWS
-2021/05/21 | 202558 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
-2021/05/21 | 20120 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
2021/05/21 | 200 | macros/luatex/generic/luatexja/src/jfm-prop.lua
-2021/05/21 | 2009491 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
2021/05/21 | 1999 | macros/unicodetex/latex/aalok/README.txt
-2021/05/21 | 199701 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
2021/05/21 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua
-2021/05/21 | 198131 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
2021/05/21 | 196 | macros/luatex/generic/luatexja/src/jfm-propw.lua
2021/05/21 | 196 | macros/luatex/generic/luatexja/src/jfm-propv.lua
2021/05/21 | 19572 | macros/luatex/generic/luatexja/src/ltj-adjust.lua
2021/05/21 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua
-2021/05/21 | 195664 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
-2021/05/21 | 195566 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
2021/05/21 | 19549 | macros/luatex/generic/luaotfload/luaotfload-init.lua
2021/05/21 | 19541 | macros/latex/contrib/siunitx/siunitx.dtx
2021/05/21 | 19516 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
2021/05/21 | 19410 | macros/luatex/generic/lualibs/lualibs-os.lua
-2021/05/21 | 193717 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
2021/05/21 | 1936005 | install/macros/luatex/generic/luaotfload.tds.zip
2021/05/21 | 1932221 | macros/luatex/generic/luaotfload.zip
2021/05/21 | 192 | macros/luatex/generic/luatexja/src/jfm-mono.lua
@@ -374,114 +890,74 @@
2021/05/21 | 1832 | macros/luatex/generic/luatexja/src/luatexja.sty
2021/05/21 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex
2021/05/21 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty
-2021/05/21 | 18096 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
2021/05/21 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst
-2021/05/21 | 180048 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/05/21 | 17957 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
2021/05/21 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua
-2021/05/21 | 179379 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
2021/05/21 | 177581 | macros/luatex/generic/luatexja/src/ltjclasses.dtx
2021/05/21 | 1765 | macros/luatex/generic/luatexja/src/ltj-inputbuf.lua
2021/05/21 | 1729 | macros/latex/contrib/siunitx/siunitx-binary.cfg
-2021/05/21 | 1725549 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
-2021/05/21 | 17243572 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2021/05/21 | 167908 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
2021/05/21 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex
2021/05/21 | 166557 | macros/luatex/generic/luatexja/doc/lltjp-geometry.pdf
2021/05/21 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5
2021/05/21 | 16529 | macros/latex/contrib/siunitx/siunitx-angle.dtx
2021/05/21 | 1637 | macros/luatex/generic/luatexja/src/addons/luatexja-fontspec.sty
-2021/05/21 | 163656 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2021/05/21 | 16327 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
2021/05/21 | 16116 | macros/luatex/generic/luaotfload/luaotfload-tool.rst
-2021/05/21 | 16113 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
-2021/05/21 | 159969 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
2021/05/21 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua
2021/05/21 | 15839 | macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty
+2021/05/21 | 157582 | info/tlmgrbasics/doc/tlmgr.pdf
2021/05/21 | 154828 | macros/luatex/generic/luatexja/src/ltj-ivd_aj1.lua
2021/05/21 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
-2021/05/21 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2021/05/21 | 153890 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
2021/05/21 | 153734 | macros/unicodetex/latex/aalok/aalok.pdf
2021/05/21 | 1536 | macros/luatex/generic/luatexja/COPYING
-2021/05/21 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2021/05/21 | 152762 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
2021/05/21 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
2021/05/21 | 1511 | macros/latex/contrib/fontsize/README
2021/05/21 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
-2021/05/21 | 147151 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
-2021/05/21 | 147140 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
2021/05/21 | 14713 | macros/luatex/generic/lualibs/lualibs-url.lua
2021/05/21 | 14709 | macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty
-2021/05/21 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
2021/05/21 | 14517 | macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua
-2021/05/21 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
2021/05/21 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua
2021/05/21 | 1441845 | macros/latex/contrib/siunitx/siunitx-code.pdf
-2021/05/21 | 14353 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
2021/05/21 | 14351 | macros/latex/contrib/siunitx/siunitx-quantity.dtx
-2021/05/21 | 1425981 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2021/05/21 | 1424811 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
2021/05/21 | 1397 | macros/luatex/generic/luatexja/tool/ivslist.tex
2021/05/21 | 13899 | macros/luatex/generic/luatexja/src/jfm-ujis.lua
2021/05/21 | 138579 | macros/latex/contrib/siunitx/siunitx.tex
2021/05/21 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua
2021/05/21 | 13726 | macros/luatex/generic/luatexja/doc/lltjp-geometry.tex
2021/05/21 | 13657 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
-2021/05/21 | 136427 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
2021/05/21 | 1362 | macros/luatex/generic/luatexja/src/patches/lltjp-footmisc.sty
2021/05/21 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua
-2021/05/21 | 135006 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
2021/05/21 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua
-2021/05/21 | 13470 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/05/21 | 134852 | support/ltximg/ltximg.pl
2021/05/21 | 13194 | macros/luatex/generic/luatexja/src/ltj-setwidth.lua
2021/05/21 | 131865 | macros/luatex/generic/lualibs/lualibs-basic-merged.lua
-2021/05/21 | 131489 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/05/21 | 1307723 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/05/21 | 1295415 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
2021/05/21 | 12829 | macros/luatex/generic/luaotfload/luaotfload-tool.1
-2021/05/21 | 1281102 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
2021/05/21 | 1278 | macros/luatex/generic/luatexja/src/ltjclasses.ins
2021/05/21 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
-2021/05/21 | 1272452 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2021/05/21 | 1271700 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
2021/05/21 | 12704 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
2021/05/21 | 126 | macros/luatex/generic/luatexja/src/ltjltxdoc.ins
2021/05/21 | 12566 | macros/luatex/generic/lualibs/lualibs-package.lua
-2021/05/21 | 124973 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
2021/05/21 | 124455 | macros/latex/contrib/easybook/easybook.dtx
2021/05/21 | 12389 | macros/luatex/generic/luatexja/src/patches/lltjcore.sty
2021/05/21 | 123718 | macros/latex/contrib/tiscreen.zip
+2021/05/21 | 122791173 | macros/context/latest/cont-tmf.zip
2021/05/21 | 1224 | macros/luatex/generic/luatexja/tool/chars2defcharrange.rb
2021/05/21 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua
2021/05/21 | 121968 | macros/latex/contrib/tiscreen/doc/tiscreen-doc.pdf
2021/05/21 | 12151 | macros/luatex/generic/luatexja/src/ltj-base.lua
2021/05/21 | 119385 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua
-2021/05/21 | 1187934 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2021/05/21 | 1187128 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
2021/05/21 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua
-2021/05/21 | 1171731 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
-2021/05/21 | 116930 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
2021/05/21 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua
-2021/05/21 | 115470 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/05/21 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
2021/05/21 | 11506 | macros/luatex/generic/luatexja/src/jfm-ujisv.lua
2021/05/21 | 113800 | macros/latex/contrib/siunitx/siunitx-number.dtx
2021/05/21 | 11335 | macros/luatex/generic/luatexja/tool/unicodeBlocks.tex
2021/05/21 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua
2021/05/21 | 1130 | macros/luatex/generic/luatexja/tool/function_uax50.lua
2021/05/21 | 1130307 | macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
-2021/05/21 | 112250 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
2021/05/21 | 111260 | macros/luatex/generic/lualibs/lualibs-extended-merged.lua
2021/05/21 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
-2021/05/21 | 109274 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/05/21 | 1078878 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
2021/05/21 | 107562 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua
-2021/05/21 | 104625 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
-2021/05/21 | 103322 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/05/21 | 10599 | support/ltximg/ltximg.1
2021/05/21 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
2021/05/21 | 10200 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
-2021/05/21 | 101763 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
2021/05/21 | 10106 | macros/latex/contrib/siunitx/siunitx-abbreviation.dtx
2021/05/21 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua
2021/05/21 | 10045 | macros/latex/contrib/siunitx/siunitx-symbol.dtx
@@ -490,23 +966,38 @@
2021/05/20 | 966784 | systems/texlive/tlnet/archive/newtx.doc.r59277.tar.xz
2021/05/20 | 9482 | support/texdoc/script/texdoclib-view.tlu
2021/05/20 | 948160 | systems/texlive/tlnet/archive/powerdot.doc.r59272.tar.xz
-2021/05/20 | 9348 | systems/texlive/tlnet/archive/projlib.source.r59271.tar.xz
2021/05/20 | 93301 | macros/xetex/generic/xetexko/xetexko.sty
-2021/05/20 | 9248 | systems/texlive/tlnet/archive/projlib.r59271.tar.xz
2021/05/20 | 8626662 | systems/win32/miktex/tm/packages/hvfloat.tar.lzma
2021/05/20 | 8600 | systems/texlive/tlnet/archive/covington.r59266.tar.xz
2021/05/20 | 84310 | support/texdoc/doc/texdoc.pdf
2021/05/20 | 842246 | macros/latex/contrib/acmart/acmart.pdf
2021/05/20 | 841881 | macros/latex/contrib/suftesi/suftesi.pdf
-2021/05/20 | 8397497 | fonts/newtx.zip
2021/05/20 | 834009 | systems/win32/w32tex/ChangeLog
+2021/05/20 | 8296 | fonts/newpx/tfm/zpl-Slanted-lf-sc-ly1.tfm
+2021/05/20 | 8292 | fonts/newpx/tfm/zpl-Slanted-osf-sc-ly1.tfm
2021/05/20 | 8291 | support/texdoc/NEWS
+2021/05/20 | 8252 | fonts/newpx/tfm/zpl-Slanted-tosf-sc-ly1.tfm
+2021/05/20 | 8252 | fonts/newpx/tfm/zpl-Slanted-tlf-sc-ly1.tfm
+2021/05/20 | 8224 | fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ly1.tfm
+2021/05/20 | 8212 | fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ly1.tfm
+2021/05/20 | 8180 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ly1.tfm
+2021/05/20 | 8180 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ly1.tfm
+2021/05/20 | 7967 | fonts/newpx/tex/newpxtext.sty
2021/05/20 | 795 | macros/latex/contrib/acmart/samples/samples.ins
+2021/05/20 | 7944 | fonts/newpx/tfm/zpl-Slanted-lf-ly1.tfm
+2021/05/20 | 7940 | fonts/newpx/tfm/zpl-Slanted-osf-ly1.tfm
+2021/05/20 | 7904 | fonts/newpx/tfm/zpl-Slanted-tosf-ly1.tfm
+2021/05/20 | 7904 | fonts/newpx/tfm/zpl-Slanted-tlf-ly1.tfm
2021/05/20 | 781050 | systems/win32/miktex/tm/packages/apa7.tar.lzma
2021/05/20 | 7793 | macros/xetex/generic/xetexko/ChangeLog
2021/05/20 | 768566 | macros/latex/contrib/acmart/samples/sample-lualatex.pdf
+2021/05/20 | 7540 | fonts/newpx/tfm/zpl-BoldSlanted-lf-ly1.tfm
+2021/05/20 | 7528 | fonts/newpx/tfm/zpl-BoldSlanted-osf-ly1.tfm
+2021/05/20 | 7496 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-ly1.tfm
+2021/05/20 | 7496 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-ly1.tfm
+2021/05/20 | 7444 | fonts/newpx/tfm/zplth-Italic-osf-ly1.tfm
+2021/05/20 | 7396 | fonts/newpx/tfm/zplth-Italic-tlf-ly1.tfm
2021/05/20 | 7060 | support/texdoc/script/texdoclib-cli.tlu
-2021/05/20 | 6946 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2021/05/20 | 6916 | systems/texlive/tlnet/archive/alterqcm.r59265.tar.xz
2021/05/20 | 681675 | macros/latex/contrib/suftesi/templates.zip
2021/05/20 | 677458 | systems/win32/miktex/tm/packages/pm-isomath.tar.lzma
@@ -522,7 +1013,6 @@
2021/05/20 | 6356 | systems/texlive/tlnet/archive/collection-latexextra.r59271.tar.xz
2021/05/20 | 6114 | macros/latex/contrib/acrotex/README.md
2021/05/20 | 6032 | systems/texlive/tlnet/tlpkg/TeXLive/trans.pl
-2021/05/20 | 60252 | systems/texlive/tlnet/archive/siunitx.r59279.tar.xz
2021/05/20 | 598702 | macros/latex/contrib/acmart/samples/sample-acmsmall-submission.pdf
2021/05/20 | 598279 | macros/latex/contrib/acmart/samples/sample-manuscript.pdf
2021/05/20 | 596225 | macros/latex/contrib/acmart/samples/sample-acmsmall.pdf
@@ -537,28 +1027,45 @@
2021/05/20 | 43284 | systems/texlive/tlnet/archive/suftesi.source.r59280.tar.xz
2021/05/20 | 4259 | support/texdoc/script/texdoclib-const.tlu
2021/05/20 | 414201 | macros/latex/contrib/acmart/acmguide.pdf
-2021/05/20 | 397364 | systems/texlive/tlnet/archive/texlive-scripts.doc.r59286.tar.xz
2021/05/20 | 39492 | macros/xetex/generic/xetexko/hanjaexa_hangul.tab
2021/05/20 | 3849 | support/texdoc/README.md
-2021/05/20 | 38415 | fonts/newtx/README
2021/05/20 | 3807 | support/texdoc/doc/texdoc.1
2021/05/20 | 3800139 | macros/latex/contrib/acrotex.zip
2021/05/20 | 3756 | macros/latex/contrib/suppose/suppose-doc.tex
2021/05/20 | 3744372 | info/biblio/tugboat.bib
+2021/05/20 | 367102 | fonts/newpx/afm/zplrsl.afm
2021/05/20 | 365158 | systems/win32/miktex/tm/packages/projlib.tar.lzma
+2021/05/20 | 3588 | fonts/newpx/tfm/zpl-Slanted-lf-sc-ot1.tfm
+2021/05/20 | 3584 | fonts/newpx/tfm/zpl-Slanted-osf-sc-ot1.tfm
2021/05/20 | 3573 | info/biblio/tugboat.ltx
+2021/05/20 | 357289 | fonts/newpx/afm/zplbsl.afm
2021/05/20 | 356212 | systems/win32/miktex/tm/packages/easybook.tar.lzma
+2021/05/20 | 3552 | fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ot1.tfm
+2021/05/20 | 3548 | fonts/newpx/tfm/zpl-Slanted-lf-ot1.tfm
+2021/05/20 | 3544 | fonts/newpx/tfm/zpl-Slanted-tosf-sc-ot1.tfm
+2021/05/20 | 3544 | fonts/newpx/tfm/zpl-Slanted-tlf-sc-ot1.tfm
+2021/05/20 | 3544 | fonts/newpx/tfm/zpl-Slanted-osf-ot1.tfm
+2021/05/20 | 3536 | fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ot1.tfm
2021/05/20 | 35275504 | systems/win32/w32tex/ltxpkgs.tar.xz
2021/05/20 | 35149 | macros/unicodetex/latex/aalok/COPYING
2021/05/20 | 35147 | support/texdoc/COPYING
+2021/05/20 | 3508 | fonts/newpx/tfm/zpl-Slanted-tosf-ot1.tfm
+2021/05/20 | 3508 | fonts/newpx/tfm/zpl-Slanted-tlf-ot1.tfm
+2021/05/20 | 3508 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ot1.tfm
+2021/05/20 | 3504 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ot1.tfm
2021/05/20 | 3471 | macros/xetex/generic/xetexko/README
-2021/05/20 | 346208 | systems/texlive/tlnet/archive/projlib.doc.r59271.tar.xz
2021/05/20 | 34042 | support/texdoc/doc/texdoc.tex
2021/05/20 | 33948 | macros/xetex/generic/xetexko/xetexko-doc.tex
2021/05/20 | 3369 | support/texdoc/script/texdoclib-util.tlu
2021/05/20 | 333842 | macros/xetex/generic/xetexko.zip
2021/05/20 | 3312 | macros/latex/contrib/acmart/Makefile
+2021/05/20 | 3300 | fonts/newpx/tfm/zpl-BoldSlanted-lf-ot1.tfm
+2021/05/20 | 3288 | fonts/newpx/tfm/zpl-BoldSlanted-osf-ot1.tfm
+2021/05/20 | 3256 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-ot1.tfm
+2021/05/20 | 3256 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-ot1.tfm
2021/05/20 | 3214 | support/texdoc/script/texdoclib-alias.tlu
+2021/05/20 | 3176 | fonts/newpx/tfm/zplth-Italic-osf-ot1.tfm
+2021/05/20 | 3136 | fonts/newpx/tfm/zplth-Italic-tlf-ot1.tfm
2021/05/20 | 31368 | macros/latex/contrib/acmart/samples/samples.dtx
2021/05/20 | 311580 | systems/texlive/tlnet/archive/easybook.doc.r59278.tar.xz
2021/05/20 | 30100 | systems/texlive/tlnet/archive/easybook.source.r59278.tar.xz
@@ -573,53 +1080,71 @@
2021/05/20 | 249884 | macros/latex/contrib/acmart/acmart.dtx
2021/05/20 | 2448 | systems/texlive/tlnet/archive/suppose.r59281.tar.xz
2021/05/20 | 24459 | support/texdoc/script/texdoclib-search.tlu
-2021/05/20 | 2362424 | systems/texlive/tlnet/archive/siunitx.doc.r59279.tar.xz
2021/05/20 | 232596 | macros/latex/contrib/suftesi/suftesi.dtx
-2021/05/20 | 2288 | fonts/newtx/tex/ot1ntxtosf.fd
-2021/05/20 | 2288 | fonts/newtx/tex/ly1ntxtosf.fd
+2021/05/20 | 23241 | fonts/newpx/map/newpx.map
2021/05/20 | 2255476 | macros/latex/contrib/acrotex/doc/aeb_man.pdf
-2021/05/20 | 2254 | fonts/newtx/tex/t1ntxtosf.fd
2021/05/20 | 222934 | macros/latex/contrib/projlib/ProjLib-doc-cn.pdf
2021/05/20 | 2227944 | systems/win32/w32tex/win64/context-w64.tar.xz
-2021/05/20 | 2115 | fonts/newtx/tex/ot1ntxosf.fd
-2021/05/20 | 2110 | fonts/newtx/tex/ly1ntxtlf.fd
-2021/05/20 | 2109 | fonts/newtx/tex/ot1ntxtlf.fd
-2021/05/20 | 2081 | fonts/newtx/tex/t1ntxosf.fd
-2021/05/20 | 2079 | fonts/newtx/tex/t1ntxtlf.fd
+2021/05/20 | 213291 | fonts/newpx/type1/zplbsl.pfb
2021/05/20 | 20758 | macros/latex/contrib/projlib/ProjLib-doc-en.tex
-2021/05/20 | 2071 | fonts/newtx/tex/ot1ntxlf.fd
-2021/05/20 | 2071 | fonts/newtx/tex/ly1ntxlf.fd
2021/05/20 | 206852 | macros/latex/contrib/suppose/suppose-doc.pdf
+2021/05/20 | 205748 | fonts/newpx/type1/zplrsl.pfb
2021/05/20 | 20413 | support/texdoc/script/texdoclib-config.tlu
-2021/05/20 | 2037 | fonts/newtx/tex/t1ntxlf.fd
2021/05/20 | 199588 | macros/latex/contrib/suppose.zip
2021/05/20 | 197272 | macros/latex/contrib/acrotex/doc/eformman.tex
2021/05/20 | 197208 | systems/texlive/tlnet/archive/suppose.doc.r59281.tar.xz
2021/05/20 | 19479 | macros/latex/contrib/projlib/ProjLib-doc-cn.tex
2021/05/20 | 1920 | systems/texlive/tlnet/archive/pgfmath-xfp.r59268.tar.xz
2021/05/20 | 18592 | systems/texlive/tlnet/archive/pm-isomath.source.r59269.tar.xz
-2021/05/20 | 1828 | fonts/newtx/tex/ly1ntxosf.fd
2021/05/20 | 1812 | macros/xetex/generic/xetexko/hanjacom_hangul.tab
2021/05/20 | 17204 | support/texdoc/texdoc.cnf
2021/05/20 | 1673509 | systems/win32/miktex/tm/packages/bxjscls.tar.lzma
2021/05/20 | 1670 | macros/latex/contrib/suftesi/README
+2021/05/20 | 1609 | fonts/newpx/tex/ly1zplth-tosf.fd
+2021/05/20 | 1608 | fonts/newpx/tex/ot1zplth-tosf.fd
+2021/05/20 | 1586 | fonts/newpx/tex/t1zplth-tosf.fd
2021/05/20 | 1577056 | install/macros/latex/contrib/suftesi.tds.zip
+2021/05/20 | 1570 | fonts/newpx/tex/ot1zplth-tlf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ot1zplth-osf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ly1zplth-tlf.fd
+2021/05/20 | 1570 | fonts/newpx/tex/ly1zplth-osf.fd
2021/05/20 | 1560182 | macros/latex/contrib/suftesi.zip
+2021/05/20 | 1549 | fonts/newpx/tex/t1zplth-osf.fd
+2021/05/20 | 1540 | fonts/newpx/tex/t1zplth-tlf.fd
+2021/05/20 | 1532 | fonts/newpx/tex/ot1zplth-lf.fd
+2021/05/20 | 1532 | fonts/newpx/tex/ly1zplth-lf.fd
2021/05/20 | 151198 | support/texdoc.zip
+2021/05/20 | 1510 | fonts/newpx/tex/t1zplth-lf.fd
2021/05/20 | 14868 | systems/texlive/tlnet/archive/suftesi.r59280.tar.xz
2021/05/20 | 144842692 | systems/win32/w32tex/context.tar.xz
2021/05/20 | 143188 | macros/latex/contrib/projlib/ProjLib-doc-en.pdf
2021/05/20 | 1382 | support/texdoc/script/texdoc.tlu
2021/05/20 | 13712 | systems/texlive/tlnet/archive/easybook.r59278.tar.xz
2021/05/20 | 135656 | systems/texlive/tlnet/archive/texdoc.doc.r59283.tar.xz
+2021/05/20 | 13344 | fonts/newpx/tfm/zpl-Slanted-lf-sc-t1.tfm
+2021/05/20 | 13340 | fonts/newpx/tfm/zpl-Slanted-osf-sc-t1.tfm
+2021/05/20 | 13300 | fonts/newpx/tfm/zpl-Slanted-tosf-sc-t1.tfm
+2021/05/20 | 13300 | fonts/newpx/tfm/zpl-Slanted-tlf-sc-t1.tfm
2021/05/20 | 1320 | support/texdoc/script/texdoclib.tlu
+2021/05/20 | 13164 | fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-t1.tfm
+2021/05/20 | 13152 | fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-t1.tfm
+2021/05/20 | 13120 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-t1.tfm
+2021/05/20 | 13120 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-t1.tfm
2021/05/20 | 126756 | macros/latex/contrib/acrotex/examples/jquiztst.pdf
2021/05/20 | 125412 | macros/xetex/generic/xetexko/hanja_hangul.tab
-2021/05/20 | 122787914 | macros/context/latest/cont-tmf.zip
+2021/05/20 | 12476 | fonts/newpx/tfm/zpl-Slanted-lf-t1.tfm
+2021/05/20 | 12464 | fonts/newpx/tfm/zpl-Slanted-osf-t1.tfm
+2021/05/20 | 12428 | fonts/newpx/tfm/zpl-Slanted-tosf-t1.tfm
+2021/05/20 | 12428 | fonts/newpx/tfm/zpl-Slanted-tlf-t1.tfm
+2021/05/20 | 11892 | fonts/newpx/tfm/zpl-BoldSlanted-lf-t1.tfm
+2021/05/20 | 11876 | fonts/newpx/tfm/zpl-BoldSlanted-osf-t1.tfm
+2021/05/20 | 11852 | fonts/newpx/tfm/zplth-Italic-osf-t1.tfm
+2021/05/20 | 11844 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-t1.tfm
+2021/05/20 | 11844 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-t1.tfm
+2021/05/20 | 11812 | fonts/newpx/tfm/zplth-Italic-tlf-t1.tfm
2021/05/20 | 1167310 | systems/win32/miktex/tm/packages/alterqcm.tar.lzma
2021/05/20 | 1158238 | systems/win32/miktex/tm/packages/tuda-ci.tar.lzma
2021/05/20 | 11035 | macros/latex/contrib/acmart/README
-2021/05/20 | 108004 | systems/texlive/tlnet/archive/texlive-scripts.r59286.tar.xz
2021/05/20 | 1078332 | systems/texlive/tlnet/archive/alterqcm.doc.r59265.tar.xz
2021/05/20 | 106879 | systems/win32/miktex/tm/packages/hvqrurl.tar.lzma
2021/05/20 | 10506 | macros/latex/contrib/suppose/suppose.sty
@@ -630,7 +1155,6 @@
2021/05/20 | 1022861 | macros/latex/contrib/acmart/samples/sample-authordraft.pdf
2021/05/20 | 1019048 | macros/latex/contrib/acmart/samples/sample-sigconf.pdf
2021/05/20 | 1016 | macros/latex/contrib/acmart/acmart.ins
-2021/05/20 | 101336 | systems/texlive/tlnet/archive/siunitx.source.r59279.tar.xz
2021/05/19 | 990 | macros/latex/contrib/suppose/README.md
2021/05/19 | 9672 | systems/texlive/tlnet/archive/hvfloat.r59255.tar.xz
2021/05/19 | 93556 | systems/texlive/tlnet/archive/latexmk.r59258.tar.xz
@@ -683,13 +1207,11 @@
2021/05/18 | 9383 | macros/latex/contrib/tuda-ci/tex/beamerouterthemeTUDa.sty
2021/05/18 | 930770 | systems/win32/miktex/tm/packages/unravel.tar.lzma
2021/05/18 | 9294 | macros/latex/contrib/tuda-ci/tex/tudamecheng.cfg
-2021/05/18 | 912 | systems/texlive/tlnet/archive/tiscreen.r59247.tar.xz
2021/05/18 | 901928 | systems/texlive/tlnet/archive/tex4ht.r59249.tar.xz
2021/05/18 | 9008 | systems/texlive/tlnet/archive/musixtex.source.r59240.tar.xz
2021/05/18 | 89431 | systems/win32/miktex/tm/packages/codehigh.tar.lzma
2021/05/18 | 87704 | language/japanese/BX/bxjscls/bxjscls-manual.tex
2021/05/18 | 8501 | macros/latex/contrib/tuda-ci/example/DEMO-TUDaSciPoster.tex
-2021/05/18 | 83288 | systems/texlive/tlnet/archive/luatexja.source.r59248.tar.xz
2021/05/18 | 831492 | macros/latex/contrib/apa7.zip
2021/05/18 | 8237 | macros/latex/contrib/tuda-ci/tex/beamerinnerthemeTUDa.sty
2021/05/18 | 775860 | systems/win32/miktex/tm/packages/lua-physical.tar.lzma
@@ -760,7 +1282,6 @@
2021/05/18 | 3427084 | systems/win32/w32tex/tex4htk-w32.tar.xz
2021/05/18 | 3243 | macros/latex/contrib/tuda-ci/tex/tudafonts.sty
2021/05/18 | 32159 | macros/latex/contrib/tuda-ci/tex/tudaexercise.cls
-2021/05/18 | 3206268 | systems/texlive/tlnet/archive/luatexja.doc.r59248.tar.xz
2021/05/18 | 319277 | systems/win32/miktex/tm/packages/xetexko.tar.lzma
2021/05/18 | 3175 | macros/latex/contrib/tuda-ci/example/DEMO-TUDaAnnouncement.tex
2021/05/18 | 315801 | macros/latex/contrib/alterqcm/doc/doc-aq-main.pdf
@@ -790,7 +1311,6 @@
2021/05/18 | 196590 | macros/latex/contrib/apa7/samples/longsample.pdf
2021/05/18 | 1950018 | systems/win32/miktex/tm/packages/pgf-spectra.tar.lzma
2021/05/18 | 193058 | systems/win32/miktex/tm/packages/mindflow.tar.lzma
-2021/05/18 | 189956 | systems/texlive/tlnet/archive/luatexja.r59248.tar.xz
2021/05/18 | 18778 | macros/latex/contrib/tuda-ci/tex/tudasciposter.cls
2021/05/18 | 1768532 | systems/texlive/tlnet/archive/pgfplots.source.r59243.tar.xz
2021/05/18 | 1748 | macros/latex/contrib/hvqrurl/latex/hvqrurl.sty
@@ -830,7 +1350,6 @@
2021/05/18 | 130712608 | systems/win32/w32tex/web2c-lib.tar.xz
2021/05/18 | 1278 | macros/latex/contrib/apa7/README.txt
2021/05/18 | 126693 | systems/win32/miktex/tm/packages/tiscreen.tar.lzma
-2021/05/18 | 123964 | systems/texlive/tlnet/archive/tiscreen.doc.r59247.tar.xz
2021/05/18 | 1210104 | systems/texlive/tlnet/archive/tex4ht.source.r59249.tar.xz
2021/05/18 | 117951 | systems/win32/miktex/tm/packages/lua-ul.tar.lzma
2021/05/18 | 1178317 | language/japanese/BX/bxjscls/bxjscls.pdf
@@ -969,7 +1488,6 @@
2021/05/16 | 11516 | systems/texlive/tlnet/tlpkg/TeXLive/TLConfig.pm
2021/05/16 | 11502 | systems/texlive/tlnet/tlpkg/TeXLive/TeXCatalogue.pm
2021/05/16 | 1143 | macros/latex/contrib/paresse/README.md
-2021/05/16 | 11424 | fonts/newtx/tex/newtxtext.sty
2021/05/16 | 1091266 | support/TeX4ht/source/tex4ht-4ht.tex
2021/05/16 | 10700492 | systems/win32/w32tex/ptex-w32.tar.xz
2021/05/16 | 10547 | usergrps/usergrps/de.html
@@ -995,1119 +1513,3 @@
2021/05/16 | 10038 | usergrps/usergrps/no.html
2021/05/16 | 10011 | usergrps/usergrps/br.html
2021/05/16 | 10000 | usergrps/usergrps/labels.pdf
-2021/05/15 | 9989 | graphics/pgf/base/tex/pgfmathfunctions.code.tex
-2021/05/15 | 997 | graphics/pgf/base/tex/tikzlibrarydatavisualization.barcharts.code.tex
-2021/05/15 | 9975 | graphics/pgf/base/tex/pgfutil-plain.def
-2021/05/15 | 992 | graphics/pgf/base/tex/pgfcore.code.tex
-2021/05/15 | 989 | graphics/pgf/base/tex/pgfcomp-version-1-18.sty
-2021/05/15 | 989 | graphics/pgf/base/source/RandomPlacer_script.h
-2021/05/15 | 9893 | graphics/pgf/base/lua/graphdrawing/pgf/gd/bindings/BindingToPGF.lua
-2021/05/15 | 98820 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-shapes.tex
-2021/05/15 | 982 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/NodeRankingMinimumHeight.lua
-2021/05/15 | 9829 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-backgrounds.tex
-2021/05/15 | 981 | graphics/pgf/base/tex/tikzlibraryscopes.code.tex
-2021/05/15 | 981 | graphics/pgf/base/source/RandomMerger_script.h
-2021/05/15 | 976 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Stack.lua
-2021/05/15 | 974 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua
-2021/05/15 | 973 | graphics/pgf/base/source/InterfaceFromOGDF.h
-2021/05/15 | 973 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua
-2021/05/15 | 970 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/ASCIIDisplayer.lua
-2021/05/15 | 969 | graphics/pgf/base/doc/version-for-dvipdfmx/en/Makefile
-2021/05/15 | 9690 | graphics/pgf/base/tex/pgfcorepatterns.code.tex
-2021/05/15 | 968 | graphics/pgf/base/source/ZeroPlacer_script.h
-2021/05/15 | 968 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua
-2021/05/15 | 968 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-trees.tex
-2021/05/15 | 967 | graphics/pgf/base/lua/graphdrawing/pgf/gd/deprecated/Cluster.lua
-2021/05/15 | 9652 | graphics/pgf/base/lua/graphdrawing/pgf/gd/deprecated/Graph.lua
-2021/05/15 | 9631 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-binding-layer.tex
-2021/05/15 | 962 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua
-2021/05/15 | 9614 | graphics/pgf/base/tex/tikzlibrarycircuits.ee.IEC.code.tex
-2021/05/15 | 954 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua
-2021/05/15 | 953 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua
-2021/05/15 | 95375 | graphics/pgf/base/tex/pgfmoduledatavisualization.code.tex
-2021/05/15 | 9532 | language/japanese/plautopatch/plautopatch.sty
-2021/05/15 | 952 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua
-2021/05/15 | 95278 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfmathfloat.code.tex
-2021/05/15 | 950 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-layered.tex
-2021/05/15 | 94973 | language/japanese/plautopatch/plautopatch-ja.pdf
-2021/05/15 | 948 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua
-2021/05/15 | 946 | graphics/pgf/contrib/pgfplots/doc/pgfplotsexample-plain.tex
-2021/05/15 | 946 | graphics/pgf/contrib/pgfplots/doc/pgfplotsexample-context.tex
-2021/05/15 | 946 | graphics/pgf/base/tex/tikzlibrarycircuits.logic.code.tex
-2021/05/15 | 946 | graphics/pgf/base/lua/graphdrawing/pgf/gd/trees/library.lua
-2021/05/15 | 93 | graphics/pgf/base/doc/licenses/manifest-documentation.txt
-2021/05/15 | 93853 | graphics/pgf/base/tex/tikzlibrarydatavisualization.code.tex
-2021/05/15 | 93690 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-circuits.tex
-2021/05/15 | 934 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/library.lua
-2021/05/15 | 931 | language/japanese/plautopatch/plarydshln.sty
-2021/05/15 | 931 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/library.lua
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-exp.gnuplot
-2021/05/15 | 92 | graphics/pgf/base/doc/text-en/plots/pgf-exp.gnuplot
-2021/05/15 | 926 | graphics/pgf/base/tex/pgf.cfg
-2021/05/15 | 926 | graphics/pgf/base/lua/graphdrawing/pgf/gd/ogdf/library.lua
-2021/05/15 | 92405 | graphics/pgf/base/tex/pgfmathfunctions.trigonometric.code.tex
-2021/05/15 | 9212 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfsys-paths.tex
-2021/05/15 | 919 | graphics/pgf/base/tex/tikzlibraryshapes.multipart.code.tex
-2021/05/15 | 91587 | graphics/pgf/base/tex/pgflibraryshapes.arrows.code.tex
-2021/05/15 | 913 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplotsclickable.code.tex
-2021/05/15 | 91244 | graphics/pgf/contrib/pgfplots/tex/pgfplotsticks.code.tex
-2021/05/15 | 911 | graphics/pgf/base/tex/tikzlibrarysvg.path.code.tex
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 90 | graphics/pgf/base/doc/text-en/plots/pgfplotgnuplot-example.gnuplot
-2021/05/15 | 909 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua
-2021/05/15 | 90515 | graphics/pgf/base/tex/pgflibraryshapes.symbols.code.tex
-2021/05/15 | 9047 | language/japanese/plautopatch/plautopatch-ja.tex
-2021/05/15 | 89878 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-decorations.tex
-2021/05/15 | 89737 | graphics/pgf/base/doc/images/pgfmanual-mindmap-2.pdf
-2021/05/15 | 8907 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua
-2021/05/15 | 88 | graphics/pgf/base/doc/licenses/manifest-code.txt
-2021/05/15 | 88956 | graphics/pgf/contrib/pgfplots/tex/pgfplotscolormap.code.tex
-2021/05/15 | 8893 | graphics/pgf/base/tex/pgfcoretransparency.code.tex
-2021/05/15 | 8843 | graphics/pgf/base/tex/pgflibrarydecorations.pathmorphing.code.tex
-2021/05/15 | 882 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarydateplot.code.tex
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/text-en/plots/pgf-sin.gnuplot
-2021/05/15 | 87 | graphics/pgf/base/doc/text-en/plots/pgfmanual-sine.gnuplot
-2021/05/15 | 878372 | systems/texlive/tlnet/archive/beebe.r59190.tar.xz
-2021/05/15 | 8766 | graphics/pgf/contrib/pgfplots/tex/meshplothandler.lua
-2021/05/15 | 873 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/List.lua
-2021/05/15 | 873 | graphics/pgf/base/doc/version-for-pdftex/en/Makefile
-2021/05/15 | 873 | graphics/pgf/base/doc/version-for-luatex/en/Makefile
-2021/05/15 | 8724 | graphics/pgf/base/tex/tikzlibrarycircuits.code.tex
-2021/05/15 | 8708 | systems/texlive/tlnet/archive/vancouver.r59192.tar.xz
-2021/05/15 | 8697 | graphics/pgf/contrib/pgfplots/scripts/matlab2pgfplots.m
-2021/05/15 | 868851 | macros/latex/contrib/tagpdf.zip
-2021/05/15 | 86658 | graphics/pgf/base/tex/tikzlibrarygraphs.code.tex
-2021/05/15 | 8612 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_leq.code.tex
-2021/05/15 | 8612 | graphics/pgf/base/lua/graphdrawing/pgf/gd/deprecated/Edge.lua
-2021/05/15 | 8605 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Path_arced.lua
-2021/05/15 | 85938 | graphics/pgf/base/tex/pgflibraryfpu.code.tex
-2021/05/15 | 85454 | graphics/pgf/base/tex/pgflibraryshapes.gates.logic.US.code.tex
-2021/05/15 | 853 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua
-2021/05/15 | 8521 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.dateplot.code.tex
-2021/05/15 | 8471 | graphics/pgf/base/tex/pgfmathutil.code.tex
-2021/05/15 | 8444 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/SimpleHuffman.lua
-2021/05/15 | 8432 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/SokalMichener1958.lua
-2021/05/15 | 83469 | graphics/pgf/contrib/pgfplots/tex/pgfplotstableshared.code.tex
-2021/05/15 | 831 | graphics/pgf/base/source/BalloonLayout_script.h
-2021/05/15 | 8269 | graphics/pgf/base/doc/text-en/pgfmanual-en-math-commands.tex
-2021/05/15 | 8251 | graphics/pgf/base/tex/pgflibrarylindenmayersystems.code.tex
-2021/05/15 | 823 | graphics/pgf/base/source/energybased_script.h
-2021/05/15 | 823 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua
-2021/05/15 | 8196 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/base/CoarseGraphFW.lua
-2021/05/15 | 813 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-edge-routing.tex
-2021/05/15 | 8115 | graphics/pgf/contrib/pgfplots/scripts/pgf2pdf.sh
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-x.gnuplot
-2021/05/15 | 80 | graphics/pgf/base/doc/text-en/plots/pgf-x.gnuplot
-2021/05/15 | 802 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/library.lua
-2021/05/15 | 8022 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.fillbetween.code.tex
-2021/05/15 | 8008 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfutil-common-lists.tex
-2021/05/15 | 7987 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-shadings.tex
-2021/05/15 | 796 | graphics/pgf/base/tex/t-pgfsys.tex
-2021/05/15 | 795 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-misc.tex
-2021/05/15 | 7936 | graphics/pgf/base/tex/pgflibrarypatterns.code.tex
-2021/05/15 | 7924 | systems/texlive/tlnet/archive/changes.r59198.tar.xz
-2021/05/15 | 791 | graphics/pgf/base/tex/t-tikz.tex
-2021/05/15 | 7902 | language/japanese/plautopatch/plautopatch.tex
-2021/05/15 | 788 | graphics/pgf/base/tex/tikzlibrarydecorations.markings.code.tex
-2021/05/15 | 78889 | language/japanese/platex-tools/plextarray.pdf
-2021/05/15 | 787 | graphics/pgf/base/tex/t-pgfrcs.tex
-2021/05/15 | 78671 | graphics/pgf/base/doc/images/brave-gnu-world-logo.jpg
-2021/05/15 | 785 | graphics/pgf/base/doc/version-for-luatex/en/pgfmanual.tex
-2021/05/15 | 7854 | graphics/pgf/base/tex/pgfmathfunctions.random.code.tex
-2021/05/15 | 782 | graphics/pgf/base/tex/LUA_CODING_STYLE
-2021/05/15 | 7778 | graphics/pgf/base/tex/pgfsyssoftpath.code.tex
-2021/05/15 | 7763 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-folding.tex
-2021/05/15 | 771 | graphics/pgf/base/doc/version-for-tex4ht/en/Makefile
-2021/05/15 | 770 | graphics/pgf/base/tex/tikzlibrarypatterns.code.tex
-2021/05/15 | 76 | graphics/pgf/base/doc/RELEASE_NOTES.md
-2021/05/15 | 7692 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-introduction.tex
-2021/05/15 | 76734 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgflibraryfpu.code.tex
-2021/05/15 | 7646 | graphics/pgf/base/tex/tikzlibraryrdf.code.tex
-2021/05/15 | 74959 | graphics/pgf/base/tex/tikzlibraryfolding.code.tex
-2021/05/15 | 747 | graphics/pgf/base/source/MakefileConfig.mk
-2021/05/15 | 7474 | graphics/pgf/base/tex/pgflibrarydecorations.pathreplacing.code.tex
-2021/05/15 | 7412 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-3d.tex
-2021/05/15 | 73 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar.lua
-2021/05/15 | 7390 | graphics/pgf/base/doc/text-en/pgfmanual-en-installation.tex
-2021/05/15 | 734 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua
-2021/05/15 | 7327 | graphics/pgf/base/tex/pgfautomata.sty
-2021/05/15 | 73216 | language/japanese/platex-tools/pxatbegshi.pdf
-2021/05/15 | 731 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua
-2021/05/15 | 730 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua
-2021/05/15 | 72 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/library.lua
-2021/05/15 | 729 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua
-2021/05/15 | 7275 | graphics/pgf/base/tex/tikzlibrarygraphdrawing.code.tex
-2021/05/15 | 7256 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-arrows.tex
-2021/05/15 | 7251 | graphics/pgf/base/tex/pgfutil-common-lists.tex
-2021/05/15 | 724 | graphics/pgf/base/tex/t-pgfmat.tex
-2021/05/15 | 724361 | graphics/pgf/contrib/pgfplots/source/pgfplotstests.context.tar.bz2
-2021/05/15 | 7235 | graphics/pgf/base/tex/pgflibrarydatavisualization.polar.code.tex
-2021/05/15 | 722 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua
-2021/05/15 | 720 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua
-2021/05/15 | 71792 | graphics/pgf/contrib/pgfplots/tex/pgfplotsutil.code.tex
-2021/05/15 | 71722 | graphics/pgf/base/tex/pgfmoduledecorations.code.tex
-2021/05/15 | 7167 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/Orientation.lua
-2021/05/15 | 7163 | graphics/pgf/base/lua/graphdrawing/pgf/gd/trees/ChildSpec.lua
-2021/05/15 | 714 | graphics/pgf/base/doc/version-for-xetex/en/Makefile
-2021/05/15 | 713 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-backend.tex
-2021/05/15 | 708 | graphics/pgf/base/tex/tikzlibraryshadings.code.tex
-2021/05/15 | 701 | graphics/pgf/base/doc/version-for-dvipdfm/en/Makefile
-2021/05/15 | 7011 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/QuadTree.lua
-2021/05/15 | 6995 | graphics/pgf/base/tex/pgflibrarytimelines.code.tex
-2021/05/15 | 6958 | graphics/pgf/base/tex/pgfmathode.code.tex
-2021/05/15 | 69566 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeys.tex
-2021/05/15 | 6944 | graphics/pgf/base/tex/pgfcoreimage.code.tex
-2021/05/15 | 691 | graphics/pgf/base/tex/t-pgfcal.tex
-2021/05/15 | 68833 | graphics/pgf/base/tex/tikzexternalshared.code.tex
-2021/05/15 | 6846 | graphics/pgf/base/tex/pgflibraryarrows.spaced.code.tex
-2021/05/15 | 6825 | graphics/pgf/base/tex/pgfutil-latex.def
-2021/05/15 | 6810 | graphics/pgf/base/tex/tikzlibrarychains.code.tex
-2021/05/15 | 6774 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/Ranking.lua
-2021/05/15 | 6762 | graphics/pgf/base/tex/pgfsys-common-pdf-via-dvi.def
-2021/05/15 | 6734916 | systems/texlive/tlnet/archive/pdfmanagement-testphase.doc.r59194.tar.xz
-2021/05/15 | 668 | graphics/pgf/base/doc/version-for-vtex/en/Makefile
-2021/05/15 | 666 | graphics/pgf/base/tex/t-pgffor.tex
-2021/05/15 | 6661 | graphics/pgf/base/lua/graphdrawing/pgf/gd/bindings/Binding.lua
-2021/05/15 | 665 | graphics/pgf/base/doc/version-for-dvisvgm/en/pgfmanual-test.tex
-2021/05/15 | 663 | graphics/pgf/base/source/MedianPlacer_script.h
-2021/05/15 | 6616 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-trees.tex
-2021/05/15 | 66153 | graphics/pgf/base/doc/text-en/pgfmanual-en-license.tex
-2021/05/15 | 6593 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-fit.tex
-2021/05/15 | 658 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-circular.tex
-2021/05/15 | 655 | graphics/pgf/base/source/SolarPlacer_script.h
-2021/05/15 | 6550 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Coordinate.lua
-2021/05/15 | 653361 | macros/latex/contrib/pm-isomath/pm-isomath.pdf
-2021/05/15 | 6529 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/doc.lua
-2021/05/15 | 6521 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.pgfsys-dvipdfmx.def
-2021/05/15 | 64927 | language/japanese/platex-tools/plextdelarray.pdf
-2021/05/15 | 64209 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.smithchart.code.tex
-2021/05/15 | 6364 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-quick.tex
-2021/05/15 | 63453 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_tikzexternalshared.code.tex
-2021/05/15 | 633 | graphics/pgf/base/tex/t-pgfkey.tex
-2021/05/15 | 632 | graphics/pgf/base/tex/tikzlibrarydatavisualization.sparklines.code.tex
-2021/05/15 | 63197 | graphics/pgf/base/doc/images/brave-gnu-world-logo.eps
-2021/05/15 | 630 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/SpringLayouts.lua
-2021/05/15 | 6265 | graphics/pgf/base/lua/graphdrawing/pgf/gd/deprecated/Node.lua
-2021/05/15 | 62618 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfsys-animations.tex
-2021/05/15 | 6254 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Collection.lua
-2021/05/15 | 625096 | systems/texlive/tlnet/archive/pdfextra.doc.r59204.tar.xz
-2021/05/15 | 62448 | graphics/pgf/base/tex/pgfsys-common-svg.def
-2021/05/15 | 6231 | language/japanese/platex-tools/pxeverysel.sty
-2021/05/15 | 62281 | graphics/pgf/base/tex/pgflibraryshapes.multipart.code.tex
-2021/05/15 | 6223 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/PriorityQueue.lua
-2021/05/15 | 6218 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.pgfsys-luatex.def
-2021/05/15 | 620 | graphics/pgf/base/lua/graphdrawing/pgf/gd/circular/library.lua
-2021/05/15 | 6189 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-design.tex
-2021/05/15 | 61664 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-animations.tex
-2021/05/15 | 61358 | graphics/pgf/base/doc/text-en/pgfmanual-en-tutorial-map.tex
-2021/05/15 | 612536 | graphics/pgf/contrib/pgfplots/doc/pgfplotstable.pdf
-2021/05/15 | 61163 | graphics/pgf/base/tex/pgfsys.code.tex
-2021/05/15 | 61132 | language/japanese/platex-tools/pxeverysel.pdf
-2021/05/15 | 607 | language/japanese/platex-tools/pxmulticol.sty
-2021/05/15 | 606125 | language/japanese/platex-tools.zip
-2021/05/15 | 60485 | graphics/pgf/base/doc/images/brave-gnu-world-logo-mask.jpg
-2021/05/15 | 6038 | graphics/pgf/base/tex/pgfcoregraphicstate.code.tex
-2021/05/15 | 6017 | graphics/pgf/base/tex/pgflibrarydatavisualization.formats.functions.code.tex
-2021/05/15 | 6007 | graphics/pgf/contrib/pgfplots/tex/streamer.lua
-2021/05/15 | 5997 | graphics/pgf/contrib/pgfplots/tex/pgfregressiontest.sty
-2021/05/15 | 5984 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Simplifiers.lua
-2021/05/15 | 597 | graphics/pgf/base/lua/graphdrawing/pgf/gd/routing/library.lua
-2021/05/15 | 596 | graphics/pgf/base/doc/description.html
-2021/05/15 | 59652 | graphics/pgf/base/tex/pgfsysanimations.code.tex
-2021/05/15 | 5923 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Edge.lua
-2021/05/15 | 591 | graphics/pgf/base/source/GreedyInsertHeuristic_script.h
-2021/05/15 | 59122 | graphics/pgf/base/doc/text-en/pgfmanual-en-tutorial.tex
-2021/05/15 | 590 | graphics/pgf/base/tex/tikzlibrarycircuits.logic.CDH.code.tex
-2021/05/15 | 5907 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.pgfsys-pdftex.def
-2021/05/15 | 5902 | language/japanese/platex-tools/plextarray.tex
-2021/05/15 | 58960 | macros/latex/contrib/pm-isomath/pm-isomath.dtx
-2021/05/15 | 58801 | graphics/pgf/base/tex/pgflibraryarrows.meta.code.tex
-2021/05/15 | 586 | graphics/pgf/base/source/module_script.h
-2021/05/15 | 58689 | language/japanese/platex-tools/plarray.pdf
-2021/05/15 | 5849 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-fixedpoint.tex
-2021/05/15 | 577 | graphics/pgf/base/source/BarycenterHeuristic_script.h
-2021/05/15 | 57673 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-paths.tex
-2021/05/15 | 5766 | dviware/dviinfox.zip
-2021/05/15 | 57602 | graphics/pgf/base/doc/FILES
-2021/05/15 | 575 | graphics/pgf/base/source/GreedyCycleRemoval_script.h
-2021/05/15 | 575 | graphics/pgf/base/source/DfsAcyclicSubgraph_script.h
-2021/05/15 | 57538 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfsys-commands.tex
-2021/05/15 | 57255 | graphics/pgf/base/tex/pgfmanual-en-macros.tex
-2021/05/15 | 5712 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_tikzexternal.sty
-2021/05/15 | 57081 | graphics/pgf/base/doc/images/brave-gnu-world-logo.25.jpg
-2021/05/15 | 5693 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/algorithms/SocialGravityDegree.lua
-2021/05/15 | 5641 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfcorelayers.code.tex
-2021/05/15 | 561 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-parametric-example.table
-2021/05/15 | 561 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-parametric-example-cut.table
-2021/05/15 | 561 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-parametric-example.table
-2021/05/15 | 561 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-parametric-example-cut.table
-2021/05/15 | 56043 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-nodes.tex
-2021/05/15 | 5601 | graphics/pgf/base/lua/graphdrawing/pgf/gd/deprecated/Vector.lua
-2021/05/15 | 5573 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/PathLengths.lua
-2021/05/15 | 5546 | graphics/pgf/base/tex/pgfsys-common-pdf.def
-2021/05/15 | 553 | graphics/pgf/base/source/ogdf_script.c++
-2021/05/15 | 5515 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-layers.tex
-2021/05/15 | 5510 | graphics/pgf/base/tex/pgfsys-dvisvgm.def
-2021/05/15 | 549 | graphics/pgf/base/source/MedianHeuristic_script.h
-2021/05/15 | 5493 | graphics/pgf/base/tex/tikzlibrarydecorations.code.tex
-2021/05/15 | 5479 | language/japanese/plautopatch/plcollcell.sty
-2021/05/15 | 544 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-sin.table
-2021/05/15 | 544 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-sin.table
-2021/05/15 | 54438 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-actions.tex
-2021/05/15 | 543 | graphics/pgf/base/tex/t-pgf.tex
-2021/05/15 | 543 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-exp.table
-2021/05/15 | 543 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-exp.table
-2021/05/15 | 542 | graphics/pgf/base/source/SplitHeuristic_script.h
-2021/05/15 | 541 | graphics/pgf/base/source/tikzexternaltest.sharedpreamble.tex
-2021/05/15 | 5401 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/forcetypes/ForceGraphDistance.lua
-2021/05/15 | 5400 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/NodeAnchors.lua
-2021/05/15 | 5364 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/Components.lua
-2021/05/15 | 5364 | graphics/pgf/base/doc/extract.lua
-2021/05/15 | 534 | graphics/pgf/base/doc/version-for-dvipdfmx/en/pgfmanual-test.tex
-2021/05/15 | 533 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-x.table
-2021/05/15 | 533 | graphics/pgf/base/doc/version-for-luatex/en/pgfmanual-test.tex
-2021/05/15 | 533 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-x.table
-2021/05/15 | 532 | graphics/pgf/base/tex/tikzlibrarygraphdrawing.evolving.code.tex
-2021/05/15 | 532 | graphics/pgf/base/doc/version-for-dvips/en/pgfmanual-test.tex
-2021/05/15 | 5297 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/library.lua
-2021/05/15 | 5292 | graphics/pgf/base/tex/tikzexternal.sty
-2021/05/15 | 5287 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/GreedyTemporalCycleRemoval.lua
-2021/05/15 | 5286 | graphics/pgf/base/tex/tikzlibraryintersections.code.tex
-2021/05/15 | 52774 | language/japanese/platex-tools/pxftnright.pdf
-2021/05/15 | 52720 | language/japanese/platex-tools/pxeveryshi.pdf
-2021/05/15 | 5258 | graphics/pgf/base/lua/graphdrawing/pgf/gd/interface/InterfaceCore.lua
-2021/05/15 | 5251 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-views.tex
-2021/05/15 | 523 | graphics/pgf/base/tex/pgfsys.tex
-2021/05/15 | 5227 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua
-2021/05/15 | 52250 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-coordinates.tex
-2021/05/15 | 5222 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/SupergraphVertexSplitOptimization.lua
-2021/05/15 | 5220 | graphics/pgf/base/tex/pgflibrarydecorations.markings.code.tex
-2021/05/15 | 521 | graphics/pgf/base/tex/pgfmath.code.tex
-2021/05/15 | 5214 | graphics/pgf/base/lua/graphdrawing/pgf/gd/trees/ReingoldTilford1981.lua
-2021/05/15 | 520 | graphics/pgf/contrib/pgfplots/tex/pgfplots.revision.tex
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-parametric-example.table
-2021/05/15 | 520 | graphics/pgf/base/doc/text-en/plots/pgf-parametric-example.table
-2021/05/15 | 5204 | graphics/pgf/base/source/InterfaceFromC++.c++
-2021/05/15 | 5196 | graphics/pgf/base/tex/pgfcorerdf.code.tex
-2021/05/15 | 517 | graphics/pgf/base/tex/pgflibraryshapes.code.tex
-2021/05/15 | 51720 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.clickable.code.tex
-2021/05/15 | 5149 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/ControlCoarsening.lua
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-sin.table
-2021/05/15 | 513 | graphics/pgf/base/doc/text-en/plots/pgf-sin.table
-2021/05/15 | 5082 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/base/PathLengthsFW.lua
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-exp.table
-2021/05/15 | 507 | graphics/pgf/base/doc/text-en/plots/pgf-x.table
-2021/05/15 | 507 | graphics/pgf/base/doc/text-en/plots/pgf-exp.table
-2021/05/15 | 50671 | graphics/pgf/base/tex/pgfmanual.prettyprinter.code.tex
-2021/05/15 | 5059 | language/japanese/platex-tools/plextdelarray.tex
-2021/05/15 | 503 | graphics/pgf/base/tex/pgf.tex
-2021/05/15 | 5026 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_tikzlibraryexternal.code.tex
-2021/05/15 | 50179 | graphics/pgf/base/doc/images/brave-gnu-world-logo.25.eps
-2021/05/15 | 499 | graphics/pgf/base/tex/pgflibrarysnakes.code.tex
-2021/05/15 | 496 | graphics/pgf/base/doc/version-for-luatex/pgfmanual-luatex.cfg
-2021/05/15 | 494 | graphics/pgf/base/tex/tikzlibraryshapes.code.tex
-2021/05/15 | 49471 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-external.tex
-2021/05/15 | 493 | graphics/pgf/base/tex/pgflibrarygraphdrawing.trees.code.tex
-2021/05/15 | 4937 | graphics/pgf/base/lua/graphdrawing/pgf/gd/tools/make_gd_wrap.lua
-2021/05/15 | 491 | graphics/pgf/base/doc/version-for-dvipdfmx/pgfmanual-dvipdfmx.cfg
-2021/05/15 | 4919 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-internalregisters.tex
-2021/05/15 | 490 | graphics/pgf/base/doc/version-for-pdftex/pgfmanual-pdftex.cfg
-2021/05/15 | 4904 | graphics/pgf/contrib/pgfplots/tex/pgfplots.sty
-2021/05/15 | 4883 | graphics/pgf/base/tex/pgfcorelayers.code.tex
-2021/05/15 | 4878 | graphics/pgf/base/tex/pgflibraryshapes.gates.ee.code.tex
-2021/05/15 | 4876 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-ogdf.tex
-2021/05/15 | 4865 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-er.tex
-2021/05/15 | 485 | graphics/pgf/base/tex/pgfbasesnakes.tex
-2021/05/15 | 4855 | graphics/pgf/base/tex/pgflibrarydatavisualization.barcharts.code.tex
-2021/05/15 | 485274 | graphics/pgf/contrib/pgfplots/tex/pgfplots.code.tex
-2021/05/15 | 48509 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-transformations.tex
-2021/05/15 | 475 | graphics/pgf/base/tex/tikzlibraryshapes.symbols.code.tex
-2021/05/15 | 475 | graphics/pgf/base/tex/pgfbaseshapes.tex
-2021/05/15 | 475 | graphics/pgf/base/tex/pgfbasematrix.tex
-2021/05/15 | 4696 | systems/texlive/tlnet/archive/noindentafter.source.r59195.tar.xz
-2021/05/15 | 46825 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-arrows.tex
-2021/05/15 | 467 | graphics/pgf/base/tex/pgfbaseplot.tex
-2021/05/15 | 465 | graphics/pgf/base/tex/pgf.revision.tex
-2021/05/15 | 46361 | graphics/pgf/contrib/pgfplots/tex/pgflibraryfillbetween.code.tex
-2021/05/15 | 462 | graphics/pgf/base/tex/pgfrcs.tex
-2021/05/15 | 46241 | graphics/pgf/base/tex/pgflibraryshapes.misc.code.tex
-2021/05/15 | 46142 | graphics/pgf/base/doc/text-en/pgfmanual-en-tutorial-chains.tex
-2021/05/15 | 4611 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/algorithms/SocialGravityCloseness.lua
-2021/05/15 | 458 | graphics/pgf/base/doc/version-for-dvisvgm/en/pgfmanual.tex
-2021/05/15 | 457 | graphics/pgf/base/tex/t-pgfbim.tex
-2021/05/15 | 4572 | graphics/pgf/base/tex/tikzlibrarybackgrounds.code.tex
-2021/05/15 | 456 | graphics/pgf/base/doc/version-for-dvipdfm/pgfmanual-dvipdfm.cfg
-2021/05/15 | 455 | graphics/pgf/base/doc/version-for-xetex/pgfmanual-xetex.cfg
-2021/05/15 | 45551 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-rdf.tex
-2021/05/15 | 4513 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered.lua
-2021/05/15 | 450 | graphics/pgf/base/doc/version-for-dvipdfmx/en/pgfmanual.tex
-2021/05/15 | 449 | graphics/pgf/base/doc/version-for-dvipdfm/en/pgfmanual.tex
-2021/05/15 | 4494 | graphics/pgf/base/tex/pgfrcs.code.tex
-2021/05/15 | 448 | graphics/pgf/base/tex/tikz.tex
-2021/05/15 | 448 | graphics/pgf/base/doc/version-for-xetex/en/pgfmanual.tex
-2021/05/15 | 448 | graphics/pgf/base/doc/version-for-pdftex/en/pgfmanual.tex
-2021/05/15 | 448 | graphics/pgf/base/doc/version-for-dvips/en/pgfmanual.tex
-2021/05/15 | 447 | graphics/pgf/base/doc/version-for-vtex/en/pgfmanual.tex
-2021/05/15 | 44784 | graphics/pgf/base/tex/pgfmoduleshapes.code.tex
-2021/05/15 | 4477 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/library.lua
-2021/05/15 | 4474 | graphics/pgf/base/doc/text-en/pgfmanual-en-math-design.tex
-2021/05/15 | 44571 | graphics/pgf/base/tex/pgflibraryintersections.code.tex
-2021/05/15 | 4445 | graphics/pgf/base/source/GEMLayout_script.h
-2021/05/15 | 443 | graphics/pgf/base/tex/pgfsys.sty
-2021/05/15 | 442 | graphics/pgf/base/lua/graphdrawing/pgf/gd/pedigrees/library.lua
-2021/05/15 | 44195 | graphics/pgf/base/tex/pgfcorepathconstruct.code.tex
-2021/05/15 | 4415 | graphics/pgf/base/source/InterfaceFromC++.h
-2021/05/15 | 44150 | language/japanese/platex-tools/pxmulticol.pdf
-2021/05/15 | 440 | graphics/pgf/base/doc/version-for-tex4ht/en/pgfmanual.tex
-2021/05/15 | 4404 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Bezier.lua
-2021/05/15 | 43904 | graphics/pgf/base/doc/text-en/pgfmanual-en-tutorial-nodes.tex
-2021/05/15 | 43831 | graphics/pgf/base/doc/text-en/pgfmanual-en-math-parsing.tex
-2021/05/15 | 43820 | graphics/pgf/base/tex/pgfcorearrows.code.tex
-2021/05/15 | 437 | graphics/pgf/base/tex/pgfarrows.sty
-2021/05/15 | 4375 | graphics/pgf/base/tex/tikzlibrarypetri.code.tex
-2021/05/15 | 4363 | graphics/pgf/base/lua/graphdrawing/pgf/gd/circular/doc.lua
-2021/05/15 | 435 | graphics/pgf/base/tex/pgfshade.sty
-2021/05/15 | 435 | graphics/pgf/base/tex/pgfbasepatterns.tex
-2021/05/15 | 43551 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-decorations.tex
-2021/05/15 | 434 | graphics/pgf/base/tex/pgfnodes.sty
-2021/05/15 | 4344 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.external.code.tex
-2021/05/15 | 432 | graphics/pgf/base/tex/pgfmath.tex
-2021/05/15 | 432 | graphics/pgf/base/tex/pgfcore.tex
-2021/05/15 | 4326 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/PlanarLayout.lua
-2021/05/15 | 431 | graphics/pgf/base/tex/pgfbaselayers.tex
-2021/05/15 | 4310 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.pgfsys-dvips.def
-2021/05/15 | 430 | graphics/pgf/base/tex/pgflibrarygraphdrawing.circular.code.tex
-2021/05/15 | 429 | graphics/pgf/base/tex/pgfbaseimage.tex
-2021/05/15 | 42966 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfmanual.prettyprinter.code.tex
-2021/05/15 | 4294 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-babel.tex
-2021/05/15 | 4288 | graphics/pgf/contrib/pgfplots/tex/pgfplotsdeque.code.tex
-2021/05/15 | 4285 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/ComponentDistance.lua
-2021/05/15 | 42816 | systems/texlive/tlnet/archive/pdfmanagement-testphase.r59194.tar.xz
-2021/05/15 | 42715 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.statistics.code.tex
-2021/05/15 | 4269 | graphics/pgf/contrib/pgfplots/tex/colormap.lua
-2021/05/15 | 4253 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/cycle_removal.lua
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgfmanual-sine.table
-2021/05/15 | 421 | graphics/pgf/base/doc/text-en/plots/pgfmanual-sine.table
-2021/05/15 | 4202 | graphics/pgf/base/tex/tikzlibrarymatrix.code.tex
-2021/05/15 | 4188 | language/japanese/platex-tools/pxatbegshi.sty
-2021/05/15 | 417 | graphics/pgf/base/doc/version-for-vtex/pgfmanual-vtex.cfg
-2021/05/15 | 4177 | graphics/pgf/base/tex/tikzlibrarycircuits.ee.code.tex
-2021/05/15 | 416 | graphics/pgf/base/tex/pgflibraryplothandlers.sty
-2021/05/15 | 415 | graphics/pgf/base/tex/pgflibrarytikzbackgrounds.sty
-2021/05/15 | 4156 | graphics/pgf/base/lua/graphdrawing/pgf/gd/circular/Tantau2012.lua
-2021/05/15 | 4151 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/GEMLayout.lua
-2021/05/15 | 414 | graphics/pgf/base/tex/tikzlibrarydatavisualization.formats.functions.code.tex
-2021/05/15 | 411 | graphics/pgf/base/tex/pgflibraryautomata.sty
-2021/05/15 | 41155 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-scopes.tex
-2021/05/15 | 41150 | graphics/pgf/base/source/pgfmathtestsuite.tex
-2021/05/15 | 410 | graphics/pgf/base/tex/tikzlibraryshapes.arrows.code.tex
-2021/05/15 | 410 | graphics/pgf/base/tex/pgflibraryplotmarks.sty
-2021/05/15 | 410 | graphics/pgf/base/tex/pgfcore.sty
-2021/05/15 | 4100 | graphics/pgf/base/tex/tikzlibraryexternal.code.tex
-2021/05/15 | 4099 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/FineTune.lua
-2021/05/15 | 407 | macros/latex/contrib/pm-isomath/README.txt
-2021/05/15 | 4076 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/base/Preprocessing.lua
-2021/05/15 | 4073 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua
-2021/05/15 | 405 | graphics/pgf/base/tex/pgflibraryshapes.sty
-2021/05/15 | 4058 | graphics/pgf/base/tex/tikzlibraryspy.code.tex
-2021/05/15 | 4051 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-angles.tex
-2021/05/15 | 404 | graphics/pgf/base/tex/t-pgfbsn.tex
-2021/05/15 | 404 | graphics/pgf/base/tex/pgflibrarysnakes.sty
-2021/05/15 | 403 | graphics/pgf/base/tex/pgflibraryarrows.sty
-2021/05/15 | 402 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua
-2021/05/15 | 400 | graphics/pgf/base/tex/pgflibrarytikztrees.sty
-2021/05/15 | 3998 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3998 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 399864 | systems/texlive/tlnet/archive/noindentafter.doc.r59195.tar.xz
-2021/05/15 | 398 | graphics/pgf/base/tex/pgfbasesnakes.sty
-2021/05/15 | 3986 | graphics/pgf/base/tex/tikzlibraryautomata.code.tex
-2021/05/15 | 39858 | language/japanese/plautopatch/plautopatch.pdf
-2021/05/15 | 3969 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua
-2021/05/15 | 3968 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-turtle.tex
-2021/05/15 | 3964 | language/japanese/platex-tools/pxatbegshi.tex
-2021/05/15 | 39636 | graphics/pgf/base/tex/pgfmoduleanimations.code.tex
-2021/05/15 | 395994 | graphics/pgf/contrib/pgfplots/doc/pgfplotstodo.pdf
-2021/05/15 | 394 | graphics/pgf/base/lua/graphdrawing/pgf/gd/interface.lua
-2021/05/15 | 393 | graphics/pgf/base/tex/t-pgfbsh.tex
-2021/05/15 | 393 | graphics/pgf/base/tex/t-pgfbma.tex
-2021/05/15 | 393 | graphics/pgf/base/tex/pgffor.tex
-2021/05/15 | 3937 | graphics/pgf/base/tex/tikzlibrarypositioning.code.tex
-2021/05/15 | 3937 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/algorithms/FruchtermanReingold.lua
-2021/05/15 | 39378 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/LayoutPipeline.lua
-2021/05/15 | 3931 | graphics/pgf/base/tex/tikzlibraryquotes.code.tex
-2021/05/15 | 392 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples.lua
-2021/05/15 | 392 | graphics/pgf/base/lua/graphdrawing/pgf/gd/bindings.lua
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-asymptotic-example.table
-2021/05/15 | 3928 | graphics/pgf/base/doc/text-en/plots/pgf-asymptotic-example.table
-2021/05/15 | 39101 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgflibraryintersections.code.tex
-2021/05/15 | 3905 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-plot-marks.tex
-2021/05/15 | 389 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control.lua
-2021/05/15 | 388 | graphics/pgf/base/tex/t-pgfbpl.tex
-2021/05/15 | 388 | graphics/pgf/base/tex/pgfbaseshapes.sty
-2021/05/15 | 388 | graphics/pgf/base/tex/pgfbasematrix.sty
-2021/05/15 | 388 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics.lua
-2021/05/15 | 386 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model.lua
-2021/05/15 | 386 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force.lua
-2021/05/15 | 3869 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/library.lua
-2021/05/15 | 3865 | graphics/pgf/base/tex/pgfmathfunctions.comparison.code.tex
-2021/05/15 | 384 | graphics/pgf/base/tex/pgfcalendar.tex
-2021/05/15 | 384 | graphics/pgf/base/tex/pgfbaseplot.sty
-2021/05/15 | 384 | graphics/pgf/base/lua/graphdrawing/pgf/gd/ogdf.lua
-2021/05/15 | 38364 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-calendar.tex
-2021/05/15 | 380 | graphics/pgf/base/tex/tikzlibrarybabel.code.tex
-2021/05/15 | 378 | graphics/pgf/base/lua/graphdrawing/pgf/gd/circular.lua
-2021/05/15 | 3775 | language/japanese/platex-tools/pxftnright.sty
-2021/05/15 | 376 | graphics/pgf/base/lua/graphdrawing/pgf/gd/pedigrees.lua
-2021/05/15 | 375691 | graphics/pgf/contrib/pgfplots/doc/TeX-programming-notes.pdf
-2021/05/15 | 374 | graphics/pgf/base/lua/graphdrawing/pgf/gd/routing.lua
-2021/05/15 | 37431 | graphics/pgf/base/tex/pgfkeysfiltered.code.tex
-2021/05/15 | 37424 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-transparency.tex
-2021/05/15 | 37376 | graphics/pgf/base/tex/pgfmathparser.code.tex
-2021/05/15 | 372 | graphics/pgf/base/tex/pgfkeys.tex
-2021/05/15 | 372 | graphics/pgf/base/doc/text-en/pgfmanual-en-main.tex
-2021/05/15 | 3727 | graphics/pgf/base/tex/pgfpict2e.sty
-2021/05/15 | 3706 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/SimpleEdgeDemo.lua
-2021/05/15 | 37060 | graphics/pgf/base/tex/pgfkeys.code.tex
-2021/05/15 | 3700 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfmanual.code.tex
-2021/05/15 | 368 | graphics/pgf/base/tex/pgflibrarygraphdrawing.layered.code.tex
-2021/05/15 | 3689 | language/japanese/platex-tools/plextarray.sty
-2021/05/15 | 367 | graphics/pgf/base/doc/version-for-dvips/pgfmanual-dvips.cfg
-2021/05/15 | 367035 | graphics/pgf/contrib/pgfplots/tex/pgfplotscoordprocessing.code.tex
-2021/05/15 | 366 | graphics/pgf/base/tex/pgflibrarygraphdrawing.examples.code.tex
-2021/05/15 | 364 | graphics/pgf/base/lua/graphdrawing/pgf/gd/trees.lua
-2021/05/15 | 3648 | graphics/pgf/base/doc/text-en/pgfmanual-en-xxcolor.tex
-2021/05/15 | 3643 | graphics/pgf/base/tex/tikzlibraryfit.code.tex
-2021/05/15 | 3640 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/NodePositioningGansnerKNV1993.lua
-2021/05/15 | 36314 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.ternary.code.tex
-2021/05/15 | 36299 | graphics/pgf/base/tex/pgfpages.sty
-2021/05/15 | 36240 | language/japanese/platex-tools/pxxspace.pdf
-2021/05/15 | 3614 | graphics/pgf/base/tex/tikzlibraryangles.code.tex
-2021/05/15 | 35 | graphics/pgf/base/doc/version-for-dvisvgm/en/color.cfg
-2021/05/15 | 3594 | graphics/pgf/base/tex/pgflibraryshapes.gates.logic.code.tex
-2021/05/15 | 3583 | graphics/pgf/base/doc/version-for-tex4ht/pgfmanual-tex4ht.cfg
-2021/05/15 | 357 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua
-2021/05/15 | 357 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/misclayout.lua
-2021/05/15 | 3574 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc.lua
-2021/05/15 | 35463 | language/japanese/platex-tools/pldocverb.pdf
-2021/05/15 | 3544 | graphics/pgf/base/tex/tikzlibraryperspective.code.tex
-2021/05/15 | 3534 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/ControlIteration.lua
-2021/05/15 | 3533 | graphics/pgf/contrib/pgfplots/tex/pgfplots.paths.code.tex
-2021/05/15 | 352 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered.lua
-2021/05/15 | 3529 | graphics/pgf/contrib/pgfplots/scripts/pgfplots.py
-2021/05/15 | 35298 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-algorithm-layer.tex
-2021/05/15 | 35249 | graphics/pgf/base/tex/pgfcoreshade.code.tex
-2021/05/15 | 351 | graphics/pgf/base/tex/t-pgfbpt.tex
-2021/05/15 | 351 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/planarity.lua
-2021/05/15 | 3515 | language/japanese/platex-tools/pxxspace.sty
-2021/05/15 | 35114 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfkeys.code.tex
-2021/05/15 | 350 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua
-2021/05/15 | 35074 | language/japanese/platex-tools/plextcolortbl.pdf
-2021/05/15 | 349 | graphics/pgf/base/tex/t-pgfbla.tex
-2021/05/15 | 34987 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-algorithms-in-c.tex
-2021/05/15 | 34957 | graphics/pgf/base/tex/pgflibrarygraphdrawing.code.tex
-2021/05/15 | 3493 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Event.lua
-2021/05/15 | 348 | graphics/pgf/base/tex/pgffor.sty
-2021/05/15 | 3473 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfsys-protocol.tex
-2021/05/15 | 34713 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex
-2021/05/15 | 346 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-examples.tex
-2021/05/15 | 3466 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/NodeRankingGansnerKNV1993.lua
-2021/05/15 | 345 | graphics/pgf/base/tex/tikzlibrarybending.code.tex
-2021/05/15 | 34575 | graphics/pgf/contrib/pgfplots/doc/pgfplotsexample.pdf
-2021/05/15 | 34556 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfkeysfiltered.code.tex
-2021/05/15 | 344 | graphics/pgf/base/tex/pgfbasepatterns.sty
-2021/05/15 | 344 | graphics/pgf/base/tex/pgfbaselayers.sty
-2021/05/15 | 344 | graphics/pgf/base/tex/pgfbaseimage.sty
-2021/05/15 | 344 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua
-2021/05/15 | 34338 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-usage-pgf.tex
-2021/05/15 | 342 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua
-2021/05/15 | 34260 | graphics/pgf/contrib/pgfplots/doc/pgfplotsexample-plain.pdf
-2021/05/15 | 3418 | dviware/dviinfox/README.md
-2021/05/15 | 340 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/module/InitialPlacer.lua
-2021/05/15 | 3405 | language/japanese/plautopatch/README.md
-2021/05/15 | 34020 | graphics/pgf/base/lua/graphdrawing/pgf/gd/interface/InterfaceToAlgorithms.lua
-2021/05/15 | 33 | graphics/pgf/contrib/pgfplots/tex/pgfplots.assert.sty
-2021/05/15 | 339 | graphics/pgf/base/tex/tikz.sty
-2021/05/15 | 339 | graphics/pgf/base/tex/tikzlibraryshapes.geometric.code.tex
-2021/05/15 | 3397 | graphics/pgf/base/tex/pgflibrarygraphdrawing.force.code.tex
-2021/05/15 | 33851 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-main.tex
-2021/05/15 | 337 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased.lua
-2021/05/15 | 3379 | graphics/pgf/base/tex/pgfmathfunctions.round.code.tex
-2021/05/15 | 33646 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Path.lua
-2021/05/15 | 3360 | graphics/pgf/base/tex/tikzlibrarytrees.code.tex
-2021/05/15 | 33432 | graphics/pgf/base/tex/tikzlibraryanimations.code.tex
-2021/05/15 | 333 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/module/RankingModule.lua
-2021/05/15 | 33336 | graphics/pgf/base/tex/pgflibraryshapes.callouts.code.tex
-2021/05/15 | 33335 | graphics/pgf/base/tex/pgfcorepoints.code.tex
-2021/05/15 | 332 | graphics/pgf/base/tex/pgfparser.sty
-2021/05/15 | 332 | graphics/pgf/base/tex/pgfmanual.sty
-2021/05/15 | 331 | graphics/pgf/base/tex/tikzlibraryplothandlers.code.tex
-2021/05/15 | 331 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/library.lua
-2021/05/15 | 329 | graphics/pgf/base/tex/tikzlibraryshapes.misc.code.tex
-2021/05/15 | 32995 | graphics/pgf/base/tex/pgflibraryplothandlers.code.tex
-2021/05/15 | 3294 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/forcetypes/ForcePullToGrid.lua
-2021/05/15 | 32926 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-paths.tex
-2021/05/15 | 328 | graphics/pgf/base/tex/pgfcalendar.sty
-2021/05/15 | 3286 | graphics/pgf/contrib/pgfplots/tex/pgfplotsutil.verb.code.tex
-2021/05/15 | 32770 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-matrices.tex
-2021/05/15 | 325 | graphics/pgf/base/tex/tikzlibraryplotmarks.code.tex
-2021/05/15 | 325 | graphics/pgf/base/tex/pgfrcs.sty
-2021/05/15 | 32488 | systems/texlive/tlnet/archive/kpathsea.r59203.tar.xz
-2021/05/15 | 3243 | graphics/pgf/base/tex/tikzlibrary3d.code.tex
-2021/05/15 | 321 | graphics/pgf/base/tex/tikzlibrarydecorations.pathmorphing.code.tex
-2021/05/15 | 321 | graphics/pgf/base/doc/INSTALL
-2021/05/15 | 3216 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/doc.lua
-2021/05/15 | 32095 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-trees.tex
-2021/05/15 | 319 | graphics/pgf/base/tex/tikzlibrarydecorations.footprints.code.tex
-2021/05/15 | 319 | graphics/pgf/base/tex/tikzlibraryarrows.code.tex
-2021/05/15 | 31876 | graphics/pgf/base/doc/text-en/pgfmanual-en-guidelines.tex
-2021/05/15 | 31874 | graphics/pgf/base/tex/pgflibraryarrows.code.tex
-2021/05/15 | 3183 | graphics/pgf/base/lua/graphdrawing/pgf/gd/routing/Hints.lua
-2021/05/15 | 317 | graphics/pgf/base/tex/tikzlibrarydecorations.fractals.code.tex
-2021/05/15 | 3177 | graphics/pgf/base/tex/pgfmathfunctions.integerarithmetics.code.tex
-2021/05/15 | 31708 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-shadings.tex
-2021/05/15 | 315 | graphics/pgf/base/tex/tikzlibrarydecorations.shapes.code.tex
-2021/05/15 | 3159 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Storage.lua
-2021/05/15 | 3158 | graphics/pgf/contrib/pgfplots/tex/pgfplotsutil.lua
-2021/05/15 | 3155 | graphics/pgf/contrib/pgfplots/tex/prepcontour_cli.lua
-2021/05/15 | 3150 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/crossing_minimization.lua
-2021/05/15 | 3134 | graphics/pgf/base/lua/graphdrawing/pgf/gd/interface/Scope.lua
-2021/05/15 | 31195 | graphics/pgf/base/doc/text-en/pgfmanual-en-math-numberprinting.tex
-2021/05/15 | 3107 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/ShiftMethod.lua
-2021/05/15 | 31025 | graphics/pgf/base/lua/graphdrawing/pgf/gd/interface/InterfaceToDisplay.lua
-2021/05/15 | 3096 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/CycleRemovalEadesLS1993.lua
-2021/05/15 | 3095 | graphics/pgf/contrib/pgfplots/tex/pgfplotssysgeneric.code.tex
-2021/05/15 | 3081 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/ControlElectric.lua
-2021/05/15 | 30754 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-plots.tex
-2021/05/15 | 306 | graphics/pgf/base/tex/pgfmath.sty
-2021/05/15 | 3063 | graphics/pgf/base/tex/pgfint.code.tex
-2021/05/15 | 3057 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua
-2021/05/15 | 3056 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/forcetypes/ForcePullToPoint.lua
-2021/05/15 | 3047 | graphics/pgf/contrib/pgfplots/tex/pgfplotslibrary.code.tex
-2021/05/15 | 3043 | macros/latex/contrib/easybook/README.md
-2021/05/15 | 3036 | graphics/pgf/base/tex/tikzlibrarypatterns.meta.code.tex
-2021/05/15 | 3034 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/parameters.lua
-2021/05/15 | 302 | graphics/pgf/base/source/misclayout_script.h
-2021/05/15 | 3013 | graphics/pgf/base/lua/graphdrawing/pgf/gd/pedigrees/Koerner2015.lua
-2021/05/15 | 3009 | language/japanese/plautopatch/pxstfloats.sty
-2021/05/15 | 30032 | graphics/pgf/contrib/pgfplots/tex/plothandler.lua
-2021/05/15 | 29754 | graphics/pgf/base/tex/tikzlibrarydecorations.text.code.tex
-2021/05/15 | 2968 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/algorithms/HuSpringElectricalFW.lua
-2021/05/15 | 2965 | graphics/pgf/base/tex/pgfcorequick.code.tex
-2021/05/15 | 2964 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua
-2021/05/15 | 29582 | graphics/pgf/base/source/InterfaceFromC.c
-2021/05/15 | 2931 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.contourlua.code.tex
-2021/05/15 | 29274 | graphics/pgf/base/tex/pgfutil-common.tex
-2021/05/15 | 2926 | graphics/pgf/base/tex/pgfsys-xetex.def
-2021/05/15 | 2926 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfsys-overview.tex
-2021/05/15 | 2919 | graphics/pgf/base/tex/tikzlibrarydatavisualization.3d.code.tex
-2021/05/15 | 2918 | language/japanese/platex-tools/README.md
-2021/05/15 | 2915 | language/japanese/platex-tools/plarray.tex
-2021/05/15 | 2890 | language/japanese/platex-tools/pxeverysel.tex
-2021/05/15 | 2889 | graphics/pgf/base/tex/tikzlibraryshadows.code.tex
-2021/05/15 | 28891 | graphics/pgf/base/doc/text-en/pgfmanual-en-oo.tex
-2021/05/15 | 28872 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-visualizers.tex
-2021/05/15 | 28852 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/Skambath2016.lua
-2021/05/15 | 2866 | graphics/pgf/base/tex/tikzlibrarylindenmayersystems.code.tex
-2021/05/15 | 28643 | graphics/pgf/base/doc/text-en/pgfmanual-en-main-body.tex
-2021/05/15 | 2861 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/layered.lua
-2021/05/15 | 283 | graphics/pgf/base/tex/tikzlibraryfpu.code.tex
-2021/05/15 | 2835648 | systems/win32/w32tex/platex.tar.xz
-2021/05/15 | 28178 | graphics/pgf/base/tex/pgfmathfunctions.basic.code.tex
-2021/05/15 | 28115 | graphics/pgf/base/doc/text-en/pgfmanual-en-tutorial-Euclid.tex
-2021/05/15 | 2804 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua
-2021/05/15 | 2790 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Direct.lua
-2021/05/15 | 2774 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/Transform.lua
-2021/05/15 | 276 | graphics/pgf/base/tex/tikzlibraryfixedpointarithmetic.code.tex
-2021/05/15 | 2763 | graphics/pgf/base/tex/pgfsys-textures.def
-2021/05/15 | 2758 | graphics/pgf/base/tex/pgfsys-vtex.def
-2021/05/15 | 2757 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/ComponentOrder.lua
-2021/05/15 | 274 | graphics/pgf/base/tex/pgfkeys.sty
-2021/05/15 | 2746 | language/japanese/platex-tools/pxeveryshi.tex
-2021/05/15 | 274109 | graphics/pgf/base/doc/images/brave-gnu-world-logo-mask.eps
-2021/05/15 | 2739 | graphics/pgf/base/tex/pgflibrarydecorations.fractals.code.tex
-2021/05/15 | 27367 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-fpu.tex
-2021/05/15 | 2732 | graphics/pgf/base/tex/tikzlibrarysnakes.code.tex
-2021/05/15 | 27253 | graphics/pgf/base/doc/text-en/pgfmanual-en-pages.tex
-2021/05/15 | 2713 | graphics/pgf/contrib/pgfplots/tex/pgfplotstable.coltype.code.tex
-2021/05/15 | 27098 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.colortol.code.tex
-2021/05/15 | 27080 | graphics/pgf/base/tex/pgfmoduleoo.code.tex
-2021/05/15 | 26872 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-formats.tex
-2021/05/15 | 26859 | graphics/pgf/contrib/pgfplots/tex/pgfplotsbinary.data.code.tex
-2021/05/15 | 2668 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/Anchoring.lua
-2021/05/15 | 26467 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Digraph.lua
-2021/05/15 | 26393 | graphics/pgf/contrib/pgfplots/tex/pgfplotsstackedplots.code.tex
-2021/05/15 | 262 | graphics/pgf/base/tex/example_graph_for_ascii_displayer.txt
-2021/05/15 | 2627 | graphics/pgf/base/tex/pgfsys-dvipdfm.def
-2021/05/15 | 2616 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-examples.tex
-2021/05/15 | 26103 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_misc.code.tex
-2021/05/15 | 260 | graphics/pgf/base/doc/images/brave-gnu-world-logo.xbb
-2021/05/15 | 2589 | language/japanese/platex-tools/pxxspace.tex
-2021/05/15 | 2576 | graphics/pgf/base/tex/tikzlibrarygraphs.standard.code.tex
-2021/05/15 | 2571 | graphics/pgf/base/lua/graphdrawing/pgf/gd/deprecated/Iterators.lua
-2021/05/15 | 25707 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.polar.code.tex
-2021/05/15 | 2563 | graphics/pgf/base/tex/pgflibraryfadings.code.tex
-2021/05/15 | 255 | graphics/pgf/base/source/tikzexternaltestmakefile.tex
-2021/05/15 | 2556 | graphics/pgf/base/source/SpringEmbedderFRExact_script.h
-2021/05/15 | 25550 | graphics/pgf/base/tex/tikzlibrarymath.code.tex
-2021/05/15 | 2549 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua
-2021/05/15 | 2544 | graphics/pgf/base/tex/pgfmanual.code.tex
-2021/05/15 | 2544 | graphics/pgf/base/tex/pgfcoreobjects.code.tex
-2021/05/15 | 2541 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/forcetypes/ForceAbsoluteValue.lua
-2021/05/15 | 2540 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/LookupTable.lua
-2021/05/15 | 25239 | graphics/pgf/contrib/pgfplots/tex/pgfplotsmeshplotimage.code.tex
-2021/05/15 | 251 | graphics/pgf/base/source/tikzexternaltest.tex
-2021/05/15 | 2505 | graphics/pgf/base/source/InterfaceFromOGDF.c++
-2021/05/15 | 24998 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/Maeusle2012.lua
-2021/05/15 | 24941 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-scopes.tex
-2021/05/15 | 2488 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/library.lua
-2021/05/15 | 24802 | graphics/pgf/contrib/pgfplots/tex/prepcontour.lua
-2021/05/15 | 2479 | graphics/pgf/base/lua/graphdrawing/pgf/gd/routing/NecklaceRouting.lua
-2021/05/15 | 24742 | graphics/pgf/base/tex/pgflibrarysvg.path.code.tex
-2021/05/15 | 2472 | graphics/pgf/base/lua/graphdrawing/pgf/gd/interface/InterfaceToC.lua
-2021/05/15 | 2463 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/algorithms/SimpleSpring.lua
-2021/05/15 | 24617 | graphics/pgf/base/tex/pgflibraryshapes.gates.logic.IEC.code.tex
-2021/05/15 | 2439 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-phylogenetics.tex
-2021/05/15 | 24373 | graphics/pgf/contrib/pgfplots/tex/pgfplotsliststructureext.code.tex
-2021/05/15 | 2436144 | systems/texlive/tlnet/archive/changes.doc.r59198.tar.xz
-2021/05/15 | 2413 | graphics/pgf/base/tex/pgfsys-dvisvgm4ht.def
-2021/05/15 | 2412 | graphics/pgf/contrib/pgfplots/tex/t-pgfplots.tex
-2021/05/15 | 24061 | graphics/pgf/base/tex/pgfcalendar.code.tex
-2021/05/15 | 23997 | graphics/pgf/base/tex/pgffor.code.tex
-2021/05/15 | 23958 | graphics/pgf/contrib/pgfplots/tex/pgfplotscolor.code.tex
-2021/05/15 | 23887 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-pics.tex
-2021/05/15 | 23778 | graphics/pgf/base/source/InterfaceFromC.h
-2021/05/15 | 23756 | graphics/pgf/base/tex/pgfsys-dvips.def
-2021/05/15 | 23635 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-decorations.tex
-2021/05/15 | 2362 | language/japanese/platex-tools/pxftnright.tex
-2021/05/15 | 235 | graphics/pgf/base/source/planarity_script.h
-2021/05/15 | 23581 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarycolorbrewer.code.tex
-2021/05/15 | 23537 | graphics/pgf/contrib/pgfplots/tex/pgfplotsarray.code.tex
-2021/05/15 | 2351 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/SimpleDemo.lua
-2021/05/15 | 23492 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-points.tex
-2021/05/15 | 23437 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-plots.tex
-2021/05/15 | 233 | graphics/pgf/base/doc/version-for-dvisvgm/en/pgfmanual.html
-2021/05/15 | 23256 | graphics/pgf/contrib/pgfplots/README
-2021/05/15 | 23159 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-plot-handlers.tex
-2021/05/15 | 23050 | graphics/pgf/contrib/pgfplots/tex/pgfplotsbinary.code.tex
-2021/05/15 | 22979 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgflibraryluamath.code.tex
-2021/05/15 | 22936 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/SpringElectricalHu2006.lua
-2021/05/15 | 2291 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua
-2021/05/15 | 22892 | graphics/pgf/base/tex/pgflibraryshapes.gates.ee.IEC.code.tex
-2021/05/15 | 2288 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/PhylogeneticTree.lua
-2021/05/15 | 2282 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib/DepthFirstSearch.lua
-2021/05/15 | 22701 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.code.tex
-2021/05/15 | 225 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-calc.tex
-2021/05/15 | 22428 | graphics/pgf/contrib/pgfplots/tex/pgfplots.errorbars.code.tex
-2021/05/15 | 2238 | graphics/pgf/base/source/FastMultipoleEmbedder_script.h
-2021/05/15 | 2232 | graphics/pgf/base/tex/xxcolor.sty
-2021/05/15 | 22320 | systems/texlive/tlnet/archive/pdfextra.r59204.tar.xz
-2021/05/15 | 22307 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/BoyerMyrvold2004.lua
-2021/05/15 | 2224 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua
-2021/05/15 | 22211 | graphics/pgf/base/tex/pgfsys-common-postscript.def
-2021/05/15 | 2220 | graphics/pgf/base/tex/pgfheaps.sty
-2021/05/15 | 22123 | graphics/pgf/base/tex/pgflibraryluamath.code.tex
-2021/05/15 | 22072 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-usage-tikz.tex
-2021/05/15 | 22045 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/NetworkSimplex.lua
-2021/05/15 | 21989 | graphics/pgf/base/tex/pgfcoretransformations.code.tex
-2021/05/15 | 21935 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.groupplots.code.tex
-2021/05/15 | 21933 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfcalendar.tex
-2021/05/15 | 21856 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeysfiltered.tex
-2021/05/15 | 2184 | graphics/pgf/base/tex/tikzlibraryturtle.code.tex
-2021/05/15 | 2161 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-svg-path.tex
-2021/05/15 | 2152 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua
-2021/05/15 | 21452 | graphics/pgf/base/doc/text-en/pgfmanual-en-drivers.tex
-2021/05/15 | 21326 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/GraphAnimationCoordination.lua
-2021/05/15 | 21302 | graphics/pgf/base/tex/pgfcorepathusage.code.tex
-2021/05/15 | 21201 | graphics/pgf/base/tex/pgfmodulematrix.code.tex
-2021/05/15 | 2108 | graphics/pgf/base/tex/tikzlibrarycircuits.logic.IEC.code.tex
-2021/05/15 | 21068 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-mindmaps.tex
-2021/05/15 | 21013 | graphics/pgf/base/tex/pgfcomp-version-0-65.sty
-2021/05/15 | 21005 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Arc.lua
-2021/05/15 | 2095 | graphics/pgf/base/README.md
-2021/05/15 | 2086 | language/japanese/plautopatch/plsiunitx.sty
-2021/05/15 | 20726 | graphics/pgf/base/tex/pgfcorescopes.code.tex
-2021/05/15 | 2070 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-tan-example.table
-2021/05/15 | 2070 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-tan-example.table
-2021/05/15 | 20641 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfcoreexternal.code.tex
-2021/05/15 | 20502 | graphics/pgf/base/tex/tikzlibrarydatavisualization.polar.code.tex
-2021/05/15 | 2048616 | graphics/pgf/contrib/pgfplots/doc/pgfplots.doc.src.tar.bz2
-2021/05/15 | 20474 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-external.tex
-2021/05/15 | 2044 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-tan-example.table
-2021/05/15 | 2044 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-tan-example.table
-2021/05/15 | 2044 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-tan-example.table
-2021/05/15 | 2044 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-tan-example.table
-2021/05/15 | 2044 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-tan-example.table
-2021/05/15 | 2044 | graphics/pgf/base/doc/text-en/plots/pgf-tan-example.table
-2021/05/15 | 20415 | graphics/pgf/base/doc/licenses/gnu-free-documentation-license-1.2.txt
-2021/05/15 | 20366 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-patterns.tex
-2021/05/15 | 20166 | graphics/pgf/base/tex/pgflibraryprofiler.code.tex
-2021/05/15 | 1997 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua
-2021/05/15 | 19944 | graphics/pgf/contrib/pgfplots/tex/pgfplotscore.code.tex
-2021/05/15 | 19862 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-transformations.tex
-2021/05/15 | 19835 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-chains.tex
-2021/05/15 | 19781 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/Embedding.lua
-2021/05/15 | 1977 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1977 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 19702 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-spy.tex
-2021/05/15 | 1965 | language/japanese/plautopatch/plextarydshln.sty
-2021/05/15 | 1963 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/ControlSprings.lua
-2021/05/15 | 19618 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua
-2021/05/15 | 19581 | graphics/pgf/base/tex/pgfmoduleparser.code.tex
-2021/05/15 | 1952 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/CycleRemovalBergerS1990b.lua
-2021/05/15 | 19512 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/SpringElectricalWalshaw2000.lua
-2021/05/15 | 1944 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/initialpositioning/CircularInitialPositioning.lua
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1944 | graphics/pgf/base/doc/text-en/plots/pgfplotgnuplot-example.table
-2021/05/15 | 1937 | language/japanese/platex-tools/pxmulticol.tex
-2021/05/15 | 19324 | graphics/pgf/base/tex/pgfcoreexternal.code.tex
-2021/05/15 | 191 | graphics/pgf/base/doc/version-for-dvisvgm/en/pgfmanual-test.html
-2021/05/15 | 1918 | graphics/pgf/base/tex/pgfmodulesorting.code.tex
-2021/05/15 | 19154 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-actions.tex
-2021/05/15 | 19110 | graphics/pgf/base/doc/licenses/latex-project-public-license-1.3c.txt
-2021/05/15 | 1910 | graphics/pgf/base/lua/graphdrawing/pgf.lua
-2021/05/15 | 1896 | graphics/pgf/base/tex/pgfsysprotocol.code.tex
-2021/05/15 | 18861 | graphics/pgf/contrib/pgfplots/tex/pgfplotsmatrix.code.tex
-2021/05/15 | 188335 | graphics/pgf/base/doc/ChangeLog
-2021/05/15 | 18773 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/PDP.lua
-2021/05/15 | 1869 | graphics/pgf/contrib/pgfplots/tex/pgfplots.lua
-2021/05/15 | 1868 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua
-2021/05/15 | 18669 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/Supergraph.lua
-2021/05/15 | 18668 | graphics/pgf/base/lua/graphdrawing/pgf/gd/trees/SpanningTreeComputation.lua
-2021/05/15 | 1865 | graphics/pgf/base/source/CirclePlacer_script.h
-2021/05/15 | 1864 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/BindingToASCII.lua
-2021/05/15 | 186007 | graphics/pgf/base/tex/tikz.code.tex
-2021/05/15 | 18491 | graphics/pgf/contrib/pgfplots/tex/tikzlibraryfillbetween.code.tex
-2021/05/15 | 18491 | graphics/pgf/base/tex/pgfsys-dvipdfmx.def
-2021/05/15 | 1841 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua
-2021/05/15 | 1839 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/node_ranking.lua
-2021/05/15 | 18393 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-matrices.tex
-2021/05/15 | 1838 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua
-2021/05/15 | 1836 | language/japanese/platex-tools/plarray.sty
-2021/05/15 | 1835 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/CycleRemovalBergerS1990a.lua
-2021/05/15 | 1828 | graphics/pgf/contrib/pgfplots/scripts/matlab2pgfplots.sh
-2021/05/15 | 18181 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfcoreimage.code.tex
-2021/05/15 | 180 | graphics/pgf/contrib/pgfplots/INSTALL
-2021/05/15 | 18092 | graphics/pgf/contrib/pgfplots/doc/COPYING
-2021/05/15 | 1808 | language/japanese/platex-tools/pxeveryshi.sty
-2021/05/15 | 18032 | graphics/pgf/base/doc/licenses/gnu-public-license-2.txt
-2021/05/15 | 1790 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/node_positioning.lua
-2021/05/15 | 1778 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/LinkedList.lua
-2021/05/15 | 17756 | graphics/pgf/contrib/pgfplots/tex/parser.lua
-2021/05/15 | 1771 | language/japanese/platex-tools/plextdelarray.sty
-2021/05/15 | 17662 | graphics/pgf/contrib/pgfplots/tex/pgfplotstexio.lua
-2021/05/15 | 17652 | systems/texlive/tlnet/archive/changes.source.r59198.tar.xz
-2021/05/15 | 17612 | graphics/pgf/base/tex/pgfsys-tex4ht.def
-2021/05/15 | 175 | graphics/pgf/base/INSTALL_NOTES
-2021/05/15 | 17583452 | install/graphics/pgf/contrib/pgfplots.tds.zip
-2021/05/15 | 1746 | language/japanese/plautopatch/pxpgfrcs.sty
-2021/05/15 | 17465 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfcorescopes.code.tex
-2021/05/15 | 17447 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.colormaps.code.tex
-2021/05/15 | 1741 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/base/InitialTemplate.lua
-2021/05/15 | 1740 | graphics/pgf/base/source/FastHierarchyLayout_script.h
-2021/05/15 | 1731 | graphics/pgf/base/source/SugiyamaLayout_script.h
-2021/05/15 | 17311 | graphics/pgf/base/tex/pgfcorepathprocessing.code.tex
-2021/05/15 | 17298 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-math.tex
-2021/05/15 | 17294 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-polar.tex
-2021/05/15 | 1718 | graphics/pgf/base/tex/tikzlibraryviews.code.tex
-2021/05/15 | 1715 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/initialpositioning/GridInitialPositioning.lua
-2021/05/15 | 17151 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/base/ForceController.lua
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 170 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 1701 | graphics/pgf/base/source/LongestPathRanking_script.h
-2021/05/15 | 1699 | graphics/pgf/base/lua/graphdrawing/pgf/gd.lua
-2021/05/15 | 16959 | graphics/pgf/base/source/unittest_luamathparser.tex
-2021/05/15 | 1679 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/ComponentDirection.lua
-2021/05/15 | 16757 | graphics/pgf/base/lua/luamath/pgf/luamath/parser.lua
-2021/05/15 | 1659 | graphics/pgf/contrib/pgfplots/tex/binary.lua
-2021/05/15 | 16558 | CTAN.sites
-2021/05/15 | 1651 | graphics/pgf/base/source/CircularLayout_script.h
-2021/05/15 | 1647 | language/japanese/platex-tools/pldocverb.tex
-2021/05/15 | 16467 | graphics/pgf/base/tex/pgflibrarydecorations.shapes.code.tex
-2021/05/15 | 1636 | language/japanese/platex-tools/plextcolortbl.tex
-2021/05/15 | 16342 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex
-2021/05/15 | 16323 | graphics/pgf/base/doc/text-en/pgfmanual-en-pgffor.tex
-2021/05/15 | 162 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 162 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 162 | graphics/pgf/base/doc/text-en/plots/pgf-asymptotic-example.gnuplot
-2021/05/15 | 16267 | graphics/pgf/contrib/pgfplots/tex/functions.lua
-2021/05/15 | 16161 | graphics/pgf/contrib/pgfplots/doc/pgfplotsexample-context.pdf
-2021/05/15 | 16121 | graphics/pgf/base/tex/pgfmoduleplot.code.tex
-2021/05/15 | 160993 | graphics/pgf/base/tex/pgflibraryshapes.geometric.code.tex
-2021/05/15 | 16091 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarydecorations.softclip.code.tex
-2021/05/15 | 1608 | graphics/pgf/base/source/SpringEmbedderFR_script.h
-2021/05/15 | 16083 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-petri.tex
-2021/05/15 | 15929 | graphics/pgf/base/tex/tikzlibrarycalc.code.tex
-2021/05/15 | 1589 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua
-2021/05/15 | 1576 | graphics/pgf/base/doc/version-for-dvisvgm/en/Makefile
-2021/05/15 | 1572 | graphics/pgf/base/source/SimpleDemoC.c
-2021/05/15 | 1571 | graphics/pgf/base/tex/tikzlibrarycircuits.logic.US.code.tex
-2021/05/15 | 1563 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/ControlDeclare.lua
-2021/05/15 | 15631 | graphics/pgf/base/tex/pgflibraryfixedpointarithmetic.code.tex
-2021/05/15 | 156060 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-axes.tex
-2021/05/15 | 154 | graphics/pgf/base/source/ExampleLocalMakefileConfig.mk
-2021/05/15 | 15497 | graphics/pgf/base/tex/pgfmanual.pdflinks.code.tex
-2021/05/15 | 15479 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-transparency.tex
-2021/05/15 | 15474 | graphics/pgf/base/tex/pgflibrarypatterns.meta.code.tex
-2021/05/15 | 1532 | graphics/pgf/base/tex/tikzlibraryshapes.gates.logic.IEC.code.tex
-2021/05/15 | 1524 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-fadings.tex
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 151 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-parametric-example-cut.gnuplot
-2021/05/15 | 1508 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/initialpositioning/RandomInitialPositioning.lua
-2021/05/15 | 1507 | graphics/pgf/contrib/pgfplots/tex/pgfplots.tex
-2021/05/15 | 1500 | language/japanese/plautopatch/LICENSE
-2021/05/15 | 1500 | language/japanese/platex-tools/LICENSE
-2021/05/15 | 14927 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_pgfmanual.pdflinks.code.tex
-2021/05/15 | 149137 | language/japanese/plautopatch.zip
-2021/05/15 | 14804 | graphics/pgf/base/tex/tikzlibrarymindmap.code.tex
-2021/05/15 | 14802 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/Sublayouts.lua
-2021/05/15 | 14741 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarycolortol.code.tex
-2021/05/15 | 147175 | graphics/pgf/base/doc/images/pgfmanual-mindmap-1.pdf
-2021/05/15 | 1468 | graphics/pgf/base/lua/graphdrawing/pgf/gd/experimental/evolving/TimeSpec.lua
-2021/05/15 | 14536 | graphics/pgf/base/doc/text-en/pgfmanual-en-introduction.tex
-2021/05/15 | 14534 | graphics/pgf/base/lua/luamath/pgf/luamath/functions.lua
-2021/05/15 | 14524 | graphics/pgf/base/tex/pgflibraryplotmarks.code.tex
-2021/05/15 | 14515 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-perspective.tex
-2021/05/15 | 14504 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-overview.tex
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 144 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 1440 | graphics/pgf/contrib/pgfplots/tex/pgfplotstable.sty
-2021/05/15 | 14370 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/CoarseGraph.lua
-2021/05/15 | 14358 | graphics/pgf/contrib/pgfplots/tex/pgfsys-luatexpatch.def
-2021/05/15 | 1433 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua
-2021/05/15 | 143246 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-graphs.tex
-2021/05/15 | 142672 | graphics/pgf/base/doc/text-en/pgfmanual-en-dv-stylesheets.tex
-2021/05/15 | 14117 | graphics/pgf/base/tex/pgflibrarycurvilinear.code.tex
-2021/05/15 | 14014 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/ComponentAlign.lua
-2021/05/15 | 139 | graphics/pgf/base/doc/images/brave-gnu-world-logo-mask.bb
-2021/05/15 | 1398 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua
-2021/05/15 | 138 | graphics/pgf/base/doc/version-for-vtex/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 138 | graphics/pgf/base/doc/version-for-tex4ht/en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 138 | graphics/pgf/base/doc/text-en/plots/pgf-parametric-example.gnuplot
-2021/05/15 | 13892 | graphics/pgf/base/doc/text-en/pgfmanual-en-module-parser.tex
-2021/05/15 | 1384 | systems/texlive/tlnet/archive/noindentafter.r59195.tar.xz
-2021/05/15 | 13828 | graphics/pgf/contrib/pgfplots/tex/pgfplotsliststructure.code.tex
-2021/05/15 | 137 | graphics/pgf/base/doc/images/brave-gnu-world-logo.25.bb
-2021/05/15 | 137272 | systems/texlive/tlnet/archive/vancouver.doc.r59192.tar.xz
-2021/05/15 | 136 | graphics/pgf/contrib/pgfplots/doc/Makefile
-2021/05/15 | 134 | graphics/pgf/base/doc/images/brave-gnu-world-logo.bb
-2021/05/15 | 1349 | language/japanese/platex-tools/pldocverb.sty
-2021/05/15 | 13391 | graphics/pgf/base/tex/pgfmathcalc.code.tex
-2021/05/15 | 133871 | graphics/pgf/contrib/pgfplots/tex/pgfplotsmeshplothandler.code.tex
-2021/05/15 | 1337 | graphics/pgf/base/source/layered_script.h
-2021/05/15 | 13375 | graphics/pgf/base/tex/pgflibrarydecorations.footprints.code.tex
-2021/05/15 | 1334 | graphics/pgf/base/source/FMMMLayout_script.h
-2021/05/15 | 13263 | graphics/pgf/contrib/pgfplots/tex/bugtracker.sty
-2021/05/15 | 13244 | graphics/pgf/base/tex/pgfsys-luatex.def
-2021/05/15 | 1319 | graphics/pgf/base/tex/tikzlibrarydecorations.pathreplacing.code.tex
-2021/05/15 | 13134 | graphics/pgf/base/tex/pgflibraryshadings.code.tex
-2021/05/15 | 1310 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-force.tex
-2021/05/15 | 1309 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/edge_routing.lua
-2021/05/15 | 13093 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/SpringHu2006.lua
-2021/05/15 | 1308 | graphics/pgf/base/source/PlanarizationLayout_script.h
-2021/05/15 | 1303 | graphics/pgf/base/tex/tikzlibraryshapes.gates.logic.US.code.tex
-2021/05/15 | 1303 | graphics/pgf/base/source/FastSimpleHierarchyLayout_script.h
-2021/05/15 | 13039 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-automata.tex
-2021/05/15 | 1296 | graphics/pgf/base/tex/t-pgfmod.tex
-2021/05/15 | 1286 | graphics/pgf/base/tex/t-pgfcor.tex
-2021/05/15 | 12827514 | install/graphics/pgf/base/pgf.tds.zip
-2021/05/15 | 1280 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.decorations.softclip.code.tex
-2021/05/15 | 1280 | graphics/pgf/base/tex/pgfexternalwithdepth.tex
-2021/05/15 | 1280 | graphics/pgf/base/source/SpringEmbedderKK_script.h
-2021/05/15 | 12752809 | graphics/pgf/base.zip
-2021/05/15 | 12681120 | graphics/pgf/contrib/pgfplots/doc/pgfplots.pdf
-2021/05/15 | 12656 | graphics/pgf/base/tex/pgflibrarydecorations.text.code.tex
-2021/05/15 | 12649 | graphics/pgf/contrib/pgfplots/tex/statistics.lua
-2021/05/15 | 126272 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-shapes.tex
-2021/05/15 | 12601 | graphics/pgf/base/tex/pgfsys-pdftex.def
-2021/05/15 | 1254 | graphics/pgf/base/source/SimpleDemoCPlusPlus.c++
-2021/05/15 | 1251 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-through.tex
-2021/05/15 | 12489 | graphics/pgf/contrib/pgfplots/tex/pgfplots.markers.code.tex
-2021/05/15 | 12457 | graphics/pgf/base/tex/tikzlibrarycalendar.code.tex
-2021/05/15 | 12413 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/DistanceMatrix.lua
-2021/05/15 | 1238 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua
-2021/05/15 | 123680 | graphics/pgf/contrib/pgfplots/tex/pgfplots.scaling.code.tex
-2021/05/15 | 12347 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_loader.code.tex
-2021/05/15 | 123343 | graphics/pgf/contrib/pgfplots/tex/pgfplotstable.code.tex
-2021/05/15 | 1228 | graphics/pgf/contrib/pgfplots/tex/pgfplots.assert.code.tex
-2021/05/15 | 12261 | graphics/pgf/base/lua/graphdrawing/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua
-2021/05/15 | 12243 | graphics/pgf/base/tex/pgfmodulenonlineartransformations.code.tex
-2021/05/15 | 122429 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.patchplots.code.tex
-2021/05/15 | 1222 | graphics/pgf/base/source/SolarMerger_script.h
-2021/05/15 | 12227 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/Sugiyama.lua
-2021/05/15 | 1220 | graphics/pgf/contrib/pgfplots/tex/pgfplotstable.tex
-2021/05/15 | 12158 | graphics/pgf/contrib/pgfplots/tex/pgfplotsoldpgfsupp_trig_format.code.tex
-2021/05/15 | 120954 | graphics/pgf/contrib/pgfplots/tex/pgfplotsplothandlers.code.tex
-2021/05/15 | 1201 | graphics/pgf/base/tex/tikzlibraryshapes.callouts.code.tex
-2021/05/15 | 11977 | graphics/pgf/contrib/pgfplots/tex/tikzlibrarypgfplots.units.code.tex
-2021/05/15 | 11960 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-images.tex
-2021/05/15 | 1195 | graphics/pgf/contrib/pgfplots/doc/pgfplotsexample.tex
-2021/05/15 | 1185 | dviware/dviinfox/LICENSE
-2021/05/15 | 1179 | graphics/pgf/base/tex/tikzlibraryfadings.code.tex
-2021/05/15 | 11742 | graphics/pgf/base/tex/pgfutil-context.def
-2021/05/15 | 1172 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua
-2021/05/15 | 1172 | graphics/pgf/base/doc/version-for-dvips/en/Makefile
-2021/05/15 | 1169 | graphics/pgf/base/tex/tikzlibraryer.code.tex
-2021/05/15 | 1169 | graphics/pgf/base/source/SiftingHeuristic_script.h
-2021/05/15 | 11662 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-edges.tex
-2021/05/15 | 11601 | graphics/pgf/base/doc/text-en/pgfmanual-en-gd-display-layer.tex
-2021/05/15 | 11566 | graphics/pgf/base/doc/version-for-dvisvgm/pgfmanual-dvisvgm.cfg
-2021/05/15 | 1151 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/OptimalRanking.lua
-2021/05/15 | 11518 | graphics/pgf/base/tex/tikzlibrarytopaths.code.tex
-2021/05/15 | 115153 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-animations.tex
-2021/05/15 | 1142 | graphics/pgf/base/doc/licenses/LICENSE
-2021/05/15 | 11407 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-design.tex
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-xetex/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-pdftex/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-luatex/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-dvisvgm/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-dvips/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-dvipdfmx/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/version-for-dvipdfm/en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 113 | graphics/pgf/base/doc/text-en/plots/pgf-tan-example.gnuplot
-2021/05/15 | 1135 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/ControlStart.lua
-2021/05/15 | 11349 | graphics/pgf/base/tex/pgfsys-dvi.def
-2021/05/15 | 113285 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.colorbrewer.code.tex
-2021/05/15 | 11324 | graphics/pgf/base/lua/graphdrawing/pgf/gd/trees/doc.lua
-2021/05/15 | 11312 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Vertex.lua
-2021/05/15 | 11127 | graphics/pgf/base/lua/graphdrawing/pgf/gd/lib.lua
-2021/05/15 | 11083 | graphics/pgf/base/lua/graphdrawing/pgf/gd/control/Distances.lua
-2021/05/15 | 1107 | graphics/pgf/base/source/tikzexternaltest.code.tex
-2021/05/15 | 1105 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/base/ForceTemplate.lua
-2021/05/15 | 1104 | graphics/pgf/base/source/IndependentSetMerger_script.h
-2021/05/15 | 11024 | graphics/pgf/base/tex/pgfmathfunctions.misc.code.tex
-2021/05/15 | 1101 | graphics/pgf/base/source/LocalBiconnectedMerger_script.h
-2021/05/15 | 1097 | graphics/pgf/contrib/pgfplots/tex/t-pgfplotstable.tex
-2021/05/15 | 1090 | graphics/pgf/base/tex/pgf.sty
-2021/05/15 | 10901 | graphics/pgf/base/tex/pgfmodulebending.code.tex
-2021/05/15 | 1087 | graphics/pgf/base/source/multilevelmixer_script.h
-2021/05/15 | 1087 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/SpringElectricalLayouts.lua
-2021/05/15 | 1080 | graphics/pgf/base/source/INSTALL
-2021/05/15 | 1077 | graphics/pgf/base/source/SimpleDemoOGDF.c++
-2021/05/15 | 1077 | graphics/pgf/base/source/BarycenterPlacer_script.h
-2021/05/15 | 10778 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-matrices.tex
-2021/05/15 | 1073000 | systems/texlive/tlnet/archive/kpathsea.doc.r59203.tar.xz
-2021/05/15 | 1068 | graphics/pgf/base/lua/graphdrawing/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua
-2021/05/15 | 106851 | graphics/pgf/base/doc/text-en/pgfmanual-en-tikz-arrows.tex
-2021/05/15 | 1066 | language/japanese/platex-tools/plextcolortbl.sty
-2021/05/15 | 10610 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-profiler.tex
-2021/05/15 | 1057 | graphics/pgf/base/source/CoffmanGrahamRanking_script.h
-2021/05/15 | 10544 | dviware/dviinfox/dviinfox.pl
-2021/05/15 | 10535 | graphics/pgf/base/doc/text-en/pgfmanual-en-base-patterns.tex
-2021/05/15 | 1051 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.pgfsys-xetex.def
-2021/05/15 | 1049 | graphics/pgf/contrib/pgfplots/tex/pgflibrarypgfplots.surfshading.pgfsys-luatexpatch.def
-2021/05/15 | 104935 | graphics/pgf/base/tex/pgfmathfloat.code.tex
-2021/05/15 | 10461 | graphics/pgf/base/doc/text-en/pgfmanual-en-library-shadows.tex
-2021/05/15 | 1042709 | graphics/pgf/contrib/pgfplots/source/pgfplotstests.tar.bz2
-2021/05/15 | 10416 | graphics/pgf/base/doc/text-en/pgfmanual-en-math-algorithms.tex
-2021/05/15 | 1040 | graphics/pgf/base/tex/tikzlibrarythrough.code.tex
-2021/05/15 | 1033 | graphics/pgf/base/source/MatchingMerger_script.h
-2021/05/15 | 1030 | graphics/pgf/base/lua/graphdrawing/pgf/gd/model/Hyperedge.lua
-2021/05/15 | 1022 | graphics/pgf/base/source/OptimalRanking_script.h
-2021/05/15 | 10197 | graphics/pgf/base/lua/graphdrawing/pgf/gd/force/jedi/doc.lua
-2021/05/15 | 10185873 | graphics/pgf/base/doc/pgfmanual.pdf
-2021/05/15 | 1017 | graphics/pgf/base/tex/pgfexternal.tex
-2021/05/15 | 1017 | graphics/pgf/base/source/EdgeCoverMerger_script.h
-2021/05/15 | 10165 | graphics/pgf/base/tex/pgfmathfunctions.base.code.tex
-2021/05/15 | 10130 | graphics/pgf/base/tex/pgfmodulesnakes.code.tex
-2021/05/15 | 101088 | systems/texlive/tlnet/archive/pdfmanagement-testphase.source.r59194.tar.xz
-2021/05/15 | 10074 | graphics/pgf/base/doc/text-en/pgfmanual-en-main-preamble.tex
-2021/05/15 | 1000 | graphics/pgf/base/source/MultilevelLayout_script.h
diff --git a/fonts/kpfonts-otf/README.md b/fonts/kpfonts-otf/README.md
index 2267028da9..cc674316d7 100644
--- a/fonts/kpfonts-otf/README.md
+++ b/fonts/kpfonts-otf/README.md
@@ -106,6 +106,17 @@ Either version 1.3 or, at your option, any later version.
Extensible delimiters corrected in KpMath-Sans.
Options frenchstyle, partialup and fancyReIm now work as intended.
+* v. 0.36:
+ - Math fonts:
+ kpfonts-otf.sty: Option mathcal deleted, \mathcal{} and \mathscr{}
+ now print different glyphs.
+ mathcal substitutions corrected for KpMath-Regular and KpMath-Sans.
+ Extensible \langle, \rangle, \lAngle and \rangle delimiters are now
+ available in eight sizes (three bigger sizes added).
+ All vertical arrows are now extensible.
+ Bug fix: extensible right paren was broken, thanks to Tom Stotko
+ for pointed it out!
+
---
Copyright 2020-2021 Daniel Flipo
E-mail: daniel (dot) flipo (at) free (dot) fr
diff --git a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx
index dfb1f39439..eb348001ae 100644
--- a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx
+++ b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.ltx
@@ -1,3 +1,5 @@
+\RequirePackage{pdfmanagement-testphase}
+\DeclareDocumentMetadata{pdfstandard=A-2b, lang=en-GB}
\documentclass[paper=a4]{scrartcl}
% Packages
\usepackage{graphics, array}
@@ -20,13 +22,11 @@
\usepackage{realscripts}
\usepackage{microtype}
\usepackage{hyperref}
-\hypersetup{pdfcreator={LuaTeX},
+\hypersetup{pdftitle={Kpfonts-otf User’s Guide},
pdfauthor={Daniel FLIPO},
- unicode,
- colorlinks,
- urlcolor=DarkBlue,
- linkcolor=Blue,
+ colorlinks
}
+\newcommand*{\hlabel}[1]{\phantomsection\label{#1}}
%
\MakeShortVerb{\|}
@@ -41,7 +41,7 @@
\title{Kp-fonts: OpenType version}
\author{\href{mailto:daniel.flipo@free.fr}{Daniel \textsc{Flipo}}}
-\newcommand*{\version}{0.35}
+\newcommand*{\version}{0.36}
\begin{document}
\selectlanguage{british}
@@ -80,14 +80,16 @@
$\symbfup{a}$ $\symbfup{\beta}$ $\symbfup{C}$ $\symbfup{\Delta}$,
$\symbfit{a}$ $\symbfit{\beta}$ $\symbfit{C}$ $\symbfit{\Delta}$.
+% Blackboard Bold capitals are available in two shapes, Serif and Sans:
+% |\mathbb{ABC}| prints either
+% \mathversion{full}$\mathbb{ABC}$ (option |[Style=bbsans]|) or
+% \mathversion{base} $\mathbb{ABC}$ (default).
Blackboard Bold capitals are available in two shapes, Serif and Sans:
|\mathbb{ABC}| prints either
- \mathversion{full}$\mathbb{ABC}$ (option |[Style=bbsans]|) or
- \mathversion{base} $\mathbb{ABC}$ (default).
- Commands |\mathcal{ABC}| and |\mathscr{ABC}| print either
- $\mathscr{ABC}$ (default) or
- \mathversion{full}$\mathscr{ABC}$ with option |[Style=mathcal]|,
- \mathversion{base}.
+ \mathversion{base} $\mathbb{ABC}$ (default) or
+ \mathversion{full}$\mathbb{ABC}$ (option |[Style=bbsans]|)
+ Commands |\mathcal{ABC}| and |\mathscr{ABC}| print respectively
+ \mathversion{full}$\mathcal{ABC}$ and \mathversion{base}$\mathscr{ABC}$.
File \file{unimath-kpfonts.pdf} shows the full list of Unicode Math symbols
provided by Kp-fonts, compared with other common Math fonts.
@@ -190,7 +192,7 @@ and a bunch of Kp-fonts specifics symbols.
\item \textsc{\textbf{\test}}
\end{itemize}
-\item[veryoldstyle:] \label{veryoldstyle} same as option \opt{oldstyle} but
+\item[veryoldstyle:] \hlabel{veryoldstyle} same as option \opt{oldstyle} but
the round `s’ is replaced by the long one
{\addfontfeatures{RawFeature=+hist;+hlig}`s\hspace{1sp}’},
unless it ends a word (then it remains `s’)%
@@ -246,9 +248,9 @@ and a bunch of Kp-fonts specifics symbols.
$\mathbb{C}$, $\mathbb{K}$, $\mathbb{N}$, $\mathbb{Q}$, $\mathbb{R}$,
$\mathbb{Z}$ (default).
-\item[mathcal:] forces commands |\mathcal| and |\mathscr| to print
- \mathversion{full}$\mathcal{A,B,C,D}$ % $\mathscr{ABCD}$
- instead of \mathversion{base} $\mathcal{A,B,C,D}$ (default).
+%\item[mathcal:] forces commands |\mathcal| and |\mathscr| to print
+% \mathversion{full}$\mathcal{A,B,C,D}$ % $\mathscr{ABCD}$
+% instead of \mathversion{base} $\mathcal{A,B,C,D}$ (default).
\item[frenchstyle:] Latin uppercase letters and all Greek letters are
printed upright, only lowercase latin letters are printed in italics;
@@ -263,7 +265,7 @@ and a bunch of Kp-fonts specifics symbols.
\quad instead of \quad
\mathversion{base}$\iiint$ et $\displaystyle\iiint$ (default).
-\enlargethispage*{\baselineskip}
+%\enlargethispage*{\baselineskip}
\item[partialup:] the |\partial| symbol is printed upright $\symup{\partial}$
instead of $\partial$.
@@ -278,6 +280,11 @@ and a bunch of Kp-fonts specifics symbols.
\end{description}
+Option \textsf{\textbf{mathcal}} has been deleted: commands |$\mathcal{ABC}$|
+and |$\mathscr{ABC}$| now print \mathversion{full}$\mathcal{ABC}$ and
+\mathversion{base}$\mathcal{ABC}$ respectively when \pkg{kpfonts-otf.sty}
+is loaded.
+
\section{Another way to load Kp-fonts}
\label{sec:options-standard}
@@ -410,7 +417,7 @@ Seven `Style Variants’ are available with Kp-fonts, here are the first three:
\begin{description}
\item[Style=mathcal] (\texttt{+ss01}) commands |\mathcal{}| and |\mathscr{}|
print \mathversion{full}$\mathcal{ABC}$ instead of
- \mathversion{base}$\mathcal{ABC}$ (default);
+ \mathversion{base}$\mathcal{ABC}$ (default), see note below;
\item[Style=bbsans] (\texttt{+ss02}) |\mathbb{}| prints Sans-Serif
Blackboard bold capitals \mathversion{full}$\mathbb{ABC}$ for Serif Math fonts
@@ -422,11 +429,19 @@ Seven `Style Variants’ are available with Kp-fonts, here are the first three:
\mathversion{base}$\iiint$ (default).
\end{description}
+\textbf{Note:} if you want commands |$\mathcal{ABC}$| and |$\mathscr{ABC}$| to
+print \mathversion{full}$\mathcal{ABC}$ and \mathversion{base}$\mathcal{ABC}$
+repectively, you can use \pkg{unicode-math}’s option |range| this way:\\
+|\setmathfont{KpMath-Regular}[|\optit{options}|]|\\
+|\setmathfont{KpMath-Regular}[range={cal,bfcal},StylisticSet=1]|\\
+The first line loads \family{KpMath} as usual, the second one modifies
+|\mathcal{}| command’s output.
+
\vspace{\baselineskip}
The next four tables present the other Style Variants available:
\\[-.5\baselineskip]
\begin{minipage}[t]{0.45\linewidth}\centering
- \captionof{table}{Style=leqslant (\texttt{+ss04})}\label{ss04}
+ \captionof{table}{Style=leqslant (\texttt{+ss04})}\hlabel{ss04}
\begin{tabular}{@{}lcc@{}}
\hline
Command & Default & Variant \\
@@ -447,7 +462,7 @@ The next four tables present the other Style Variants available:
\end{tabular}
\end{minipage}\hspace{\fill}
\begin{minipage}[t]{0.5\linewidth}\centering
- \captionof{table}{Style=smaller (\texttt{+ss05})}\label{ss05}
+ \captionof{table}{Style=smaller (\texttt{+ss05})}\hlabel{ss05}
\begin{tabular}{@{}lcc@{}}
\hline
Command & Default & Variant \\
@@ -463,7 +478,7 @@ The next four tables present the other Style Variants available:
\end{minipage}
\par\noindent
\begin{minipage}[t]{0.45\linewidth}\centering
- \captionof{table}{Style=subsetneq (\texttt{+ss06})}\label{ss06}
+ \captionof{table}{Style=subsetneq (\texttt{+ss06})}\hlabel{ss06}
\begin{tabular}{@{}lcc@{}}
\hline
Command & Default & Variant \\
@@ -476,7 +491,7 @@ The next four tables present the other Style Variants available:
\end{tabular}
\end{minipage}\hspace{\fill}
\begin{minipage}[t]{0.5\linewidth}\centering
- \captionof{table}{Style=parallelslant (\texttt{+ss07})}\label{ss07}
+ \captionof{table}{Style=parallelslant (\texttt{+ss07})}\hlabel{ss07}
\begin{tabular}{@{}lcc@{}}
\hline
Command & Default & Variant \\
@@ -503,7 +518,7 @@ Table~\vref{cv} shows the available `Glyphs Variants’:
\begin{table}[ht]
\centering
\caption{Glyphs Variants}
- \label{cv}
+ \hlabel{cv}
\begin{tabular}{@{}>{\ttfamily}lccl@{}}
\hline
& Default & Variant & Command\\
diff --git a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf
index 0c06d3fb9c..1c53b58dac 100644
--- a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf
+++ b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-English.pdf
Binary files differ
diff --git a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx
index dff014531e..ef89473660 100644
--- a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx
+++ b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.ltx
@@ -1,3 +1,5 @@
+\RequirePackage{pdfmanagement-testphase}
+\DeclareDocumentMetadata{pdfstandard=A-2b, lang=fr-FR}
\documentclass[paper=a4,french]{scrartcl}
% Packages
\usepackage{graphics, array, varioref}
@@ -18,21 +20,16 @@
\usepackage{babel}
\frenchsetup{og=«, fg=»,%ListItemsAsPar
}
-\usepackage[All]{lua-typo}
+
\usepackage{realscripts}
\usepackage{microtype}
\usepackage{hyperref}
-\hypersetup{pdfcreator={LuaTeX},
+\hypersetup{pdftitle={Mode d’emploi des Kpfonts-otf},
pdfauthor={Daniel FLIPO},
- unicode,
colorlinks,
- urlcolor=DarkBlue,
- linkcolor=Blue,
}
-% Mise en page
-%\setlength{\parindent}{0pt}
-%\renewcommand{\arraystretch}{1.3}
-
+\newcommand*{\hlabel}[1]{\phantomsection\label{#1}}
+%
\MakeShortVerb{\|}
\newcommand*{\pkg}[1]{\texttt{#1}}
@@ -46,7 +43,7 @@
\title{Kp-fonts version OpenType}
\author{\href{mailto:daniel.flipo@free.fr}{Daniel \textsc{Flipo}}}
-\newcommand*{\version}{0.35}
+\newcommand*{\version}{0.36}
\begin{document}
\maketitle
@@ -86,14 +83,14 @@
$\symbfup{a}$ $\symbfup{\beta}$ $\symbfup{C}$ $\symbfup{\Delta}$,
$\symbfit{a}$ $\symbfit{\beta}$ $\symbfit{C}$ $\symbfit{\Delta}$.
- la commande |\mathbb{ABC}| affiche au choix
- \mathversion{full}$\mathbb{ABC}$ (option |Style=bbsans|) ou
- \mathversion{base} $\mathbb{ABC}$ par défaut,
- les commandes |\mathcal{ABC}| et |\mathscr{ABC}| affichent
- $\mathscr{ABC}$ par défaut ou
- \mathversion{full}$\mathscr{ABC}$ avec l’option |Style=mathcal|,
- \mathversion{base}
- tandis que la commande |\mathfrak{ABCabc}| affiche $\mathfrak{ABCabc}$.
+ La commande |\mathbb{ABC}| affiche au choix
+ \mathversion{base} $\mathbb{ABC}$ par défaut ou
+ \mathversion{full}$\mathbb{ABC}$ avec l’option |Style=bbsans|,
+ deux versions des capitales calligraphiées
+ sont disponibles : |\mathcal{ABC}| et |\mathscr{ABC}| affichent
+ respectivement \mathversion{full}$\mathcal{ABC}$ et
+ \mathversion{base}$\mathcal{ABC}$ ;
+ la commande |\mathfrak{ABCabc}| affiche $\mathfrak{ABCabc}$.
La liste complète des symboles mathématiques présents dans Unicode et
disponibles dans les polices \family{KpMath} est présentée dans
@@ -207,7 +204,7 @@ Notez que ces options n'affectent que les polices de texte.
\item \textsc{\textbf{\test}}
\end{itemize}
-\item[veryoldstyle :] \label{veryoldstyle}
+\item[veryoldstyle :] \hlabel{veryoldstyle}
identique à l'option \opt{oldstyle} mais en plus le « s » rond est
remplacé par le « {\addfontfeatures{RawFeature=+hist;+hlig}s} » long
sauf en fin de mot (où il doit rester rond) et les ligatures
@@ -276,10 +273,10 @@ Notez que ces options n'affectent que les polices de texte.
$\mathbb{C}$, $\mathbb{K}$, $\mathbb{N}$, $\mathbb{Q}$, $\mathbb{R}$,
$\mathbb{Z}$.
-\item[mathcal :] cette option modifie l’effet des commandes
- |\mathcal| et |\mathscr|, elles produisent toutes les deux
- \mathversion{full}$\mathcal{ABCD}$ % $\mathscr{ABCD}$
- alors que par défaut \mathversion{base} on a $\mathcal{ABCD}$.
+%\item[mathcal :] cette option modifie l’effet des commandes
+% |\mathcal| et |\mathscr|, elles produisent toutes les deux
+% \mathversion{full}$\mathcal{ABCD}$ % $\mathscr{ABCD}$
+% alors que par défaut \mathversion{base} on a $\mathcal{ABCD}$.
\item[frenchstyle :] les majuscules romaines et toutes les lettres grecques
(majuscules ou minuscules) sont droites, selon la tradition typographique
@@ -310,7 +307,12 @@ Notez que ces options n'affectent que les polices de texte.
\end{description}
-\enlargethispage*{2\baselineskip}
+L’option \textsf{\textbf{mathcal}} a été supprimée : désormais, les commandes
+|$\mathcal{ABC}$| et |$\mathscr{ABC}$| affichent respectivement
+\mathversion{full}$\mathcal{ABC}$ et \mathversion{base}$\mathcal{ABC}$
+lorsque \pkg{kpfonts-otf.sty} est chargé.
+
+%\enlargethispage*{2\baselineskip}
\section{Autre façon de charger les Kp-fonts}
\label{sec:options-standard}
@@ -449,7 +451,7 @@ trois premières :
\begin{description}
\item[Style=mathcal] (\texttt{+ss01}) les commandes |\mathcal{}| et
|\mathscr{}| produisent \mathversion{full}$\mathcal{ABC}$
- au lieu de \mathversion{base}$\mathcal{ABC}$ ;
+ au lieu de \mathversion{base}$\mathcal{ABC}$ (voir remarque ci-dessous) ;
\item[Style=bbsans] (\texttt{+ss02}) les glyphes produits par la commande
|\mathbb{}| sont en sans-serif \mathversion{full}$\mathbb{ABC}$ au lieu de
@@ -460,10 +462,20 @@ trois premières :
\mathversion{base}$\iiint$.
\end{description}
+\textbf{Remarque :} pour que |$\mathcal{ABC}$| et |$\mathscr{ABC}$| affichent
+respectivement \mathversion{full}$\mathcal{ABC}$ et
+\mathversion{base}$\mathcal{ABC}$,
+on peut utiliser l’option |range| de \pkg{unicode-math} comme ceci :\\
+|\setmathfont{KpMath-Regular}[|\optit{options}|]|\\
+|\setmathfont{KpMath-Regular}[range={cal,bfcal},StylisticSet=1]|\\
+Les \emph{deux} lignes sont nécessaires : la première ligne charge
+\family{KpMath} normalement, la seconde modifie la sortie de la commande
+|\mathcal{}|.
+
Les quatre tables suivantes recensent les autres variantes de style proposées.
\nopagebreak\par\noindent
\begin{minipage}[t]{0.45\linewidth}\centering
- \captionof{table}{Style=leqslant (\texttt{+ss04})} \label{ss04}
+ \captionof{table}{Style=leqslant (\texttt{+ss04})} \hlabel{ss04}
\begin{tabular}[t]{@{}lcc@{}}
\hline
Commande & Base & Variante \\
@@ -484,7 +496,7 @@ Les quatre tables suivantes recensent les autres variantes de style proposées.
\end{tabular}
\end{minipage}\hspace{\fill}
\begin{minipage}[t]{0.5\linewidth}\centering
- \captionof{table}{Style=smaller (\texttt{+ss05})}\label{ss05}
+ \captionof{table}{Style=smaller (\texttt{+ss05})}\hlabel{ss05}
\begin{tabular}[t]{@{}lcc@{}}
\hline
Commande & Base & Variante \\
@@ -500,7 +512,7 @@ Les quatre tables suivantes recensent les autres variantes de style proposées.
\end{minipage}
\par\noindent
\begin{minipage}[t]{0.45\linewidth}\centering
- \captionof{table}{Style=subsetneq (\texttt{+ss06})}\label{ss06}
+ \captionof{table}{Style=subsetneq (\texttt{+ss06})}\hlabel{ss06}
\begin{tabular}[t]{@{}lcc@{}}
\hline
Commande & Base & Variante \\
@@ -513,7 +525,7 @@ Les quatre tables suivantes recensent les autres variantes de style proposées.
\end{tabular}
\end{minipage}\hspace{\fill}
\begin{minipage}[t]{0.5\linewidth}\centering
- \captionof{table}{Style=parallelslant (\texttt{+ss07})}\label{ss07}
+ \captionof{table}{Style=parallelslant (\texttt{+ss07})}\hlabel{ss07}
\begin{tabular}[t]{@{}lcc@{}}
\hline
Commande & Base & Variante \\
@@ -540,7 +552,7 @@ La table~\vref{cv} recense les variantes de glyphes proposées.
\begin{table}[ht]
\centering
\caption{Variantes de glyphes}
- \label{cv}
+ \hlabel{cv}
\begin{tabular}{@{}>{\ttfamily}lccl@{}}
\hline
& Base & Variante & Commande\\
diff --git a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf
index 7e74e307fe..8795cc84cb 100644
--- a/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf
+++ b/fonts/kpfonts-otf/doc/Kpfonts-OTF-Doc-French.pdf
Binary files differ
diff --git a/fonts/kpfonts-otf/doc/unimath-kpfonts.pdf b/fonts/kpfonts-otf/doc/unimath-kpfonts.pdf
index a95fe93dc9..8fea46f8ac 100644
--- a/fonts/kpfonts-otf/doc/unimath-kpfonts.pdf
+++ b/fonts/kpfonts-otf/doc/unimath-kpfonts.pdf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMath-Bold.otf b/fonts/kpfonts-otf/fonts/KpMath-Bold.otf
index 04082f75ff..bec81e0070 100644
--- a/fonts/kpfonts-otf/fonts/KpMath-Bold.otf
+++ b/fonts/kpfonts-otf/fonts/KpMath-Bold.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMath-Light.otf b/fonts/kpfonts-otf/fonts/KpMath-Light.otf
index c874d9ebc9..8141fa8cb2 100644
--- a/fonts/kpfonts-otf/fonts/KpMath-Light.otf
+++ b/fonts/kpfonts-otf/fonts/KpMath-Light.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMath-Regular.otf b/fonts/kpfonts-otf/fonts/KpMath-Regular.otf
index 17185f8865..c0a39bd7cc 100644
--- a/fonts/kpfonts-otf/fonts/KpMath-Regular.otf
+++ b/fonts/kpfonts-otf/fonts/KpMath-Regular.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMath-Sans.otf b/fonts/kpfonts-otf/fonts/KpMath-Sans.otf
index 021ca063b9..d404da41ef 100644
--- a/fonts/kpfonts-otf/fonts/KpMath-Sans.otf
+++ b/fonts/kpfonts-otf/fonts/KpMath-Sans.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMath-Semibold.otf b/fonts/kpfonts-otf/fonts/KpMath-Semibold.otf
index d7530476b9..0c5b50be6a 100644
--- a/fonts/kpfonts-otf/fonts/KpMath-Semibold.otf
+++ b/fonts/kpfonts-otf/fonts/KpMath-Semibold.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMono-Bold.otf b/fonts/kpfonts-otf/fonts/KpMono-Bold.otf
index d2de74d8b2..d587fc63d7 100644
--- a/fonts/kpfonts-otf/fonts/KpMono-Bold.otf
+++ b/fonts/kpfonts-otf/fonts/KpMono-Bold.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf b/fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf
index 8066ae6136..67f1329514 100644
--- a/fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf
+++ b/fonts/kpfonts-otf/fonts/KpMono-BoldItalic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMono-Italic.otf b/fonts/kpfonts-otf/fonts/KpMono-Italic.otf
index 3d25604b24..7f13960415 100644
--- a/fonts/kpfonts-otf/fonts/KpMono-Italic.otf
+++ b/fonts/kpfonts-otf/fonts/KpMono-Italic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpMono-Regular.otf b/fonts/kpfonts-otf/fonts/KpMono-Regular.otf
index 945d10385b..c0adddfaa1 100644
--- a/fonts/kpfonts-otf/fonts/KpMono-Regular.otf
+++ b/fonts/kpfonts-otf/fonts/KpMono-Regular.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-Bold.otf b/fonts/kpfonts-otf/fonts/KpRoman-Bold.otf
index 5866731d13..2f9eedcfc7 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-Bold.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-Bold.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf b/fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf
index 5a4e0a11c7..ca2ef0ffe1 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-BoldItalic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-Italic.otf b/fonts/kpfonts-otf/fonts/KpRoman-Italic.otf
index a5f5ab9410..a60ba1bae9 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-Italic.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-Italic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-Light.otf b/fonts/kpfonts-otf/fonts/KpRoman-Light.otf
index 4edc9c4652..f486883683 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-Light.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-Light.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf b/fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf
index cf4c18de5b..8ee3ae544d 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-LightItalic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-Regular.otf b/fonts/kpfonts-otf/fonts/KpRoman-Regular.otf
index 4c98236c84..c325b735e1 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-Regular.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-Regular.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf b/fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf
index 98e80e1021..ee26b8102b 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-Semibold.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf b/fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf
index df16f0329b..f44e9c486c 100644
--- a/fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf
+++ b/fonts/kpfonts-otf/fonts/KpRoman-SemiboldItalic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpSans-Bold.otf b/fonts/kpfonts-otf/fonts/KpSans-Bold.otf
index 43c4a4f0cf..42d8aa36e9 100644
--- a/fonts/kpfonts-otf/fonts/KpSans-Bold.otf
+++ b/fonts/kpfonts-otf/fonts/KpSans-Bold.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf b/fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf
index ba68320c71..54fd23602b 100644
--- a/fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf
+++ b/fonts/kpfonts-otf/fonts/KpSans-BoldItalic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpSans-Italic.otf b/fonts/kpfonts-otf/fonts/KpSans-Italic.otf
index e7d68286ab..c9f86c39eb 100644
--- a/fonts/kpfonts-otf/fonts/KpSans-Italic.otf
+++ b/fonts/kpfonts-otf/fonts/KpSans-Italic.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/fonts/KpSans-Regular.otf b/fonts/kpfonts-otf/fonts/KpSans-Regular.otf
index f3ed871b8f..e7297a33b7 100644
--- a/fonts/kpfonts-otf/fonts/KpSans-Regular.otf
+++ b/fonts/kpfonts-otf/fonts/KpSans-Regular.otf
Binary files differ
diff --git a/fonts/kpfonts-otf/tex/kpfonts-otf.sty b/fonts/kpfonts-otf/tex/kpfonts-otf.sty
index 0630b74ed2..b182d5f199 100644
--- a/fonts/kpfonts-otf/tex/kpfonts-otf.sty
+++ b/fonts/kpfonts-otf/tex/kpfonts-otf.sty
@@ -1,6 +1,6 @@
\NeedsTeXFormat{LaTeX2e}[2019-01-01]
-\def\fileversion{0.35}
-\def\filedate{2021-03-14}
+\def\fileversion{0.36}
+\def\filedate{2021-05-21}
\ProvidesPackage{kpfonts-otf}[\filedate\space\fileversion]
% Ensure luatex or xetex engine
@@ -179,6 +179,12 @@
\fi
% Loading Math fonts...
+\newcommand*{\KP@mathcal@Warning}{%
+ \PackageWarning{kpfonts-otf}{Option mathcal is no longer needed:\MessageBreak
+ just use \protect\mathcal{} for "calligraphic" \MessageBreak
+ and \protect\mathscr{} for "script" capitals;\MessageBreak reported
+ }%
+}
\ifkp@math
\ifkp@tight
\thinmuskip=2mu
@@ -187,7 +193,7 @@
\fi
\ifkp@lightmath
\ifkp@calasscr
- \Store@KP@MOption{RawFeature}{+ss01}
+ \KP@mathcal@Warning
\fi
\ifkp@sfmathbb
\Store@KP@MOption{RawFeature}{+ss02}
@@ -208,9 +214,10 @@
\Store@KP@MOption{partial}{upright}
\fi
\expandafter\setmathfont\expandafter[\the\KpMtoks]{KpMath-Light.otf}
+ \setmathfont[range={cal,bfcal},RawFeature=+ss01]{KpMath-Light.otf}
\else
\ifkp@calasscr
- \Store@KP@MOption{RawFeature}{+ss01}
+ \KP@mathcal@Warning
\fi
\ifkp@sfmathbb
\Store@KP@MOption{RawFeature}{+ss02}
@@ -231,6 +238,7 @@
\Store@KP@MOption{partial}{upright}
\fi
\expandafter\setmathfont\expandafter[\the\KpMtoks]{KpMath-Regular.otf}
+ \setmathfont[range={cal,bfcal},RawFeature=+ss01]{KpMath-Regular.otf}
\fi
\fi
diff --git a/fonts/newpx/README b/fonts/newpx/README
index 3b5cf277a0..529f2a2d91 100644
--- a/fonts/newpx/README
+++ b/fonts/newpx/README
@@ -1,10 +1,15 @@
This package, based initially on pxfonts, provides many fixes and enhancements to that package, splitting it in two parts---newpxtext and newpxmath---which may be run independently of one another. It provides scaling, improved metrics, and other options. For proper operation, the packages require that the packages newtxmath, pxfonts and TeXGyrePagella be installed and their map files enabled. The text package now relies on an extension of the TeXGyrePagella Type1 fonts that is provided with this package. The accompanying MANIFEST-newpx.txt provides details of the extension as requested by GUST-FONT-LICENSE.txt
-Current version: 1.415 2021-03-24
+Current version: 1.42 2021-05-21
This material is subject to the LaTeX Project Public License. See http://www.ctan.org/license/lppl1.3
for the details of that license.
+Changes in version 1.42
+1. Added a new text family, npxth, to accommodate the theorem font which is available only in regular weight, italic shape. (In previous versions, the theorem font was accessed as the slanted shape, which turned out to be a bad decision on my part.)
+2. Added true slanted shapes and a new option, trueslanted, to newtxtext. If this option is not specified, newtxtext behaves exactly as in the previous version, with \textsl producing italic with upright punctation. If specified, \textsl produces true slanted text. It is strongly recommended to always use this option in order to get the correct behavior of figures in header text made after specifying \pagestyle{headings}. The only cost will be that you cannot use \textsl to invokee the theorem font. The substitute is \textth or, equivalently, \textthit.
+3. Corrected the mismatched sizes of some extended math parentheses. (Thanks Kazuki Maeda.)
+
Changes in version 1.415
1. Added same corrections to math fonts as in newtx 1.641.
2. Added new lowercase letters to the math BB alphabet addressed by the option varbb.
diff --git a/fonts/newpx/afm/zplbsl.afm b/fonts/newpx/afm/zplbsl.afm
new file mode 100644
index 0000000000..d4bdb1583b
--- /dev/null
+++ b/fonts/newpx/afm/zplbsl.afm
@@ -0,0 +1,13281 @@
+StartFontMetrics 2.0
+Comment Generated by FontForge 20200314
+Comment Creation Date: Thu May 20 11:44:42 2021
+FontName TeXGyrePagellaX-BoldSlanted
+FullName TeXGyrePagellaX-BoldSlanted
+FamilyName TeXGyrePagellaX
+Weight Bold
+Notice (Copyright 2006, 2009 for TeX Gyre extensions by B. Jackowski and J.M. Nowacki (on behalf of TeX users groups). This work is released under the GUST Font License -- see http://tug.org/fonts/licenses/G)
+Comment UST-FONT-LICENSE.txt for details.
+Comment
+Comment Copyright (c) 2015--2021 Michael Sharpe for added superior figures, letters and symbols.
+ItalicAngle -10
+IsFixedPitch false
+UnderlinePosition -50
+UnderlineThickness 50
+Version 2.004
+EncodingScheme ISO10646-1
+FontBBox -468 -267 1343 1097
+CapHeight 678
+XHeight 459
+Ascender 645
+Descender -250
+StartCharMetrics 1185
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 72 -12 340 688 ;
+C 34 ; WX 402 ; N quotedbl ; B 131 376 491 695 ;
+C 35 ; WX 500 ; N numbersign ; B 42 0 579 673 ;
+C 36 ; WX 500 ; N dollar ; B 36 -114 545 721 ;
+C 37 ; WX 889 ; N percent ; B 152 -9 860 714 ;
+C 38 ; WX 833 ; N ampersand ; B 79 -17 859 684 ;
+C 39 ; WX 227 ; N quotesingle ; B 154 376 292 695 ;
+C 40 ; WX 333 ; N parenleft ; B 110 -104 429 723 ;
+C 41 ; WX 333 ; N parenright ; B 14 -104 332 723 ;
+C 42 ; WX 444 ; N asterisk ; B 125 332 488 695 ;
+C 43 ; WX 606 ; N plus ; B 82 -7 612 507 ;
+C 44 ; WX 250 ; N comma ; B -33 -166 249 141 ;
+C 45 ; WX 333 ; N hyphen ; B 52 195 369 305 ;
+C 46 ; WX 250 ; N period ; B 56 -12 216 144 ;
+C 47 ; WX 296 ; N slash ; B -12 -17 432 720 ;
+C 48 ; WX 500 ; N zero ; B 72 -17 544 660 ;
+C 49 ; WX 500 ; N one ; B 74 -3 462 670 ;
+C 50 ; WX 500 ; N two ; B 24 -3 530 660 ;
+C 51 ; WX 500 ; N three ; B 48 -17 512 660 ;
+C 52 ; WX 500 ; N four ; B 48 -3 512 672 ;
+C 53 ; WX 500 ; N five ; B 67 -17 562 656 ;
+C 54 ; WX 500 ; N six ; B 75 -17 547 660 ;
+C 55 ; WX 500 ; N seven ; B 89 -3 608 656 ;
+C 56 ; WX 500 ; N eight ; B 58 -17 531 660 ;
+C 57 ; WX 500 ; N nine ; B 69 -17 541 660 ;
+C 58 ; WX 250 ; N colon ; B 56 -12 271 454 ;
+C 59 ; WX 250 ; N semicolon ; B -33 -166 294 454 ;
+C 60 ; WX 606 ; N less ; B 110 -2 603 502 ;
+C 61 ; WX 606 ; N equal ; B 68 122 627 378 ;
+C 62 ; WX 606 ; N greater ; B 73 -2 565 502 ;
+C 63 ; WX 444 ; N question ; B 125 -12 507 687 ;
+C 64 ; WX 747 ; N at ; B 94 -12 779 681 ;
+C 65 ; WX 778 ; N A ; B 23 -3 763 686 ;
+C 66 ; WX 667 ; N B ; B 71 -3 687 681 ;
+C 67 ; WX 722 ; N C ; B 98 -17 807 695 ;
+C 68 ; WX 833 ; N D ; B 67 -3 860 681 ;
+C 69 ; WX 611 ; N E ; B 71 -3 684 681 ;
+C 70 ; WX 556 ; N F ; B 27 -3 657 681 ;
+C 71 ; WX 833 ; N G ; B 101 -17 840 695 ;
+C 72 ; WX 833 ; N H ; B 35 -3 916 681 ;
+C 73 ; WX 389 ; N I ; B 38 -3 470 681 ; L J IJ ;
+C 74 ; WX 389 ; N J ; B -48 -213 470 681 ;
+C 75 ; WX 778 ; N K ; B 38 -3 858 681 ;
+C 76 ; WX 611 ; N L ; B 71 -3 608 681 ;
+C 77 ; WX 1000 ; N M ; B 31 -10 1088 681 ;
+C 78 ; WX 833 ; N N ; B 34 -16 918 681 ;
+C 79 ; WX 833 ; N O ; B 98 -17 856 695 ;
+C 80 ; WX 611 ; N P ; B 38 -3 691 681 ;
+C 81 ; WX 833 ; N Q ; B 97 -184 856 695 ;
+C 82 ; WX 722 ; N R ; B 38 -3 715 681 ;
+C 83 ; WX 611 ; N S ; B 62 -17 633 695 ;
+C 84 ; WX 667 ; N T ; B 121 -3 769 681 ;
+C 85 ; WX 778 ; N U ; B 139 -17 880 681 ;
+C 86 ; WX 778 ; N V ; B 134 -3 883 681 ;
+C 87 ; WX 1000 ; N W ; B 131 -3 1108 686 ;
+C 88 ; WX 667 ; N X ; B 17 -3 769 695 ;
+C 89 ; WX 667 ; N Y ; B 125 -3 780 695 ;
+C 90 ; WX 667 ; N Z ; B 23 -3 743 681 ;
+C 91 ; WX 333 ; N bracketleft ; B 55 -104 418 720 ;
+C 92 ; WX 606 ; N backslash ; B 199 0 534 720 ;
+C 93 ; WX 333 ; N bracketright ; B 24 -104 387 720 ;
+C 94 ; WX 606 ; N asciicircum ; B 100 275 602 678 ;
+C 95 ; WX 500 ; N underscore ; B -22 -125 487 -75 ;
+C 96 ; WX 333 ; N grave ; B 130 506 344 691 ;
+C 97 ; WX 500 ; N a ; B 55 -17 484 471 ;
+C 98 ; WX 611 ; N b ; B 79 -17 610 720 ;
+C 99 ; WX 444 ; N c ; B 70 -17 487 471 ;
+C 100 ; WX 611 ; N d ; B 74 -17 634 720 ;
+C 101 ; WX 500 ; N e ; B 75 -17 517 471 ;
+C 102 ; WX 389 ; N f ; B 33 -3 507 720 ; L l fl ; L i fi ; L f ff ; L k f_k ;
+C 103 ; WX 556 ; N g ; B 2 -266 610 471 ;
+C 104 ; WX 611 ; N h ; B 23 -3 593 720 ;
+C 105 ; WX 333 ; N i ; B 33 -3 347 706 ; L j ij ;
+C 106 ; WX 333 ; N j ; B -37 -266 347 706 ;
+C 107 ; WX 611 ; N k ; B 28 -3 646 720 ;
+C 108 ; WX 333 ; N l ; B 31 -3 351 720 ;
+C 109 ; WX 889 ; N m ; B 23 -3 870 471 ;
+C 110 ; WX 611 ; N n ; B 23 -3 593 471 ;
+C 111 ; WX 556 ; N o ; B 73 -17 565 471 ;
+C 112 ; WX 611 ; N p ; B -16 -258 621 471 ;
+C 113 ; WX 611 ; N q ; B 83 -258 614 471 ;
+C 114 ; WX 389 ; N r ; B 29 -3 471 471 ;
+C 115 ; WX 444 ; N s ; B 41 -17 449 471 ;
+C 116 ; WX 333 ; N t ; B 86 -17 399 632 ;
+C 117 ; WX 611 ; N u ; B 94 -17 596 471 ;
+C 118 ; WX 556 ; N v ; B 85 -3 626 459 ;
+C 119 ; WX 833 ; N w ; B 87 -3 901 471 ;
+C 120 ; WX 500 ; N x ; B 21 -3 564 471 ;
+C 121 ; WX 556 ; N y ; B -13 -266 627 459 ;
+C 122 ; WX 500 ; N z ; B 15 -3 535 458 ;
+C 123 ; WX 310 ; N braceleft ; B 58 -117 416 725 ;
+C 124 ; WX 606 ; N bar ; B 242 -104 473 720 ;
+C 125 ; WX 310 ; N braceright ; B 1 -117 358 725 ;
+C 126 ; WX 606 ; N asciitilde ; B 89 174 606 329 ;
+C 160 ; WX 333 ; N uni00A0 ; B 0 0 0 0 ;
+C 161 ; WX 278 ; N exclamdown ; B 18 -234 286 466 ;
+C 162 ; WX 500 ; N cent ; B 104 -106 524 554 ;
+C 163 ; WX 500 ; N sterling ; B 5 -19 594 676 ;
+C 164 ; WX 500 ; N currency ; B 57 96 553 533 ;
+C 165 ; WX 500 ; N yen ; B 102 -3 603 695 ;
+C 166 ; WX 606 ; N brokenbar ; B 242 -104 473 720 ;
+C 167 ; WX 500 ; N section ; B 19 -217 541 695 ;
+C 168 ; WX 333 ; N dieresis ; B 96 532 448 666 ;
+C 169 ; WX 747 ; N copyright ; B 74 -16 793 691 ;
+C 170 ; WX 438 ; N ordfeminine ; B 128 288 431 660 ;
+C 171 ; WX 500 ; N guillemotleft ; B 77 44 536 438 ;
+C 172 ; WX 606 ; N logicalnot ; B 97 165 627 378 ;
+C 173 ; WX 333 ; N uni00AD ; B 52 195 369 305 ;
+C 174 ; WX 747 ; N registered ; B 74 -16 793 691 ;
+C 175 ; WX 333 ; N macron ; B 100 564 444 635 ;
+C 176 ; WX 400 ; N degree ; B 137 360 443 660 ;
+C 177 ; WX 606 ; N plusminus ; B 46 0 627 593 ;
+C 178 ; WX 300 ; N two.superior ; B 58 259 367 657 ;
+C 179 ; WX 300 ; N three.superior ; B 72 251 357 657 ;
+C 180 ; WX 333 ; N acute ; B 167 506 431 691 ;
+C 181 ; WX 611 ; N uni00B5 ; B 56 -225 596 471 ;
+C 182 ; WX 641 ; N paragraph ; B 109 -161 719 683 ;
+C 183 ; WX 250 ; N periodcentered ; B 89 172 249 328 ;
+C 184 ; WX 333 ; N cedilla ; B 36 -225 278 7 ;
+C 185 ; WX 300 ; N one.superior ; B 88 259 328 663 ;
+C 186 ; WX 488 ; N ordmasculine ; B 140 288 494 660 ;
+C 187 ; WX 500 ; N guillemotright ; B 48 44 509 438 ;
+C 188 ; WX 750 ; N onequarter ; B 91 -2 776 665 ;
+C 189 ; WX 750 ; N onehalf ; B 81 -2 778 665 ;
+C 190 ; WX 750 ; N threequarters ; B 79 -2 760 667 ;
+C 191 ; WX 444 ; N questiondown ; B 17 -233 399 466 ;
+C 192 ; WX 778 ; N Agrave ; B 23 -3 763 884 ;
+C 193 ; WX 778 ; N Aacute ; B 23 -3 763 884 ;
+C 194 ; WX 778 ; N Acircumflex ; B 23 -3 763 881 ;
+C 195 ; WX 778 ; N Atilde ; B 23 -3 763 872 ;
+C 196 ; WX 778 ; N Adieresis ; B 23 -3 763 876 ;
+C 197 ; WX 778 ; N Aring ; B 23 -3 763 926 ;
+C 198 ; WX 1000 ; N AE ; B 11 -4 1061 682 ;
+C 199 ; WX 722 ; N Ccedilla ; B 98 -225 807 695 ;
+C 200 ; WX 611 ; N Egrave ; B 71 -3 684 884 ;
+C 201 ; WX 611 ; N Eacute ; B 71 -3 684 884 ;
+C 202 ; WX 611 ; N Ecircumflex ; B 71 -3 684 881 ;
+C 203 ; WX 611 ; N Edieresis ; B 71 -3 684 876 ;
+C 204 ; WX 389 ; N Igrave ; B 38 -3 470 884 ;
+C 205 ; WX 389 ; N Iacute ; B 38 -3 491 884 ;
+C 206 ; WX 389 ; N Icircumflex ; B 38 -3 507 881 ;
+C 207 ; WX 389 ; N Idieresis ; B 38 -3 514 876 ;
+C 208 ; WX 833 ; N Eth ; B 67 -3 860 681 ;
+C 209 ; WX 833 ; N Ntilde ; B 34 -16 918 872 ;
+C 210 ; WX 833 ; N Ograve ; B 98 -17 856 884 ;
+C 211 ; WX 833 ; N Oacute ; B 98 -17 856 884 ;
+C 212 ; WX 833 ; N Ocircumflex ; B 98 -17 856 881 ;
+C 213 ; WX 833 ; N Otilde ; B 98 -17 856 872 ;
+C 214 ; WX 833 ; N Odieresis ; B 98 -17 856 876 ;
+C 215 ; WX 606 ; N multiply ; B 108 38 586 462 ;
+C 216 ; WX 833 ; N Oslash ; B 36 -20 924 698 ;
+C 217 ; WX 778 ; N Ugrave ; B 139 -17 880 884 ;
+C 218 ; WX 778 ; N Uacute ; B 139 -17 880 884 ;
+C 219 ; WX 778 ; N Ucircumflex ; B 139 -17 880 881 ;
+C 220 ; WX 778 ; N Udieresis ; B 139 -17 880 876 ;
+C 221 ; WX 667 ; N Yacute ; B 125 -3 780 884 ;
+C 222 ; WX 611 ; N Thorn ; B 38 -3 648 681 ;
+C 223 ; WX 611 ; N germandbls ; B 29 -17 626 720 ;
+C 224 ; WX 500 ; N agrave ; B 55 -17 484 691 ;
+C 225 ; WX 500 ; N aacute ; B 55 -17 524 691 ;
+C 226 ; WX 500 ; N acircumflex ; B 55 -17 518 687 ;
+C 227 ; WX 500 ; N atilde ; B 55 -17 559 662 ;
+C 228 ; WX 500 ; N adieresis ; B 55 -17 541 666 ;
+C 229 ; WX 500 ; N aring ; B 55 -17 484 699 ;
+C 230 ; WX 778 ; N ae ; B 62 -17 787 471 ;
+C 231 ; WX 444 ; N ccedilla ; B 70 -225 487 471 ;
+C 232 ; WX 500 ; N egrave ; B 75 -17 517 691 ;
+C 233 ; WX 500 ; N eacute ; B 75 -17 535 691 ;
+C 234 ; WX 500 ; N ecircumflex ; B 75 -17 529 687 ;
+C 235 ; WX 500 ; N edieresis ; B 75 -17 552 666 ;
+C 236 ; WX 333 ; N igrave ; B 33 -3 344 691 ;
+C 237 ; WX 333 ; N iacute ; B 33 -3 430 691 ;
+C 238 ; WX 333 ; N icircumflex ; B 33 -3 424 687 ;
+C 239 ; WX 333 ; N idieresis ; B 33 -3 447 666 ;
+C 240 ; WX 556 ; N eth ; B 73 -17 591 720 ;
+C 241 ; WX 611 ; N ntilde ; B 23 -3 606 662 ;
+C 242 ; WX 556 ; N ograve ; B 73 -17 565 691 ;
+C 243 ; WX 556 ; N oacute ; B 73 -17 565 691 ;
+C 244 ; WX 556 ; N ocircumflex ; B 73 -17 565 687 ;
+C 245 ; WX 556 ; N otilde ; B 73 -17 576 662 ;
+C 246 ; WX 556 ; N odieresis ; B 73 -17 565 666 ;
+C 247 ; WX 606 ; N divide ; B 82 2 612 498 ;
+C 248 ; WX 556 ; N oslash ; B 24 -18 613 471 ;
+C 249 ; WX 611 ; N ugrave ; B 94 -17 596 691 ;
+C 250 ; WX 611 ; N uacute ; B 94 -17 596 691 ;
+C 251 ; WX 611 ; N ucircumflex ; B 94 -17 596 687 ;
+C 252 ; WX 611 ; N udieresis ; B 94 -17 596 666 ;
+C 253 ; WX 556 ; N yacute ; B -13 -266 627 691 ;
+C 254 ; WX 611 ; N thorn ; B -20 -258 617 720 ;
+C 255 ; WX 556 ; N ydieresis ; B -13 -266 627 666 ;
+C -1 ; WX 778 ; N Amacron ; B 23 -3 763 845 ;
+C -1 ; WX 500 ; N amacron ; B 55 -17 537 635 ;
+C -1 ; WX 778 ; N Abreve ; B 23 -3 763 876 ;
+C -1 ; WX 500 ; N abreve ; B 55 -17 531 681 ;
+C -1 ; WX 778 ; N Aogonek ; B 23 -250 763 686 ;
+C -1 ; WX 500 ; N aogonek ; B 55 -250 484 471 ;
+C -1 ; WX 722 ; N Cacute ; B 98 -17 807 884 ;
+C -1 ; WX 444 ; N cacute ; B 70 -17 523 691 ;
+C -1 ; WX 722 ; N Ccircumflex ; B 98 -17 807 881 ;
+C -1 ; WX 444 ; N ccircumflex ; B 70 -17 517 687 ;
+C -1 ; WX 722 ; N Cdotaccent ; B 98 -17 807 876 ;
+C -1 ; WX 444 ; N cdotaccent ; B 70 -17 487 666 ;
+C -1 ; WX 722 ; N Ccaron ; B 98 -17 807 881 ;
+C -1 ; WX 444 ; N ccaron ; B 70 -17 548 687 ;
+C -1 ; WX 833 ; N Dcaron ; B 67 -3 860 881 ;
+C -1 ; WX 611 ; N dcaron ; B 74 -17 837 720 ;
+C -1 ; WX 833 ; N Dcroat ; B 67 -3 860 681 ;
+C -1 ; WX 611 ; N dcroat ; B 74 -17 693 720 ;
+C -1 ; WX 611 ; N Emacron ; B 71 -3 684 845 ;
+C -1 ; WX 500 ; N emacron ; B 75 -17 548 635 ;
+C -1 ; WX 611 ; N Ebreve ; B 71 -3 684 876 ;
+C -1 ; WX 500 ; N ebreve ; B 75 -17 542 681 ;
+C -1 ; WX 611 ; N Edotaccent ; B 71 -3 684 876 ;
+C -1 ; WX 500 ; N edotaccent ; B 75 -17 517 666 ;
+C -1 ; WX 611 ; N Eogonek ; B 71 -250 684 681 ;
+C -1 ; WX 500 ; N eogonek ; B 75 -250 517 471 ;
+C -1 ; WX 611 ; N Ecaron ; B 71 -3 684 881 ;
+C -1 ; WX 500 ; N ecaron ; B 75 -17 560 687 ;
+C -1 ; WX 833 ; N Gcircumflex ; B 101 -17 840 881 ;
+C -1 ; WX 556 ; N gcircumflex ; B 2 -266 610 687 ;
+C -1 ; WX 833 ; N Gbreve ; B 101 -17 840 876 ;
+C -1 ; WX 556 ; N gbreve ; B 2 -266 610 681 ;
+C -1 ; WX 833 ; N Gdotaccent ; B 101 -17 840 876 ;
+C -1 ; WX 556 ; N gdotaccent ; B 2 -266 610 666 ;
+C -1 ; WX 833 ; N Gcommaaccent ; B 101 -258 840 695 ;
+C -1 ; WX 556 ; N gcommaaccent ; B 2 -266 610 718 ;
+C -1 ; WX 833 ; N Hcircumflex ; B 35 -3 916 881 ;
+C -1 ; WX 611 ; N hcircumflex ; B 23 -3 625 920 ;
+C -1 ; WX 833 ; N Hbar ; B 35 -3 916 681 ;
+C -1 ; WX 655 ; N hbar ; B 45 -3 615 720 ;
+C -1 ; WX 389 ; N Itilde ; B 38 -3 532 872 ;
+C -1 ; WX 333 ; N itilde ; B 33 -3 465 662 ;
+C -1 ; WX 389 ; N Imacron ; B 38 -3 510 845 ;
+C -1 ; WX 333 ; N imacron ; B 33 -3 443 635 ;
+C -1 ; WX 389 ; N Ibreve ; B 38 -3 513 876 ;
+C -1 ; WX 333 ; N ibreve ; B 33 -3 437 681 ;
+C -1 ; WX 389 ; N Iogonek ; B 38 -250 470 681 ;
+C -1 ; WX 333 ; N iogonek ; B 33 -250 348 706 ;
+C -1 ; WX 389 ; N Idotaccent ; B 38 -3 470 876 ;
+C -1 ; WX 333 ; N dotlessi ; B 33 -3 309 471 ;
+C -1 ; WX 799 ; N IJ ; B 45 -213 873 681 ;
+C -1 ; WX 618 ; N ij ; B 33 -266 634 706 ;
+C -1 ; WX 389 ; N Jcircumflex ; B -48 -213 507 881 ;
+C -1 ; WX 333 ; N jcircumflex ; B -37 -266 424 687 ;
+C -1 ; WX 778 ; N Kcommaaccent ; B 38 -258 858 681 ;
+C -1 ; WX 611 ; N kcommaaccent ; B 28 -258 646 720 ;
+C -1 ; WX 611 ; N Lacute ; B 71 -3 608 884 ;
+C -1 ; WX 333 ; N lacute ; B 31 -3 460 923 ;
+C -1 ; WX 611 ; N Lcommaaccent ; B 71 -258 608 681 ;
+C -1 ; WX 333 ; N lcommaaccent ; B 18 -258 351 720 ;
+C -1 ; WX 611 ; N Lcaron ; B 71 -3 672 681 ;
+C -1 ; WX 333 ; N lcaron ; B 31 -3 554 720 ;
+C -1 ; WX 611 ; N Ldot ; B 71 -3 634 681 ;
+C -1 ; WX 351 ; N ldot ; B 31 -3 474 720 ;
+C -1 ; WX 611 ; N Lslash ; B 71 -3 608 681 ;
+C -1 ; WX 333 ; N lslash ; B 31 -3 418 720 ;
+C -1 ; WX 833 ; N Nacute ; B 34 -16 918 884 ;
+C -1 ; WX 611 ; N nacute ; B 23 -3 593 691 ;
+C -1 ; WX 833 ; N Ncommaaccent ; B 34 -258 918 681 ;
+C -1 ; WX 611 ; N ncommaaccent ; B 23 -258 593 471 ;
+C -1 ; WX 833 ; N Ncaron ; B 34 -16 918 881 ;
+C -1 ; WX 611 ; N ncaron ; B 23 -3 596 687 ;
+C -1 ; WX 833 ; N Eng ; B 34 -187 918 681 ;
+C -1 ; WX 611 ; N eng ; B 23 -167 577 471 ;
+C -1 ; WX 833 ; N Omacron ; B 98 -17 856 845 ;
+C -1 ; WX 556 ; N omacron ; B 73 -17 565 635 ;
+C -1 ; WX 833 ; N Obreve ; B 98 -17 856 876 ;
+C -1 ; WX 556 ; N obreve ; B 73 -17 565 681 ;
+C -1 ; WX 833 ; N Ohungarumlaut ; B 98 -17 881 884 ;
+C -1 ; WX 556 ; N ohungarumlaut ; B 73 -17 685 692 ;
+C -1 ; WX 1000 ; N OE ; B 95 -17 1092 695 ;
+C -1 ; WX 833 ; N oe ; B 82 -17 855 471 ;
+C -1 ; WX 722 ; N Racute ; B 38 -3 715 884 ;
+C -1 ; WX 389 ; N racute ; B 29 -3 487 691 ;
+C -1 ; WX 722 ; N Rcommaaccent ; B 38 -258 715 681 ;
+C -1 ; WX 389 ; N rcommaaccent ; B 24 -258 471 471 ;
+C -1 ; WX 722 ; N Rcaron ; B 38 -3 715 881 ;
+C -1 ; WX 389 ; N rcaron ; B 29 -3 512 687 ;
+C -1 ; WX 611 ; N Sacute ; B 62 -17 633 884 ;
+C -1 ; WX 444 ; N sacute ; B 41 -17 485 691 ;
+C -1 ; WX 611 ; N Scircumflex ; B 62 -17 633 881 ;
+C -1 ; WX 444 ; N scircumflex ; B 41 -17 479 687 ;
+C -1 ; WX 611 ; N Scedilla ; B 62 -225 633 695 ;
+C -1 ; WX 444 ; N scedilla ; B 41 -225 449 471 ;
+C -1 ; WX 611 ; N Scaron ; B 62 -17 634 881 ;
+C -1 ; WX 444 ; N scaron ; B 41 -17 510 687 ;
+C -1 ; WX 667 ; N Tcedilla ; B 121 -225 769 681 ;
+C -1 ; WX 333 ; N tcedilla ; B 56 -225 399 632 ;
+C -1 ; WX 667 ; N Tcaron ; B 121 -3 769 881 ;
+C -1 ; WX 333 ; N tcaron ; B 86 -17 517 669 ;
+C -1 ; WX 778 ; N Utilde ; B 139 -17 880 872 ;
+C -1 ; WX 611 ; N utilde ; B 94 -17 604 662 ;
+C -1 ; WX 778 ; N Umacron ; B 139 -17 880 845 ;
+C -1 ; WX 611 ; N umacron ; B 94 -17 596 635 ;
+C -1 ; WX 778 ; N Ubreve ; B 139 -17 880 876 ;
+C -1 ; WX 611 ; N ubreve ; B 94 -17 596 681 ;
+C -1 ; WX 778 ; N Uring ; B 139 -17 880 926 ;
+C -1 ; WX 611 ; N uring ; B 94 -17 596 699 ;
+C -1 ; WX 778 ; N Uhungarumlaut ; B 139 -17 896 884 ;
+C -1 ; WX 611 ; N uhungarumlaut ; B 94 -17 713 692 ;
+C -1 ; WX 778 ; N Uogonek ; B 139 -250 880 681 ;
+C -1 ; WX 611 ; N uogonek ; B 94 -250 596 471 ;
+C -1 ; WX 1000 ; N Wcircumflex ; B 131 -3 1108 881 ;
+C -1 ; WX 833 ; N wcircumflex ; B 87 -3 901 687 ;
+C -1 ; WX 667 ; N Ycircumflex ; B 125 -3 780 881 ;
+C -1 ; WX 556 ; N ycircumflex ; B -13 -266 627 687 ;
+C -1 ; WX 667 ; N Ydieresis ; B 125 -3 780 876 ;
+C -1 ; WX 667 ; N Zacute ; B 23 -3 743 884 ;
+C -1 ; WX 500 ; N zacute ; B 15 -3 535 691 ;
+C -1 ; WX 667 ; N Zdotaccent ; B 23 -3 743 876 ;
+C -1 ; WX 500 ; N zdotaccent ; B 15 -3 535 666 ;
+C -1 ; WX 667 ; N Zcaron ; B 23 -3 743 881 ;
+C -1 ; WX 500 ; N zcaron ; B 15 -3 535 687 ;
+C -1 ; WX 389 ; N longs ; B 33 -3 507 720 ;
+C -1 ; WX 611 ; N Ereversed ; B 51 -3 697 681 ;
+C -1 ; WX 500 ; N florin ; B -32 -242 614 703 ;
+C -1 ; WX 833 ; N Ohorn ; B 98 -17 977 751 ;
+C -1 ; WX 598 ; N ohorn ; B 73 -17 717 541 ;
+C -1 ; WX 819 ; N Uhorn ; B 139 -17 975 751 ;
+C -1 ; WX 649 ; N uhorn ; B 94 -17 772 541 ;
+C -1 ; WX 778 ; N Acaron ; B 23 -3 763 881 ;
+C -1 ; WX 500 ; N acaron ; B 55 -17 549 687 ;
+C -1 ; WX 389 ; N Icaron ; B 38 -3 532 881 ;
+C -1 ; WX 333 ; N icaron ; B 33 -3 455 687 ;
+C -1 ; WX 833 ; N Ocaron ; B 98 -17 856 881 ;
+C -1 ; WX 556 ; N ocaron ; B 73 -17 566 687 ;
+C -1 ; WX 778 ; N Ucaron ; B 139 -17 880 881 ;
+C -1 ; WX 611 ; N ucaron ; B 94 -17 596 687 ;
+C -1 ; WX 778 ; N Udieresisacute ; B 139 -17 880 1079 ;
+C -1 ; WX 611 ; N udieresisacute ; B 94 -17 599 874 ;
+C -1 ; WX 778 ; N Udieresiscaron ; B 139 -17 880 1076 ;
+C -1 ; WX 611 ; N udieresiscaron ; B 94 -17 641 871 ;
+C -1 ; WX 778 ; N Udieresisgrave ; B 139 -17 880 1079 ;
+C -1 ; WX 611 ; N udieresisgrave ; B 94 -17 596 874 ;
+C -1 ; WX 500 ; N eturned ; B 66 -17 508 471 ;
+C -1 ; WX 833 ; N Gcaron ; B 101 -17 840 881 ;
+C -1 ; WX 556 ; N gcaron ; B 2 -266 610 687 ;
+C -1 ; WX 833 ; N Oogonek ; B 98 -250 856 695 ;
+C -1 ; WX 556 ; N oogonek ; B 72 -250 565 471 ;
+C -1 ; WX 333 ; N jcaron ; B -37 -266 455 687 ;
+C -1 ; WX 833 ; N Gacute ; B 101 -17 840 884 ;
+C -1 ; WX 556 ; N gacute ; B 2 -266 610 691 ;
+C -1 ; WX 778 ; N Aringacute ; B 23 -3 763 1097 ;
+C -1 ; WX 500 ; N aringacute ; B 55 -17 553 870 ;
+C -1 ; WX 1000 ; N AEacute ; B 11 -4 1061 884 ;
+C -1 ; WX 778 ; N aeacute ; B 62 -17 787 691 ;
+C -1 ; WX 833 ; N Oslashacute ; B 36 -20 924 884 ;
+C -1 ; WX 556 ; N oslashacute ; B 24 -18 613 691 ;
+C -1 ; WX 778 ; N Adblgrave ; B 23 -3 763 884 ;
+C -1 ; WX 500 ; N adblgrave ; B 55 -17 484 692 ;
+C -1 ; WX 611 ; N Edblgrave ; B 71 -3 684 884 ;
+C -1 ; WX 500 ; N edblgrave ; B 75 -17 517 692 ;
+C -1 ; WX 389 ; N Idblgrave ; B 34 -3 470 884 ;
+C -1 ; WX 333 ; N idblgrave ; B -15 -3 388 692 ;
+C -1 ; WX 833 ; N Odblgrave ; B 98 -17 856 884 ;
+C -1 ; WX 556 ; N odblgrave ; B 73 -17 565 692 ;
+C -1 ; WX 722 ; N Rdblgrave ; B 38 -3 715 884 ;
+C -1 ; WX 389 ; N rdblgrave ; B 29 -3 471 692 ;
+C -1 ; WX 778 ; N Udblgrave ; B 139 -17 880 884 ;
+C -1 ; WX 611 ; N udblgrave ; B 94 -17 596 692 ;
+C -1 ; WX 611 ; N uni0218 ; B 62 -258 633 695 ;
+C -1 ; WX 444 ; N uni0219 ; B 41 -258 449 471 ;
+C -1 ; WX 667 ; N uni021A ; B 121 -258 769 681 ;
+C -1 ; WX 333 ; N uni021B ; B 20 -258 399 632 ;
+C -1 ; WX 333 ; N uni0237 ; B -37 -266 309 471 ;
+C -1 ; WX 500 ; N ereversed ; B 65 -17 507 471 ;
+C -1 ; WX 500 ; N schwa ; B 66 -17 508 471 ;
+C -1 ; WX 359 ; N ringhalfright ; B 111 325 405 666 ;
+C -1 ; WX 359 ; N ringhalfleft ; B 129 325 423 666 ;
+C -1 ; WX 333 ; N circumflex ; B 88 512 425 687 ;
+C -1 ; WX 333 ; N caron ; B 119 512 456 687 ;
+C -1 ; WX 333 ; N breve ; B 131 518 438 681 ;
+C -1 ; WX 333 ; N dotaccent ; B 204 532 341 666 ;
+C -1 ; WX 333 ; N ring ; B 171 499 375 699 ;
+C -1 ; WX 333 ; N ogonek ; B 26 -250 254 14 ;
+C -1 ; WX 333 ; N tilde ; B 79 536 466 662 ;
+C -1 ; WX 333 ; N hungarumlaut ; B 123 507 575 692 ;
+C -1 ; WX 0 ; N uni0300 ; B -286 506 -72 691 ;
+C -1 ; WX 0 ; N uni0301 ; B -249 506 15 691 ;
+C -1 ; WX 0 ; N uni0302 ; B -328 512 9 687 ;
+C -1 ; WX 0 ; N uni0303 ; B -337 536 50 662 ;
+C -1 ; WX 0 ; N uni0304 ; B -316 564 28 635 ;
+C -1 ; WX 0 ; N uni0306 ; B -285 518 22 681 ;
+C -1 ; WX 0 ; N uni0307 ; B -212 532 -75 666 ;
+C -1 ; WX 0 ; N uni0308 ; B -320 532 32 666 ;
+C -1 ; WX 0 ; N uni0309 ; B -224 525 -45 714 ;
+C -1 ; WX 0 ; N uni030A ; B -245 499 -41 699 ;
+C -1 ; WX 0 ; N uni030B ; B -293 507 159 692 ;
+C -1 ; WX 0 ; N uni030C ; B -297 512 40 687 ;
+C -1 ; WX 0 ; N uni030F ; B -431 507 -28 692 ;
+C -1 ; WX 0 ; N uni0311 ; B -310 518 -3 681 ;
+C -1 ; WX 0 ; N uni0323 ; B -227 -212 -91 -78 ;
+C -1 ; WX 0 ; N uni0326 ; B -396 -258 -209 -66 ;
+C -1 ; WX 0 ; N uni032E ; B -429 -211 -99 -78 ;
+C -1 ; WX 0 ; N uni032F ; B -450 -211 -120 -78 ;
+C -1 ; WX 0 ; N uni0330 ; B -468 -208 -81 -82 ;
+C -1 ; WX 0 ; N uni0331 ; B -447 -180 -103 -109 ;
+C -1 ; WX 0 ; N uni0332 ; B -447 -180 -103 -109 ;
+C -1 ; WX 778 ; N Alpha ; B 23 -3 763 686 ;
+C -1 ; WX 667 ; N Beta ; B 71 -3 687 681 ;
+C -1 ; WX 556 ; N Gamma ; B 27 -3 657 681 ;
+C -1 ; WX 659 ; N Delta ; B 3 0 657 731 ;
+C -1 ; WX 611 ; N Epsilon ; B 71 -3 684 681 ;
+C -1 ; WX 667 ; N Zeta ; B 23 -3 743 681 ;
+C -1 ; WX 833 ; N Eta ; B 35 -3 916 681 ;
+C -1 ; WX 833 ; N Theta ; B 98 -17 856 695 ;
+C -1 ; WX 389 ; N Iota ; B 38 -3 470 681 ;
+C -1 ; WX 778 ; N Kappa ; B 38 -3 858 681 ;
+C -1 ; WX 778 ; N Lambda ; B 23 -3 763 686 ;
+C -1 ; WX 1000 ; N Mu ; B 31 -10 1088 681 ;
+C -1 ; WX 833 ; N Nu ; B 34 -16 918 681 ;
+C -1 ; WX 690 ; N Xi ; B 52 -3 726 689 ;
+C -1 ; WX 833 ; N Omicron ; B 98 -17 856 695 ;
+C -1 ; WX 733 ; N Pi ; B 35 -3 856 681 ;
+C -1 ; WX 611 ; N Rho ; B 38 -3 691 681 ;
+C -1 ; WX 660 ; N Sigma ; B 7 -69 689 781 ;
+C -1 ; WX 667 ; N Tau ; B 121 -3 769 681 ;
+C -1 ; WX 782 ; N Upsilon ; B 106 -3 865 696 ;
+C -1 ; WX 716 ; N Phi ; B 103 -3 732 681 ;
+C -1 ; WX 667 ; N Chi ; B 17 -3 769 695 ;
+C -1 ; WX 880 ; N Psi ; B 139 -3 935 681 ;
+C -1 ; WX 766 ; N Omega ; B 47 0 788 731 ;
+C -1 ; WX 723 ; N alpha ; B 81 -17 704 473 ;
+C -1 ; WX 642 ; N beta ; B -31 -241 639 698 ;
+C -1 ; WX 650 ; N gamma ; B 90 -250 684 471 ;
+C -1 ; WX 579 ; N delta ; B 78 -17 610 698 ;
+C -1 ; WX 549 ; N epsilon ; B 69 -10 529 465 ;
+C -1 ; WX 528 ; N zeta ; B 73 -250 570 691 ;
+C -1 ; WX 611 ; N eta ; B 93 -200 577 471 ;
+C -1 ; WX 506 ; N theta ; B 93 -17 532 698 ;
+C -1 ; WX 455 ; N iota ; B 110 -17 429 454 ;
+C -1 ; WX 611 ; N kappa ; B 46 -17 585 471 ;
+C -1 ; WX 599 ; N lambda ; B 50 -11 576 692 ;
+C -1 ; WX 729 ; N mu ; B 48 -267 703 454 ;
+C -1 ; WX 616 ; N nu ; B 101 -21 628 500 ;
+C -1 ; WX 589 ; N xi ; B 64 -250 664 691 ;
+C -1 ; WX 556 ; N omicron ; B 73 -17 565 471 ;
+C -1 ; WX 725 ; N pi ; B 65 -29 750 485 ;
+C -1 ; WX 564 ; N rho ; B 32 -234 562 471 ;
+C -1 ; WX 496 ; N uni03C2 ; B 90 -149 526 471 ;
+C -1 ; WX 604 ; N sigma ; B 79 -17 645 556 ;
+C -1 ; WX 613 ; N tau ; B 106 -17 632 485 ;
+C -1 ; WX 640 ; N upsilon ; B 106 -17 646 502 ;
+C -1 ; WX 662 ; N phi ; B 82 -246 662 471 ;
+C -1 ; WX 546 ; N chi ; B 66 -248 565 469 ;
+C -1 ; WX 724 ; N psi ; B 106 -250 730 696 ;
+C -1 ; WX 675 ; N omega ; B 81 -17 674 474 ;
+C -1 ; WX 703 ; N uni03D1 ; B 106 -17 737 698 ;
+C -1 ; WX 569 ; N uni03D5 ; B 79 -250 571 696 ;
+C -1 ; WX 675 ; N uni03D6 ; B 81 -17 678 592 ;
+C -1 ; WX 569 ; N uni03F1 ; B 63 -250 571 471 ;
+C -1 ; WX 530 ; N uni03F5 ; B 84 -17 536 471 ;
+C -1 ; WX 667 ; N baht ; B 71 -83 687 764 ;
+C -1 ; WX 833 ; N Ddotbelow ; B 67 -212 860 681 ;
+C -1 ; WX 611 ; N ddotbelow ; B 74 -212 634 720 ;
+C -1 ; WX 833 ; N Dlinebelow ; B 67 -180 860 681 ;
+C -1 ; WX 611 ; N dlinebelow ; B 74 -180 634 720 ;
+C -1 ; WX 833 ; N Hdotbelow ; B 35 -212 916 681 ;
+C -1 ; WX 611 ; N hdotbelow ; B 23 -212 593 720 ;
+C -1 ; WX 833 ; N Hdieresis ; B 35 -3 916 876 ;
+C -1 ; WX 611 ; N hdieresis ; B 23 -3 631 915 ;
+C -1 ; WX 833 ; N Hbrevebelow ; B 35 -211 916 681 ;
+C -1 ; WX 611 ; N hbrevebelow ; B 23 -211 593 720 ;
+C -1 ; WX 389 ; N Idieresisacute ; B 38 -3 525 1079 ;
+C -1 ; WX 333 ; N idieresisacute ; B 33 -3 460 874 ;
+C -1 ; WX 611 ; N Ldotbelow ; B 71 -212 608 681 ;
+C -1 ; WX 333 ; N ldotbelow ; B 31 -212 351 720 ;
+C -1 ; WX 611 ; N Ldotbelowmacron ; B 71 -212 608 845 ;
+C -1 ; WX 333 ; N ldotbelowmacron ; B 31 -212 486 884 ;
+C -1 ; WX 1000 ; N Mdotbelow ; B 31 -212 1088 681 ;
+C -1 ; WX 889 ; N mdotbelow ; B 23 -212 870 471 ;
+C -1 ; WX 833 ; N Ndotaccent ; B 34 -16 918 876 ;
+C -1 ; WX 611 ; N ndotaccent ; B 23 -3 593 666 ;
+C -1 ; WX 833 ; N Ndotbelow ; B 34 -212 918 681 ;
+C -1 ; WX 611 ; N ndotbelow ; B 23 -212 593 471 ;
+C -1 ; WX 722 ; N Rdotaccent ; B 38 -3 715 876 ;
+C -1 ; WX 389 ; N rdotaccent ; B 29 -3 471 666 ;
+C -1 ; WX 722 ; N Rdotbelow ; B 38 -212 715 681 ;
+C -1 ; WX 389 ; N rdotbelow ; B 29 -212 471 471 ;
+C -1 ; WX 722 ; N Rdotbelowmacron ; B 38 -212 715 845 ;
+C -1 ; WX 389 ; N rdotbelowmacron ; B 29 -212 503 652 ;
+C -1 ; WX 611 ; N Sdotbelow ; B 62 -212 633 695 ;
+C -1 ; WX 444 ; N sdotbelow ; B 41 -212 449 471 ;
+C -1 ; WX 667 ; N Tdotbelow ; B 121 -212 769 681 ;
+C -1 ; WX 333 ; N tdotbelow ; B 73 -212 399 632 ;
+C -1 ; WX 667 ; N Tlinebelow ; B 121 -180 769 681 ;
+C -1 ; WX 333 ; N tlinebelow ; B -31 -180 399 632 ;
+C -1 ; WX 1000 ; N Wgrave ; B 131 -3 1108 884 ;
+C -1 ; WX 833 ; N wgrave ; B 87 -3 901 691 ;
+C -1 ; WX 1000 ; N Wacute ; B 131 -3 1108 884 ;
+C -1 ; WX 833 ; N wacute ; B 87 -3 901 691 ;
+C -1 ; WX 1000 ; N Wdieresis ; B 131 -3 1108 876 ;
+C -1 ; WX 833 ; N wdieresis ; B 87 -3 901 666 ;
+C -1 ; WX 667 ; N Zdotbelow ; B 23 -212 743 681 ;
+C -1 ; WX 500 ; N zdotbelow ; B 15 -212 535 458 ;
+C -1 ; WX 333 ; N tdieresis ; B 86 -17 462 827 ;
+C -1 ; WX 778 ; N Adotbelow ; B 23 -212 763 686 ;
+C -1 ; WX 500 ; N adotbelow ; B 55 -212 484 471 ;
+C -1 ; WX 778 ; N Ahookabove ; B 23 -3 763 941 ;
+C -1 ; WX 500 ; N ahookabove ; B 55 -17 484 714 ;
+C -1 ; WX 778 ; N Acircumflexacute ; B 23 -3 763 1052 ;
+C -1 ; WX 500 ; N acircumflexacute ; B 55 -17 533 825 ;
+C -1 ; WX 778 ; N Acircumflexgrave ; B 23 -3 763 1052 ;
+C -1 ; WX 500 ; N acircumflexgrave ; B 55 -17 533 825 ;
+C -1 ; WX 778 ; N Acircumflexhookabove ; B 23 -3 763 1093 ;
+C -1 ; WX 500 ; N acircumflexhookabove ; B 55 -17 587 866 ;
+C -1 ; WX 778 ; N Acircumflextilde ; B 23 -3 763 1037 ;
+C -1 ; WX 500 ; N acircumflextilde ; B 55 -17 586 810 ;
+C -1 ; WX 778 ; N Acircumflexdotbelow ; B 23 -212 763 881 ;
+C -1 ; WX 500 ; N acircumflexdotbelow ; B 55 -212 518 687 ;
+C -1 ; WX 778 ; N Abreveacute ; B 23 -3 763 1050 ;
+C -1 ; WX 500 ; N abreveacute ; B 55 -17 565 823 ;
+C -1 ; WX 778 ; N Abrevegrave ; B 23 -3 763 1050 ;
+C -1 ; WX 500 ; N abrevegrave ; B 55 -17 539 823 ;
+C -1 ; WX 778 ; N Abrevehookabove ; B 23 -3 763 1042 ;
+C -1 ; WX 500 ; N abrevehookabove ; B 55 -17 539 815 ;
+C -1 ; WX 778 ; N Abrevetilde ; B 23 -3 763 1032 ;
+C -1 ; WX 500 ; N abrevetilde ; B 55 -17 585 805 ;
+C -1 ; WX 778 ; N Abrevedotbelow ; B 23 -212 763 876 ;
+C -1 ; WX 500 ; N abrevedotbelow ; B 55 -212 531 681 ;
+C -1 ; WX 611 ; N Edotbelow ; B 71 -212 684 681 ;
+C -1 ; WX 500 ; N edotbelow ; B 75 -212 517 471 ;
+C -1 ; WX 611 ; N Ehookabove ; B 71 -3 684 941 ;
+C -1 ; WX 500 ; N ehookabove ; B 75 -17 517 714 ;
+C -1 ; WX 611 ; N Etilde ; B 71 -3 684 872 ;
+C -1 ; WX 500 ; N etilde ; B 75 -17 570 662 ;
+C -1 ; WX 611 ; N Ecircumflexacute ; B 71 -3 684 1052 ;
+C -1 ; WX 500 ; N ecircumflexacute ; B 75 -17 544 825 ;
+C -1 ; WX 611 ; N Ecircumflexgrave ; B 71 -3 684 1052 ;
+C -1 ; WX 500 ; N ecircumflexgrave ; B 75 -17 544 825 ;
+C -1 ; WX 611 ; N Ecircumflexhookabove ; B 71 -3 684 1093 ;
+C -1 ; WX 500 ; N ecircumflexhookabove ; B 75 -17 598 866 ;
+C -1 ; WX 611 ; N Ecircumflextilde ; B 71 -3 684 1037 ;
+C -1 ; WX 500 ; N ecircumflextilde ; B 75 -17 597 810 ;
+C -1 ; WX 611 ; N Ecircumflexdotbelow ; B 71 -212 684 881 ;
+C -1 ; WX 500 ; N ecircumflexdotbelow ; B 75 -212 529 687 ;
+C -1 ; WX 389 ; N Ihookabove ; B 38 -3 470 941 ;
+C -1 ; WX 333 ; N ihookabove ; B 33 -3 370 714 ;
+C -1 ; WX 389 ; N Idotbelow ; B 38 -212 470 681 ;
+C -1 ; WX 333 ; N idotbelow ; B 33 -212 347 706 ;
+C -1 ; WX 833 ; N Odotbelow ; B 98 -212 856 695 ;
+C -1 ; WX 556 ; N odotbelow ; B 73 -212 565 471 ;
+C -1 ; WX 833 ; N Ohookabove ; B 98 -17 856 941 ;
+C -1 ; WX 556 ; N ohookabove ; B 73 -17 565 714 ;
+C -1 ; WX 833 ; N Ocircumflexacute ; B 98 -17 856 1052 ;
+C -1 ; WX 556 ; N ocircumflexacute ; B 73 -17 565 825 ;
+C -1 ; WX 833 ; N Ocircumflexgrave ; B 98 -17 856 1052 ;
+C -1 ; WX 556 ; N ocircumflexgrave ; B 73 -17 565 825 ;
+C -1 ; WX 833 ; N Ocircumflexhookabove ; B 98 -17 856 1093 ;
+C -1 ; WX 556 ; N ocircumflexhookabove ; B 73 -17 604 866 ;
+C -1 ; WX 833 ; N Ocircumflextilde ; B 98 -17 856 1037 ;
+C -1 ; WX 556 ; N ocircumflextilde ; B 73 -17 603 810 ;
+C -1 ; WX 833 ; N Ocircumflexdotbelow ; B 98 -212 856 881 ;
+C -1 ; WX 556 ; N ocircumflexdotbelow ; B 73 -212 565 687 ;
+C -1 ; WX 833 ; N Ohornacute ; B 98 -17 977 884 ;
+C -1 ; WX 598 ; N ohornacute ; B 73 -17 717 691 ;
+C -1 ; WX 833 ; N Ohorngrave ; B 98 -17 977 884 ;
+C -1 ; WX 598 ; N ohorngrave ; B 73 -17 717 691 ;
+C -1 ; WX 833 ; N Ohornhookabove ; B 98 -17 977 941 ;
+C -1 ; WX 598 ; N ohornhookabove ; B 73 -17 717 714 ;
+C -1 ; WX 833 ; N Ohorntilde ; B 98 -17 977 872 ;
+C -1 ; WX 598 ; N ohorntilde ; B 73 -17 717 662 ;
+C -1 ; WX 833 ; N Ohorndotbelow ; B 98 -212 977 751 ;
+C -1 ; WX 598 ; N ohorndotbelow ; B 73 -212 717 541 ;
+C -1 ; WX 778 ; N Udotbelow ; B 139 -212 880 681 ;
+C -1 ; WX 611 ; N udotbelow ; B 94 -212 596 471 ;
+C -1 ; WX 778 ; N Uhookabove ; B 139 -17 880 941 ;
+C -1 ; WX 611 ; N uhookabove ; B 94 -17 596 714 ;
+C -1 ; WX 819 ; N Uhornacute ; B 139 -17 975 884 ;
+C -1 ; WX 649 ; N uhornacute ; B 94 -17 772 691 ;
+C -1 ; WX 819 ; N Uhorngrave ; B 139 -17 975 884 ;
+C -1 ; WX 649 ; N uhorngrave ; B 94 -17 772 691 ;
+C -1 ; WX 819 ; N Uhornhookabove ; B 139 -17 975 941 ;
+C -1 ; WX 649 ; N uhornhookabove ; B 94 -17 772 714 ;
+C -1 ; WX 819 ; N Uhorntilde ; B 139 -17 975 872 ;
+C -1 ; WX 649 ; N uhorntilde ; B 94 -17 772 662 ;
+C -1 ; WX 819 ; N Uhorndotbelow ; B 139 -212 975 751 ;
+C -1 ; WX 649 ; N uhorndotbelow ; B 94 -212 772 541 ;
+C -1 ; WX 667 ; N Ygrave ; B 125 -3 780 884 ;
+C -1 ; WX 556 ; N ygrave ; B -13 -266 627 691 ;
+C -1 ; WX 667 ; N Ydotbelow ; B 125 -212 780 695 ;
+C -1 ; WX 556 ; N ydotbelow ; B -13 -266 627 459 ;
+C -1 ; WX 667 ; N Yhookabove ; B 125 -3 780 941 ;
+C -1 ; WX 556 ; N yhookabove ; B -13 -266 627 714 ;
+C -1 ; WX 667 ; N Ytilde ; B 125 -3 780 872 ;
+C -1 ; WX 556 ; N ytilde ; B -13 -266 627 662 ;
+C -1 ; WX 333 ; N uni2010 ; B 52 195 369 305 ;
+C -1 ; WX 333 ; N uni2011 ; B 52 195 369 305 ;
+C -1 ; WX 500 ; N endash ; B 37 208 551 291 ;
+C -1 ; WX 1000 ; N emdash ; B 37 208 1051 291 ;
+C -1 ; WX 606 ; N dblverticalbar ; B 156 -104 559 720 ;
+C -1 ; WX 278 ; N quoteleft ; B 103 405 369 695 ;
+C -1 ; WX 278 ; N quoteright ; B 103 405 369 695 ;
+C -1 ; WX 333 ; N quotesinglbase ; B 31 -160 297 130 ;
+C -1 ; WX 500 ; N quotedblleft ; B 108 405 586 695 ;
+C -1 ; WX 500 ; N quotedblright ; B 108 405 586 695 ;
+C -1 ; WX 500 ; N quotedblbase ; B 9 -160 487 130 ;
+C -1 ; WX 500 ; N dagger ; B 94 -6 554 682 ;
+C -1 ; WX 500 ; N daggerdbl ; B 22 -245 554 682 ;
+C -1 ; WX 606 ; N bullet ; B 189 172 539 516 ;
+C -1 ; WX 1000 ; N ellipsis ; B 98 -12 924 144 ;
+C -1 ; WX 1000 ; N perthousand ; B 117 -9 1014 724 ;
+C -1 ; WX 1329 ; N permyriad ; B 117 -9 1343 724 ;
+C -1 ; WX 389 ; N guilsinglleft ; B 123 44 380 438 ;
+C -1 ; WX 389 ; N guilsinglright ; B 93 44 352 438 ;
+C -1 ; WX 606 ; N referencemark ; B 42 -53 652 553 ;
+C -1 ; WX 444 ; N interrobang ; B 125 -12 507 738 ;
+C -1 ; WX 504 ; N uni203F ; B 1 -258 461 -114 ;
+C -1 ; WX 504 ; N uni2040 ; B 118 537 578 681 ;
+C -1 ; WX 167 ; N fraction ; B -152 0 436 660 ;
+C -1 ; WX 375 ; N quillbracketleft ; B 48 -113 456 721 ;
+C -1 ; WX 375 ; N quillbracketright ; B 26 -113 434 721 ;
+C -1 ; WX 500 ; N discount ; B 59 0 561 681 ;
+C -1 ; WX 504 ; N uni2054 ; B -22 -258 438 -114 ;
+C -1 ; WX 266 ; N parenleft.superior ; B 124 198 365 692 ;
+C -1 ; WX 266 ; N parenright.superior ; B 59 198 298 692 ;
+C -1 ; WX 722 ; N colonmonetary ; B 98 -83 807 764 ;
+C -1 ; WX 500 ; N lira ; B 5 -19 594 676 ;
+C -1 ; WX 833 ; N naira ; B 34 -16 918 681 ;
+C -1 ; WX 1000 ; N won ; B 58 -3 1108 686 ;
+C -1 ; WX 559 ; N dong ; B 38 -48 611 681 ;
+C -1 ; WX 500 ; N Euro ; B 51 -17 615 660 ;
+C -1 ; WX 611 ; N peso ; B 38 -3 691 681 ;
+C -1 ; WX 1139 ; N centigrade ; B 137 -17 1159 695 ;
+C -1 ; WX 434 ; N l.script ; B 77 -17 468 698 ;
+C -1 ; WX 1095 ; N numero ; B -1 -16 1091 681 ;
+C -1 ; WX 747 ; N published ; B 74 -16 793 691 ;
+C -1 ; WX 717 ; N weierstrass ; B 57 -250 717 492 ;
+C -1 ; WX 722 ; N recipe ; B 38 -3 717 681 ;
+C -1 ; WX 957 ; N servicemark ; B 108 326 1031 687 ;
+C -1 ; WX 998 ; N trademark ; B 158 329 1072 681 ;
+C -1 ; WX 766 ; N ohm ; B 47 0 788 731 ;
+C -1 ; WX 766 ; N uni2127 ; B 99 -49 840 682 ;
+C -1 ; WX 773 ; N estimated ; B 95 0 786 613 ;
+C -1 ; WX 1000 ; N uni2190 ; B 122 -1 960 501 ;
+C -1 ; WX 685 ; N uni2191 ; B 177 -158 679 672 ;
+C -1 ; WX 1000 ; N uni2192 ; B 128 -1 966 501 ;
+C -1 ; WX 685 ; N uni2193 ; B 95 -172 597 658 ;
+C -1 ; WX 494 ; N partialdiff ; B 51 -13 545 750 ;
+C -1 ; WX 713 ; N summation ; B -8 -123 755 752 ;
+C -1 ; WX 606 ; N minus ; B 82 207 612 293 ;
+C -1 ; WX 606 ; N minusplus ; B 67 -93 648 500 ;
+C -1 ; WX 0 ; N fraction.alt ; B -236 0 352 660 ;
+C -1 ; WX 518 ; N asterisk.math ; B 78 32 514 468 ;
+C -1 ; WX 549 ; N radical ; B 66 -96 699 935 ;
+C -1 ; WX 833 ; N infinity ; B 153 103 787 494 ;
+C -1 ; WX 606 ; N anglearc ; B 107 -63 610 563 ;
+C -1 ; WX 606 ; N approxequal ; B 70 64 625 439 ;
+C -1 ; WX 606 ; N notequal ; B 68 20 627 480 ;
+C -1 ; WX 606 ; N lessequal ; B 84 -43 625 631 ;
+C -1 ; WX 606 ; N greaterequal ; B 84 -43 607 631 ;
+C -1 ; WX 500 ; N star ; B 69 34 535 477 ;
+C -1 ; WX 606 ; N diameter ; B 45 -16 649 516 ;
+C -1 ; WX 456 ; N angleleft ; B 100 -104 537 720 ;
+C -1 ; WX 456 ; N angleright ; B 28 -104 464 720 ;
+C -1 ; WX 611 ; N blanksymbol ; B 75 -17 610 720 ;
+C -1 ; WX 500 ; N uni2423 ; B 23 -129 490 203 ;
+C -1 ; WX 494 ; N lozenge ; B 84 0 532 740 ;
+C -1 ; WX 606 ; N openbullet ; B 189 172 539 516 ;
+C -1 ; WX 600 ; N uni266A ; B 101 -17 586 681 ;
+C -1 ; WX 500 ; N married ; B -81 23 669 477 ;
+C -1 ; WX 500 ; N divorced ; B -135 -204 723 704 ;
+C -1 ; WX 436 ; N dblbracketleft ; B 28 -104 517 720 ;
+C -1 ; WX 436 ; N dblbracketright ; B 28 -104 517 720 ;
+C -1 ; WX 606 ; N lessequal.slant ; B 113 -87 625 631 ;
+C -1 ; WX 606 ; N greaterequal.slant ; B 58 -87 588 631 ;
+C -1 ; WX 591 ; N abreveacute.sc ; B 29 -3 597 823 ;
+C -1 ; WX 591 ; N abrevedotbelow.sc ; B 29 -209 569 681 ;
+C -1 ; WX 591 ; N abrevegrave.sc ; B 29 -3 571 823 ;
+C -1 ; WX 591 ; N abrevehookabove.sc ; B 29 -3 571 815 ;
+C -1 ; WX 591 ; N abrevetilde.sc ; B 29 -3 617 805 ;
+C -1 ; WX 591 ; N acaron.sc ; B 29 -3 581 687 ;
+C -1 ; WX 591 ; N acircumflexacute.sc ; B 29 -3 569 825 ;
+C -1 ; WX 591 ; N acircumflexdotbelow.sc ; B 29 -209 569 687 ;
+C -1 ; WX 591 ; N acircumflexgrave.sc ; B 29 -3 569 825 ;
+C -1 ; WX 591 ; N acircumflexhookabove.sc ; B 29 -3 619 866 ;
+C -1 ; WX 591 ; N acircumflextilde.sc ; B 29 -3 618 810 ;
+C -1 ; WX 591 ; N adblgrave.sc ; B 29 -3 569 692 ;
+C -1 ; WX 591 ; N adotbelow.sc ; B 29 -212 569 460 ;
+C -1 ; WX 591 ; N ahookabove.sc ; B 29 -3 569 714 ;
+C -1 ; WX 591 ; N aogonekacute.sc ; B 29 -250 569 691 ;
+C -1 ; WX 591 ; N aringacute.sc ; B 29 -3 585 870 ;
+C -1 ; WX 635 ; N dcroat.sc ; B 59 -2 641 456 ;
+C -1 ; WX 635 ; N ddotbelow.sc ; B 61 -212 641 457 ;
+C -1 ; WX 635 ; N dlinebelow.sc ; B 61 -180 641 457 ;
+C -1 ; WX 310 ; N dotlessi.sc ; B 40 -3 351 457 ;
+C -1 ; WX 310 ; N dotlessj.sc ; B -22 -140 351 457 ;
+C -1 ; WX 460 ; N ecircumflexacute.sc ; B 63 -3 517 825 ;
+C -1 ; WX 460 ; N ecircumflexdotbelow.sc ; B 63 -209 507 687 ;
+C -1 ; WX 460 ; N ecircumflexgrave.sc ; B 63 -3 517 825 ;
+C -1 ; WX 460 ; N ecircumflexhookabove.sc ; B 63 -3 571 866 ;
+C -1 ; WX 460 ; N ecircumflextilde.sc ; B 63 -3 570 810 ;
+C -1 ; WX 460 ; N edblgrave.sc ; B 63 -3 507 692 ;
+C -1 ; WX 460 ; N edotbelow.sc ; B 63 -212 507 457 ;
+C -1 ; WX 460 ; N ehookabove.sc ; B 63 -3 507 714 ;
+C -1 ; WX 460 ; N eogonekacute.sc ; B 63 -250 507 691 ;
+C -1 ; WX 460 ; N ereversed.sc ; B 51 -3 517 457 ;
+C -1 ; WX 460 ; N etilde.sc ; B 63 -3 543 662 ;
+C -1 ; WX 460 ; N eturned.sc ; B 50 -3 494 457 ;
+C -1 ; WX 625 ; N gacute.sc ; B 80 -11 625 691 ;
+C -1 ; WX 625 ; N gcaron.sc ; B 80 -11 625 687 ;
+C -1 ; WX 929 ; N germandbls.sc ; B 50 -11 925 465 ;
+C -1 ; WX 630 ; N h_uni0303.sc ; B 37 -3 672 645 ;
+C -1 ; WX 630 ; N hbrevebelow.sc ; B 37 -211 672 457 ;
+C -1 ; WX 630 ; N hdieresis.sc ; B 37 -3 672 649 ;
+C -1 ; WX 310 ; N icaron.sc ; B 40 -3 445 687 ;
+C -1 ; WX 310 ; N idblgrave.sc ; B -25 -3 378 692 ;
+C -1 ; WX 310 ; N idieresisacute.sc ; B 40 -3 450 874 ;
+C -1 ; WX 310 ; N idotbelow.sc ; B 40 -212 351 457 ;
+C -1 ; WX 310 ; N ihookabove.sc ; B 40 -3 360 714 ;
+C -1 ; WX 310 ; N imacron.alt.sc ; B 40 -3 378 635 ;
+C -1 ; WX 310 ; N iogonekacute.sc ; B 18 -250 419 691 ;
+C -1 ; WX 310 ; N jacute.sc ; B -22 -140 420 691 ;
+C -1 ; WX 460 ; N l_uni0303.sc ; B 63 -3 458 662 ;
+C -1 ; WX 460 ; N lslash.sc ; B 63 -3 458 457 ;
+C -1 ; WX 640 ; N ocaron.sc ; B 78 -11 643 687 ;
+C -1 ; WX 640 ; N ocircumflexacute.sc ; B 78 -11 643 825 ;
+C -1 ; WX 640 ; N ocircumflexdotbelow.sc ; B 78 -201 643 687 ;
+C -1 ; WX 640 ; N ocircumflexgrave.sc ; B 78 -11 643 825 ;
+C -1 ; WX 640 ; N ocircumflexhookabove.sc ; B 78 -11 649 866 ;
+C -1 ; WX 640 ; N ocircumflextilde.sc ; B 78 -11 648 810 ;
+C -1 ; WX 640 ; N odblgrave.sc ; B 78 -11 643 692 ;
+C -1 ; WX 640 ; N odotbelow.sc ; B 78 -212 643 465 ;
+C -1 ; WX 746 ; N oe.sc ; B 77 -11 806 465 ;
+C -1 ; WX 640 ; N ohookabove.sc ; B 78 -11 643 714 ;
+C -1 ; WX 760 ; N ohorn.sc ; B 98 -11 757 541 ;
+C -1 ; WX 760 ; N ohornacute.sc ; B 98 -11 757 691 ;
+C -1 ; WX 760 ; N ohorndotbelow.sc ; B 98 -201 757 541 ;
+C -1 ; WX 760 ; N ohorngrave.sc ; B 98 -11 757 691 ;
+C -1 ; WX 760 ; N ohornhookabove.sc ; B 98 -11 757 714 ;
+C -1 ; WX 760 ; N ohorntilde.sc ; B 98 -11 757 662 ;
+C -1 ; WX 640 ; N oogonek.sc ; B 78 -250 643 465 ;
+C -1 ; WX 640 ; N oogonekacute.sc ; B 78 -250 643 691 ;
+C -1 ; WX 550 ; N rdblgrave.sc ; B 40 -3 534 692 ;
+C -1 ; WX 550 ; N rdotaccent.sc ; B 40 -3 534 666 ;
+C -1 ; WX 480 ; N scaron.sc ; B 59 -11 523 687 ;
+C -1 ; WX 480 ; N sdotbelow.sc ; B 59 -212 476 465 ;
+C -1 ; WX 491 ; N t_uni0303.sc ; B 82 -2 558 662 ;
+C -1 ; WX 491 ; N tcedilla.sc ; B 82 -225 558 457 ;
+C -1 ; WX 491 ; N tdieresis.sc ; B 82 -2 558 666 ;
+C -1 ; WX 491 ; N tdotbelow.sc ; B 82 -212 558 457 ;
+C -1 ; WX 491 ; N tlinebelow.sc ; B 49 -180 558 457 ;
+C -1 ; WX 591 ; N ubrevebelowinverted.sc ; B 104 -211 646 457 ;
+C -1 ; WX 591 ; N ucaron.sc ; B 104 -11 646 687 ;
+C -1 ; WX 591 ; N udblgrave.sc ; B 104 -11 646 692 ;
+C -1 ; WX 591 ; N udieresisacute.sc ; B 104 -11 646 874 ;
+C -1 ; WX 591 ; N udieresiscaron.sc ; B 104 -11 664 871 ;
+C -1 ; WX 591 ; N udieresisgrave.sc ; B 104 -11 646 874 ;
+C -1 ; WX 591 ; N udotbelow.sc ; B 104 -212 646 457 ;
+C -1 ; WX 591 ; N uhookabove.sc ; B 104 -11 646 714 ;
+C -1 ; WX 686 ; N uhorn.sc ; B 119 -11 780 541 ;
+C -1 ; WX 686 ; N uhornacute.sc ; B 119 -11 780 691 ;
+C -1 ; WX 686 ; N uhorndotbelow.sc ; B 119 -201 780 541 ;
+C -1 ; WX 686 ; N uhorngrave.sc ; B 119 -11 780 691 ;
+C -1 ; WX 686 ; N uhornhookabove.sc ; B 119 -11 780 714 ;
+C -1 ; WX 686 ; N uhorntilde.sc ; B 119 -11 780 662 ;
+C -1 ; WX 511 ; N ydotbelow.sc ; B 95 -212 573 466 ;
+C -1 ; WX 511 ; N yhookabove.sc ; B 95 -3 573 714 ;
+C -1 ; WX 511 ; N ytilde.sc ; B 95 -3 574 662 ;
+C -1 ; WX 491 ; N zcaron.sc ; B 11 -3 545 687 ;
+C -1 ; WX 491 ; N zdotbelow.sc ; B 11 -212 545 457 ;
+C -1 ; WX 911 ; N f_k ; B 13 -3 946 720 ;
+C -1 ; WX 333 ; N acute.cap ; B 144 506 422 657 ;
+C -1 ; WX 0 ; N uni0301.cap ; B -232 733 47 884 ;
+C -1 ; WX 333 ; N breve.cap ; B 115 516 445 649 ;
+C -1 ; WX 333 ; N space_uni0306_uni0301.cap ; B 115 516 471 823 ;
+C -1 ; WX 333 ; N space_uni0306_uni0301 ; B 115 516 471 823 ;
+C -1 ; WX 333 ; N space_uni032E ; B -13 -211 317 -78 ;
+C -1 ; WX 333 ; N space_uni032F ; B -34 -211 296 -78 ;
+C -1 ; WX 0 ; N uni0306.cap ; B -261 743 69 876 ;
+C -1 ; WX 333 ; N space_uni0306_uni0300.cap ; B 115 516 445 823 ;
+C -1 ; WX 333 ; N space_uni0306_uni0300 ; B 115 516 445 823 ;
+C -1 ; WX 333 ; N space_uni0306_uni0309.cap ; B 115 516 445 815 ;
+C -1 ; WX 333 ; N space_uni0306_uni0309 ; B 115 516 445 815 ;
+C -1 ; WX 333 ; N space_uni0311.cap ; B 94 516 424 649 ;
+C -1 ; WX 333 ; N space_uni0311 ; B 106 518 413 681 ;
+C -1 ; WX 0 ; N uni0311.cap ; B -282 743 48 876 ;
+C -1 ; WX 333 ; N space_uni0306_uni0303.cap ; B 104 516 491 805 ;
+C -1 ; WX 333 ; N space_uni0306_uni0303 ; B 104 516 491 805 ;
+C -1 ; WX 333 ; N caron.cap ; B 99 511 463 654 ;
+C -1 ; WX 0 ; N uni030C.cap ; B -277 738 87 881 ;
+C -1 ; WX 333 ; N circumflex.cap ; B 75 511 439 654 ;
+C -1 ; WX 333 ; N space_uni0302_uni0301.cap ; B 75 511 439 825 ;
+C -1 ; WX 333 ; N space_uni0302_uni0301 ; B 75 511 439 825 ;
+C -1 ; WX 0 ; N uni0302.cap ; B -301 738 63 881 ;
+C -1 ; WX 333 ; N space_uni0302_uni0300.cap ; B 75 511 439 825 ;
+C -1 ; WX 333 ; N space_uni0302_uni0300 ; B 75 511 439 825 ;
+C -1 ; WX 333 ; N space_uni0302_uni0309.cap ; B 75 511 493 866 ;
+C -1 ; WX 333 ; N space_uni0302_uni0309 ; B 75 511 493 866 ;
+C -1 ; WX 333 ; N space_uni0302_uni0303.cap ; B 75 511 492 810 ;
+C -1 ; WX 333 ; N space_uni0302_uni0303 ; B 75 511 492 810 ;
+C -1 ; WX 333 ; N space_uni0326 ; B 20 -258 207 -66 ;
+C -1 ; WX 333 ; N breve.cyrcap ; B 115 516 445 649 ;
+C -1 ; WX 333 ; N breve.cyr ; B 131 518 438 681 ;
+C -1 ; WX 333 ; N circumflex.cyrcap ; B 94 516 424 649 ;
+C -1 ; WX 333 ; N circumflex.cyr ; B 106 518 413 681 ;
+C -1 ; WX 333 ; N space_uni030F.cap ; B -36 506 386 657 ;
+C -1 ; WX 333 ; N space_uni030F ; B -15 507 388 692 ;
+C -1 ; WX 0 ; N uni030F.cap ; B -411 733 10 884 ;
+C -1 ; WX 333 ; N dieresis.cap ; B 93 515 445 649 ;
+C -1 ; WX 333 ; N space_uni0308_uni0301.cap ; B 93 515 457 852 ;
+C -1 ; WX 333 ; N space_uni0308_uni0301 ; B 96 532 461 874 ;
+C -1 ; WX 333 ; N space_uni0308_uni030C.cap ; B 93 515 498 849 ;
+C -1 ; WX 333 ; N space_uni0308_uni030C ; B 96 532 503 871 ;
+C -1 ; WX 0 ; N uni0308.cap ; B -283 742 69 876 ;
+C -1 ; WX 333 ; N space_uni0308_uni0300.cap ; B 93 515 445 852 ;
+C -1 ; WX 333 ; N space_uni0308_uni0300 ; B 96 532 448 874 ;
+C -1 ; WX 333 ; N dotaccent.cap ; B 201 515 338 649 ;
+C -1 ; WX 0 ; N uni0307.cap ; B -175 742 -38 876 ;
+C -1 ; WX 333 ; N grave.cap ; B 129 506 367 657 ;
+C -1 ; WX 0 ; N uni0300.cap ; B -246 733 -9 884 ;
+C -1 ; WX 333 ; N space_uni0309.cap ; B 189 508 368 697 ;
+C -1 ; WX 333 ; N space_uni0309 ; B 192 525 371 714 ;
+C -1 ; WX 0 ; N uni0309.cap ; B -187 735 -8 924 ;
+C -1 ; WX 333 ; N space_uni031B ; B 219 347 422 541 ;
+C -1 ; WX 333 ; N hungarumlaut.cap ; B 125 506 587 657 ;
+C -1 ; WX 0 ; N uni030B.cap ; B -251 733 212 884 ;
+C -1 ; WX 333 ; N space_uni0332 ; B -31 -180 313 -109 ;
+C -1 ; WX 333 ; N macron.cap ; B 97 547 441 618 ;
+C -1 ; WX 333 ; N macron.cap.alt ; B 153 547 385 618 ;
+C -1 ; WX 333 ; N macron.alt ; B 156 564 388 635 ;
+C -1 ; WX 333 ; N space_uni0331 ; B -31 -180 313 -109 ;
+C -1 ; WX 0 ; N uni0304.cap ; B -279 774 65 845 ;
+C -1 ; WX 333 ; N ring.cap ; B 171 499 375 699 ;
+C -1 ; WX 333 ; N space_uni030A_uni0301.cap ; B 171 499 459 870 ;
+C -1 ; WX 333 ; N space_uni030A_uni0301 ; B 171 499 459 870 ;
+C -1 ; WX 0 ; N uni030A.cap ; B -205 726 -1 926 ;
+C -1 ; WX 333 ; N tilde.cap ; B 76 519 463 645 ;
+C -1 ; WX 333 ; N space_uni0330 ; B -52 -208 335 -82 ;
+C -1 ; WX 0 ; N uni0303.cap ; B -300 746 87 872 ;
+C -1 ; WX 333 ; N acute.ts1 ; B 167 506 431 691 ;
+C -1 ; WX 778 ; N Aogonekacute ; B 23 -250 763 884 ;
+C -1 ; WX 500 ; N aogonekacute ; B 55 -250 514 691 ;
+C -1 ; WX 747 ; N at.alt ; B 69 -155 754 538 ;
+C -1 ; WX 747 ; N bigcircle ; B 74 -16 793 691 ;
+C -1 ; WX 500 ; N star.alt ; B 69 34 535 477 ;
+C -1 ; WX 333 ; N breve.ts1 ; B 131 518 438 681 ;
+C -1 ; WX 333 ; N caron.ts1 ; B 119 512 456 687 ;
+C -1 ; WX 747 ; N copyleft ; B 74 -16 793 691 ;
+C -1 ; WX 0 ; N cwm ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N cwmascender ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N cwmcapital ; B 0 0 0 0 ;
+C -1 ; WX 333 ; N dblgrave.ts1 ; B -15 507 388 692 ;
+C -1 ; WX 592 ; N died ; B 114 0 639 681 ;
+C -1 ; WX 333 ; N dieresis.ts1 ; B 96 532 448 666 ;
+C -1 ; WX 333 ; N space_uni0323 ; B 73 -212 209 -78 ;
+C -1 ; WX 611 ; N Eogonekacute ; B 71 -250 684 884 ;
+C -1 ; WX 500 ; N eogonekacute ; B 75 -250 517 691 ;
+C -1 ; WX 1199 ; N Germandbls ; B 51 -17 1227 695 ;
+C -1 ; WX 444 ; N gnaborretni ; B 25 -239 407 511 ;
+C -1 ; WX 333 ; N grave.ts1 ; B 130 506 344 691 ;
+C -1 ; WX 833 ; N guarani ; B 101 -83 840 764 ;
+C -1 ; WX 333 ; N hungarumlaut.ts1 ; B 123 507 575 692 ;
+C -1 ; WX 167 ; N hyphen.alt ; B 52 195 369 305 ;
+C -1 ; WX 333 ; N hyphen.prop ; B 72 309 389 419 ;
+C -1 ; WX 333 ; N hyphendbl ; B 29 66 392 434 ;
+C -1 ; WX 167 ; N hyphendbl.alt ; B 29 66 392 434 ;
+C -1 ; WX 389 ; N Iogonekacute ; B 38 -250 491 884 ;
+C -1 ; WX 333 ; N iogonekacute ; B 33 -250 431 691 ;
+C -1 ; WX 389 ; N Jacute ; B -48 -213 491 884 ;
+C -1 ; WX 333 ; N jacute ; B -37 -266 430 691 ;
+C -1 ; WX 1000 ; N leaf ; B 30 -68 1090 749 ;
+C -1 ; WX 333 ; N macron.ts1 ; B 100 564 444 635 ;
+C -1 ; WX 833 ; N Oogonekacute ; B 98 -250 856 884 ;
+C -1 ; WX 556 ; N oogonekacute ; B 72 -250 565 691 ;
+C -1 ; WX 514 ; N paragraph.alt ; B 109 -161 573 683 ;
+C -1 ; WX 385 ; N perthousandzero ; B 24 0 356 328 ;
+C -1 ; WX 402 ; N quotedblbase.ts1 ; B 36 -163 396 156 ;
+C -1 ; WX 227 ; N quotesinglbase.ts1 ; B 59 -163 197 156 ;
+C -1 ; WX 227 ; N quotesingle.ts1 ; B 154 376 292 695 ;
+C -1 ; WX 446 ; N registered.alt ; B 147 412 507 766 ;
+C -1 ; WX 333 ; N suppress ; B 70 278 418 552 ;
+C -1 ; WX 333 ; N tieaccentcapital ; B 238 537 698 681 ;
+C -1 ; WX 504 ; N tieaccentcapital.new ; B 118 537 578 681 ;
+C -1 ; WX 277 ; N tieaccentlowercase ; B 213 557 582 701 ;
+C -1 ; WX 500 ; N tieaccentlowercase.new ; B 165 557 534 701 ;
+C -1 ; WX 606 ; N asciitilde.low ; B 45 -77 561 78 ;
+C -1 ; WX 667 ; N emdash.alt ; B 37 208 718 291 ;
+C -1 ; WX 778 ; N U_uni032F ; B 139 -211 880 681 ;
+C -1 ; WX 611 ; N u_uni032F ; B 94 -211 596 471 ;
+C -1 ; WX 389 ; N J_uni030C.cap ; B -48 -213 657 681 ;
+C -1 ; WX 446 ; N copyright.alt ; B 146 409 506 763 ;
+C -1 ; WX 333 ; N imacron.alt ; B 33 -3 388 635 ;
+C -1 ; WX 389 ; N Imacron.alt ; B 38 -3 470 845 ;
+C -1 ; WX 833 ; N H_uni0303 ; B 35 -3 916 872 ;
+C -1 ; WX 611 ; N h_uni0303 ; B 23 -3 649 911 ;
+C -1 ; WX 611 ; N L_uni0303 ; B 71 -3 608 872 ;
+C -1 ; WX 333 ; N l_uni0303 ; B 31 -3 508 911 ;
+C -1 ; WX 667 ; N T_uni0303 ; B 121 -3 769 872 ;
+C -1 ; WX 333 ; N t_uni0303 ; B 86 -17 480 823 ;
+C -1 ; WX 667 ; N T_uni0308 ; B 121 -3 769 876 ;
+C -1 ; WX 833 ; N Orogate ; B 98 -189 856 867 ;
+C -1 ; WX 556 ; N orogate ; B 73 -189 565 643 ;
+C -1 ; WX 760 ; N orogate.sc ; B 78 -189 643 637 ;
+C -1 ; WX 500 ; N zero.slash ; B 72 -17 544 660 ;
+C -1 ; WX 527 ; N zero.prop ; B 85 -17 557 660 ;
+C -1 ; WX 539 ; N two.prop ; B 45 -3 551 660 ;
+C -1 ; WX 528 ; N three.prop ; B 72 -17 536 660 ;
+C -1 ; WX 507 ; N four.prop ; B 59 -3 523 672 ;
+C -1 ; WX 522 ; N five.prop ; B 71 -17 566 656 ;
+C -1 ; WX 524 ; N six.prop ; B 84 -17 556 660 ;
+C -1 ; WX 493 ; N seven.prop ; B 66 -3 585 656 ;
+C -1 ; WX 525 ; N eight.prop ; B 70 -17 543 660 ;
+C -1 ; WX 524 ; N nine.prop ; B 84 -17 556 660 ;
+C -1 ; WX 500 ; N zero.taboldstyle ; B 72 -17 518 481 ;
+C -1 ; WX 500 ; N one.taboldstyle ; B 74 -3 461 480 ;
+C -1 ; WX 500 ; N two.taboldstyle ; B 24 -3 492 474 ;
+C -1 ; WX 500 ; N three.taboldstyle ; B 8 -234 480 481 ;
+C -1 ; WX 500 ; N four.taboldstyle ; B 19 -232 483 507 ;
+C -1 ; WX 500 ; N five.taboldstyle ; B -22 -234 520 475 ;
+C -1 ; WX 500 ; N six.taboldstyle ; B 75 -17 547 660 ;
+C -1 ; WX 500 ; N seven.taboldstyle ; B 55 -199 574 460 ;
+C -1 ; WX 500 ; N eight.taboldstyle ; B 58 -17 531 660 ;
+C -1 ; WX 500 ; N nine.taboldstyle ; B 38 -196 509 481 ;
+C -1 ; WX 591 ; N abreve.sc ; B 29 -3 569 681 ;
+C -1 ; WX 591 ; N amacron.sc ; B 29 -3 569 635 ;
+C -1 ; WX 591 ; N aogonek.sc ; B 29 -250 569 460 ;
+C -1 ; WX 741 ; N aeacute.sc ; B 20 -3 779 691 ;
+C -1 ; WX 545 ; N cacute.sc ; B 78 -11 601 691 ;
+C -1 ; WX 545 ; N ccaron.sc ; B 78 -11 610 687 ;
+C -1 ; WX 545 ; N ccircumflex.sc ; B 78 -11 601 687 ;
+C -1 ; WX 545 ; N cdotaccent.sc ; B 78 -11 601 666 ;
+C -1 ; WX 635 ; N dcaron.sc ; B 61 -3 641 687 ;
+C -1 ; WX 460 ; N ebreve.sc ; B 63 -3 515 681 ;
+C -1 ; WX 460 ; N ecaron.sc ; B 63 -3 533 687 ;
+C -1 ; WX 460 ; N edotaccent.sc ; B 63 -3 507 666 ;
+C -1 ; WX 460 ; N emacron.sc ; B 63 -3 521 635 ;
+C -1 ; WX 630 ; N eng.sc ; B 37 -250 674 457 ;
+C -1 ; WX 460 ; N eogonek.sc ; B 63 -250 507 457 ;
+C -1 ; WX 625 ; N gbreve.sc ; B 80 -11 625 681 ;
+C -1 ; WX 625 ; N gcircumflex.sc ; B 80 -11 625 687 ;
+C -1 ; WX 625 ; N gcommaaccent.sc ; B 80 -258 625 465 ;
+C -1 ; WX 625 ; N gdotaccent.sc ; B 80 -11 625 666 ;
+C -1 ; WX 630 ; N hbar.sc ; B 22 -3 657 457 ;
+C -1 ; WX 630 ; N hcircumflex.sc ; B 37 -3 672 654 ;
+C -1 ; WX 310 ; N ibreve.sc ; B 40 -3 427 681 ;
+C -1 ; WX 622 ; N ij.sc ; B 45 -140 657 457 ;
+C -1 ; WX 310 ; N imacron.sc ; B 40 -3 433 635 ;
+C -1 ; WX 310 ; N iogonek.sc ; B 18 -250 351 457 ;
+C -1 ; WX 310 ; N itilde.sc ; B 40 -3 455 662 ;
+C -1 ; WX 310 ; N jcircumflex.sc ; B -22 -140 414 687 ;
+C -1 ; WX 591 ; N kcommaaccent.sc ; B 40 -258 631 457 ;
+C -1 ; WX 460 ; N lacute.sc ; B 63 -3 458 691 ;
+C -1 ; WX 460 ; N lcaron.sc ; B 48 -3 537 457 ;
+C -1 ; WX 460 ; N lcommaaccent.sc ; B 63 -258 458 457 ;
+C -1 ; WX 460 ; N ldot.sc ; B 48 -3 485 457 ;
+C -1 ; WX 630 ; N nacute.sc ; B 37 -11 674 691 ;
+C -1 ; WX 630 ; N ncaron.sc ; B 37 -11 674 687 ;
+C -1 ; WX 630 ; N ncommaaccent.sc ; B 37 -258 674 457 ;
+C -1 ; WX 640 ; N obreve.sc ; B 78 -11 643 681 ;
+C -1 ; WX 640 ; N ohungarumlaut.sc ; B 78 -11 730 692 ;
+C -1 ; WX 640 ; N omacron.sc ; B 78 -11 643 635 ;
+C -1 ; WX 635 ; N oslashacute.sc ; B 34 -15 682 706 ;
+C -1 ; WX 550 ; N racute.sc ; B 40 -3 534 691 ;
+C -1 ; WX 550 ; N rcaron.sc ; B 40 -3 556 687 ;
+C -1 ; WX 550 ; N rcommaaccent.sc ; B 40 -258 534 457 ;
+C -1 ; WX 480 ; N sacute.sc ; B 59 -11 498 691 ;
+C -1 ; WX 480 ; N scedilla.sc ; B 59 -225 476 465 ;
+C -1 ; WX 480 ; N scircumflex.sc ; B 59 -11 492 687 ;
+C -1 ; WX 480 ; N uni0219.sc ; B 59 -258 476 465 ;
+C -1 ; WX 491 ; N tcaron.sc ; B 82 -2 558 687 ;
+C -1 ; WX 491 ; N uni021B.sc ; B 82 -258 558 457 ;
+C -1 ; WX 591 ; N ubreve.sc ; B 104 -11 646 681 ;
+C -1 ; WX 591 ; N uhungarumlaut.sc ; B 104 -11 736 692 ;
+C -1 ; WX 591 ; N umacron.sc ; B 104 -11 646 635 ;
+C -1 ; WX 591 ; N uogonek.sc ; B 104 -250 646 457 ;
+C -1 ; WX 591 ; N uring.sc ; B 104 -11 646 699 ;
+C -1 ; WX 591 ; N utilde.sc ; B 104 -11 646 662 ;
+C -1 ; WX 751 ; N wacute.sc ; B 99 -2 811 691 ;
+C -1 ; WX 751 ; N wcircumflex.sc ; B 99 -2 811 687 ;
+C -1 ; WX 751 ; N wdieresis.sc ; B 99 -2 811 666 ;
+C -1 ; WX 751 ; N wgrave.sc ; B 99 -2 811 691 ;
+C -1 ; WX 511 ; N ycircumflex.sc ; B 95 -3 573 687 ;
+C -1 ; WX 511 ; N ygrave.sc ; B 95 -3 573 691 ;
+C -1 ; WX 491 ; N zacute.sc ; B 11 -3 545 691 ;
+C -1 ; WX 491 ; N zdotaccent.sc ; B 11 -3 545 666 ;
+C -1 ; WX 310 ; N idotaccent.sc ; B 40 -3 351 666 ;
+C -1 ; WX 333 ; N dotlessj ; B -37 -266 309 471 ;
+C -1 ; WX 466 ; N one.prop ; B 62 -3 450 670 ;
+C -1 ; WX 750 ; N threequartersemdash ; B 37 208 801 291 ;
+C -1 ; WX 611 ; N dollar.oldstyle ; B 62 -83 633 764 ;
+C -1 ; WX 523 ; N zero.oldstyle ; B 80 -17 526 481 ;
+C -1 ; WX 512 ; N one.oldstyle ; B 85 -3 472 480 ;
+C -1 ; WX 539 ; N two.oldstyle ; B 45 -3 513 474 ;
+C -1 ; WX 513 ; N three.oldstyle ; B 17 -234 489 481 ;
+C -1 ; WX 549 ; N four.oldstyle ; B 53 -232 517 507 ;
+C -1 ; WX 526 ; N five.oldstyle ; B 17 -234 559 475 ;
+C -1 ; WX 524 ; N six.oldstyle ; B 84 -17 556 660 ;
+C -1 ; WX 539 ; N seven.oldstyle ; B 55 -199 574 460 ;
+C -1 ; WX 525 ; N eight.oldstyle ; B 70 -17 543 660 ;
+C -1 ; WX 524 ; N nine.oldstyle ; B 53 -196 524 481 ;
+C -1 ; WX 591 ; N a.sc ; B 29 -3 569 460 ;
+C -1 ; WX 516 ; N b.sc ; B 63 -3 515 457 ;
+C -1 ; WX 545 ; N c.sc ; B 78 -11 601 465 ;
+C -1 ; WX 635 ; N d.sc ; B 61 -3 641 457 ;
+C -1 ; WX 460 ; N e.sc ; B 63 -3 507 457 ;
+C -1 ; WX 421 ; N f.sc ; B 32 -3 488 457 ;
+C -1 ; WX 625 ; N g.sc ; B 80 -11 625 465 ;
+C -1 ; WX 630 ; N h.sc ; B 37 -3 672 457 ;
+C -1 ; WX 310 ; N i.sc ; B 40 -3 351 457 ;
+C -1 ; WX 310 ; N j.sc ; B -22 -140 351 457 ;
+C -1 ; WX 591 ; N k.sc ; B 40 -3 631 457 ;
+C -1 ; WX 460 ; N l.sc ; B 63 -3 458 457 ;
+C -1 ; WX 751 ; N m.sc ; B 35 -7 796 457 ;
+C -1 ; WX 630 ; N n.sc ; B 37 -11 674 457 ;
+C -1 ; WX 640 ; N o.sc ; B 78 -11 643 465 ;
+C -1 ; WX 475 ; N p.sc ; B 40 -3 517 457 ;
+C -1 ; WX 680 ; N q.sc ; B 78 -121 643 465 ;
+C -1 ; WX 550 ; N r.sc ; B 40 -3 534 457 ;
+C -1 ; WX 480 ; N s.sc ; B 59 -11 476 465 ;
+C -1 ; WX 491 ; N t.sc ; B 82 -2 558 457 ;
+C -1 ; WX 591 ; N u.sc ; B 104 -11 646 457 ;
+C -1 ; WX 591 ; N v.sc ; B 101 -2 649 457 ;
+C -1 ; WX 751 ; N w.sc ; B 99 -2 811 460 ;
+C -1 ; WX 511 ; N x.sc ; B 25 -3 565 465 ;
+C -1 ; WX 511 ; N y.sc ; B 95 -3 573 466 ;
+C -1 ; WX 491 ; N z.sc ; B 11 -3 545 457 ;
+C -1 ; WX 444 ; N cent.oldstyle ; B 70 -83 487 537 ;
+C -1 ; WX 591 ; N agrave.sc ; B 29 -3 569 691 ;
+C -1 ; WX 591 ; N aacute.sc ; B 29 -3 569 691 ;
+C -1 ; WX 591 ; N acircumflex.sc ; B 29 -3 569 687 ;
+C -1 ; WX 591 ; N atilde.sc ; B 29 -3 591 662 ;
+C -1 ; WX 591 ; N adieresis.sc ; B 29 -3 573 666 ;
+C -1 ; WX 591 ; N aring.sc ; B 29 -3 569 699 ;
+C -1 ; WX 741 ; N ae.sc ; B 20 -3 779 457 ;
+C -1 ; WX 545 ; N ccedilla.sc ; B 78 -225 601 465 ;
+C -1 ; WX 460 ; N egrave.sc ; B 63 -3 507 691 ;
+C -1 ; WX 460 ; N eacute.sc ; B 63 -3 508 691 ;
+C -1 ; WX 460 ; N ecircumflex.sc ; B 63 -3 507 687 ;
+C -1 ; WX 460 ; N edieresis.sc ; B 63 -3 525 666 ;
+C -1 ; WX 310 ; N igrave.sc ; B 40 -3 351 691 ;
+C -1 ; WX 310 ; N iacute.sc ; B 40 -3 420 691 ;
+C -1 ; WX 310 ; N icircumflex.sc ; B 40 -3 414 687 ;
+C -1 ; WX 310 ; N idieresis.sc ; B 40 -3 437 666 ;
+C -1 ; WX 635 ; N eth.sc ; B 59 -2 641 456 ;
+C -1 ; WX 630 ; N ntilde.sc ; B 37 -11 674 662 ;
+C -1 ; WX 640 ; N ograve.sc ; B 78 -11 643 691 ;
+C -1 ; WX 640 ; N oacute.sc ; B 78 -11 643 691 ;
+C -1 ; WX 640 ; N ocircumflex.sc ; B 78 -11 643 687 ;
+C -1 ; WX 640 ; N otilde.sc ; B 78 -11 643 662 ;
+C -1 ; WX 640 ; N odieresis.sc ; B 78 -11 643 666 ;
+C -1 ; WX 635 ; N oslash.sc ; B 34 -15 682 469 ;
+C -1 ; WX 591 ; N ugrave.sc ; B 104 -11 646 691 ;
+C -1 ; WX 591 ; N uacute.sc ; B 104 -11 646 691 ;
+C -1 ; WX 591 ; N ucircumflex.sc ; B 104 -11 646 687 ;
+C -1 ; WX 591 ; N udieresis.sc ; B 104 -11 646 666 ;
+C -1 ; WX 511 ; N yacute.sc ; B 95 -3 573 691 ;
+C -1 ; WX 475 ; N thorn.sc ; B 41 -2 488 456 ;
+C -1 ; WX 511 ; N ydieresis.sc ; B 95 -3 573 666 ;
+C -1 ; WX 709 ; N ff ; B 33 -3 827 720 ; L l ffl ; L i ffi ;
+C -1 ; WX 611 ; N fi ; B 9 -3 653 720 ;
+C -1 ; WX 611 ; N fl ; B 16 -3 648 720 ;
+C -1 ; WX 971 ; N ffi ; B 33 -3 996 720 ;
+C -1 ; WX 954 ; N ffl ; B 33 -3 991 720 ;
+C -1 ; WX 280 ; N .notdef ; B 0 0 0 0 ;
+C -1 ; WX 333 ; N acute.dup ; B 167 506 431 691 ;
+C -1 ; WX 1000 ; N AE.dup ; B 11 -4 1061 682 ;
+C -1 ; WX 778 ; N ae.dup ; B 62 -17 787 471 ;
+C -1 ; WX 333 ; N cedilla.dup ; B 36 -225 278 7 ;
+C -1 ; WX 333 ; N circumflex.dup ; B 88 512 425 687 ;
+C -1 ; WX 333 ; N dieresis.dup ; B 96 532 448 666 ;
+C -1 ; WX 434 ; N l.script.dup ; B 77 -17 468 698 ;
+C -1 ; WX 833 ; N Gcedilla ; B 101 -258 840 695 ;
+C -1 ; WX 556 ; N gcedilla ; B 2 -266 610 718 ;
+C -1 ; WX 611 ; N germandbls.dup ; B 29 -17 626 720 ;
+C -1 ; WX 333 ; N hyphen.dup ; B 52 195 369 305 ;
+C -1 ; WX 778 ; N Kcedilla ; B 38 -258 858 681 ;
+C -1 ; WX 611 ; N kcedilla ; B 28 -258 646 720 ;
+C -1 ; WX 611 ; N Lcedilla ; B 71 -258 608 681 ;
+C -1 ; WX 333 ; N lcedilla ; B 18 -258 351 720 ;
+C -1 ; WX 333 ; N macron.dup ; B 100 564 444 635 ;
+C -1 ; WX 833 ; N Ncedilla ; B 34 -258 918 681 ;
+C -1 ; WX 611 ; N ncedilla ; B 23 -258 593 471 ;
+C -1 ; WX 1000 ; N OE.dup ; B 95 -17 1092 695 ;
+C -1 ; WX 833 ; N oe.dup ; B 82 -17 855 471 ;
+C -1 ; WX 833 ; N Oslash.dup ; B 36 -20 924 698 ;
+C -1 ; WX 556 ; N oslash.dup ; B 24 -18 613 471 ;
+C -1 ; WX 278 ; N quoteleft.dup ; B 103 405 369 695 ;
+C -1 ; WX 278 ; N quoteright.dup ; B 103 405 369 695 ;
+C -1 ; WX 722 ; N Rcedilla ; B 38 -258 715 681 ;
+C -1 ; WX 389 ; N rcedilla ; B 24 -258 471 471 ;
+C -1 ; WX 333 ; N tilde.dup ; B 79 536 466 662 ;
+C -1 ; WX 630 ; N hdotbelow.sc ; B 37 -212 672 457 ;
+C -1 ; WX 310 ; N jcaron.sc ; B -22 -140 445 687 ;
+C -1 ; WX 460 ; N ldotbelow.sc ; B 63 -212 458 457 ;
+C -1 ; WX 460 ; N ldotbelowmacron.sc ; B 63 -212 458 638 ;
+C -1 ; WX 751 ; N mdotbelow.sc ; B 35 -212 796 457 ;
+C -1 ; WX 630 ; N ndotaccent.sc ; B 37 -11 674 666 ;
+C -1 ; WX 630 ; N ndotbelow.sc ; B 37 -212 674 457 ;
+C -1 ; WX 550 ; N rdotbelow.sc ; B 40 -212 534 457 ;
+C -1 ; WX 550 ; N rdotbelowmacron.sc ; B 40 -212 544 638 ;
+C -1 ; WX 222 ; N exclam.superior ; B 105 254 301 705 ;
+C -1 ; WX 322 ; N quotedbl.superior ; B 124 450 422 708 ;
+C -1 ; WX 401 ; N numbersign.superior ; B 68 261 495 665 ;
+C -1 ; WX 410 ; N dollar.superior ; B 74 193 474 692 ;
+C -1 ; WX 712 ; N percent.superior ; B 148 256 730 686 ;
+C -1 ; WX 667 ; N ampersand.superior ; B 104 251 723 669 ;
+C -1 ; WX 182 ; N quoteright.superior ; B 142 450 262 708 ;
+C -1 ; WX 355 ; N asterisk.superior ; B 128 457 417 675 ;
+C -1 ; WX 485 ; N plus.superior ; B 101 257 527 567 ;
+C -1 ; WX 199 ; N comma.superior ; B 19 128 246 377 ;
+C -1 ; WX 266 ; N hyphen.superior ; B 77 363 333 454 ;
+C -1 ; WX 200 ; N period.superior ; B 92 254 221 381 ;
+C -1 ; WX 246 ; N slash.superior ; B 36 251 378 699 ;
+C -1 ; WX 200 ; N colon.superior ; B 92 254 248 532 ;
+C -1 ; WX 200 ; N semicolon.superior ; B 21 144 268 548 ;
+C -1 ; WX 484 ; N less.superior ; B 126 259 514 578 ;
+C -1 ; WX 485 ; N equal.superior ; B 93 322 536 496 ;
+C -1 ; WX 484 ; N greater.superior ; B 102 251 491 578 ;
+C -1 ; WX 355 ; N question.superior ; B 130 254 434 670 ;
+C -1 ; WX 599 ; N at.superior ; B 111 254 657 667 ;
+C -1 ; WX 653 ; N A.superior ; B 64 259 690 679 ;
+C -1 ; WX 538 ; N B.superior ; B 103 259 581 667 ;
+C -1 ; WX 558 ; N C.superior ; B 113 251 648 675 ;
+C -1 ; WX 647 ; N D.superior ; B 100 259 698 667 ;
+C -1 ; WX 500 ; N E.superior ; B 103 259 579 667 ;
+C -1 ; WX 451 ; N F.superior ; B 68 259 555 667 ;
+C -1 ; WX 667 ; N G.superior ; B 115 251 700 675 ;
+C -1 ; WX 667 ; N H.superior ; B 74 259 757 667 ;
+C -1 ; WX 311 ; N I.superior ; B 76 259 399 667 ;
+C -1 ; WX 311 ; N J.superior ; B 13 125 400 675 ;
+C -1 ; WX 663 ; N K.superior ; B 76 259 732 667 ;
+C -1 ; WX 496 ; N L.superior ; B 103 259 536 667 ;
+C -1 ; WX 836 ; N M.superior ; B 71 255 930 667 ;
+C -1 ; WX 751 ; N N.superior ; B 73 246 842 667 ;
+C -1 ; WX 666 ; N O.superior ; B 114 251 717 675 ;
+C -1 ; WX 489 ; N P.superior ; B 76 259 579 667 ;
+C -1 ; WX 666 ; N Q.superior ; B 114 150 717 675 ;
+C -1 ; WX 587 ; N R.superior ; B 76 259 630 667 ;
+C -1 ; WX 489 ; N S.superior ; B 96 251 534 675 ;
+C -1 ; WX 548 ; N T.superior ; B 117 259 653 667 ;
+C -1 ; WX 623 ; N U.superior ; B 131 251 728 667 ;
+C -1 ; WX 649 ; N V.superior ; B 126 259 755 667 ;
+C -1 ; WX 824 ; N W.superior ; B 124 259 933 670 ;
+C -1 ; WX 565 ; N X.superior ; B 59 258 669 680 ;
+C -1 ; WX 534 ; N Y.superior ; B 120 259 646 676 ;
+C -1 ; WX 573 ; N Z.superior ; B 64 259 661 667 ;
+C -1 ; WX 267 ; N bracketleft.superior ; B 91 189 358 698 ;
+C -1 ; WX 509 ; N backslash.superior ; B 179 261 500 699 ;
+C -1 ; WX 267 ; N bracketright.superior ; B 66 189 333 698 ;
+C -1 ; WX 533 ; N asciicircum.superior ; B 112 411 565 677 ;
+C -1 ; WX 400 ; N underscore.superior ; B 31 179 440 222 ;
+C -1 ; WX 266 ; N quoteleft.superior ; B 128 541 301 692 ;
+C -1 ; WX 386 ; N a.superior ; B 87 251 421 542 ;
+C -1 ; WX 490 ; N b.superior ; B 109 251 526 695 ;
+C -1 ; WX 355 ; N c.superior ; B 95 251 420 542 ;
+C -1 ; WX 490 ; N d.superior ; B 99 251 531 698 ;
+C -1 ; WX 401 ; N e.superior ; B 99 251 450 542 ;
+C -1 ; WX 312 ; N f.superior ; B 72 259 427 690 ;
+C -1 ; WX 446 ; N g.superior ; B 52 102 519 542 ;
+C -1 ; WX 490 ; N h.superior ; B 64 259 524 695 ;
+C -1 ; WX 267 ; N i.superior ; B 72 259 295 658 ;
+C -1 ; WX 267 ; N j.superior ; B 27 102 295 658 ;
+C -1 ; WX 519 ; N k.superior ; B 67 258 572 695 ;
+C -1 ; WX 267 ; N l.superior ; B 71 259 305 705 ;
+C -1 ; WX 713 ; N m.superior ; B 64 259 746 542 ;
+C -1 ; WX 490 ; N n.superior ; B 64 259 524 542 ;
+C -1 ; WX 445 ; N o.superior ; B 98 251 489 542 ;
+C -1 ; WX 490 ; N p.superior ; B 41 107 535 542 ;
+C -1 ; WX 490 ; N q.superior ; B 106 107 523 542 ;
+C -1 ; WX 312 ; N r.superior ; B 69 259 408 542 ;
+C -1 ; WX 356 ; N s.superior ; B 79 251 396 542 ;
+C -1 ; WX 267 ; N t.superior ; B 100 251 352 644 ;
+C -1 ; WX 490 ; N u.superior ; B 110 251 521 562 ;
+C -1 ; WX 470 ; N v.superior ; B 95 259 556 535 ;
+C -1 ; WX 694 ; N w.superior ; B 97 259 779 542 ;
+C -1 ; WX 443 ; N x.superior ; B 70 258 524 549 ;
+C -1 ; WX 462 ; N y.superior ; B 42 102 548 535 ;
+C -1 ; WX 437 ; N z.superior ; B 58 259 504 535 ;
+C -1 ; WX 249 ; N braceleft.superior ; B 80 188 354 694 ;
+C -1 ; WX 485 ; N bar.superior ; B 242 198 400 690 ;
+C -1 ; WX 248 ; N braceright.superior ; B 50 188 324 694 ;
+C -1 ; WX 484 ; N asciitilde.superior ; B 106 339 521 466 ;
+C -1 ; WX 223 ; N exclamdown.superior ; B 64 103 261 555 ;
+C -1 ; WX 401 ; N eacute.superior ; B 99 251 454 678 ;
+C -1 ; WX 401 ; N egrave.superior ; B 99 251 451 678 ;
+C -1 ; WX 400 ; N zero.superior ; B 97 251 466 654 ;
+C -1 ; WX 400 ; N four.superior ; B 77 259 450 672 ;
+C -1 ; WX 405 ; N five.superior ; B 94 251 479 653 ;
+C -1 ; WX 399 ; N six.superior ; B 99 251 460 654 ;
+C -1 ; WX 430 ; N seven.superior ; B 108 259 541 653 ;
+C -1 ; WX 406 ; N eight.superior ; B 86 251 458 654 ;
+C -1 ; WX 400 ; N nine.superior ; B 101 240 464 660 ;
+C -1 ; WX 1140 ; N T_h ; B 121 -3 1122 720 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 12067
+KPX comma quotedblright 15
+KPX comma quoteright 15
+KPX hyphen T_h -60
+KPX hyphen ydieresis.sc -70
+KPX hyphen ae.sc -30
+KPX hyphen aring.sc -15
+KPX hyphen adieresis.sc -15
+KPX hyphen y.sc -70
+KPX hyphen w.sc -10
+KPX hyphen v.sc -55
+KPX hyphen t.sc -60
+KPX hyphen a.sc -15
+KPX hyphen ycircumflex.sc -70
+KPX hyphen wgrave.sc -10
+KPX hyphen wdieresis.sc -10
+KPX hyphen wcircumflex.sc -10
+KPX hyphen wacute.sc -10
+KPX hyphen uni021B.sc -60
+KPX hyphen tcaron.sc -60
+KPX hyphen aeacute.sc -30
+KPX hyphen aogonek.sc -15
+KPX hyphen amacron.sc -15
+KPX hyphen Wdieresis -10
+KPX hyphen Wacute -10
+KPX hyphen Wgrave -10
+KPX hyphen uni021A -60
+KPX hyphen AEacute -30
+KPX hyphen Ydieresis -70
+KPX hyphen Ycircumflex -70
+KPX hyphen Wcircumflex -10
+KPX hyphen Tcaron -60
+KPX hyphen Aogonek -15
+KPX hyphen Amacron -15
+KPX hyphen AE -30
+KPX hyphen Aring -15
+KPX hyphen Adieresis -15
+KPX hyphen Y -70
+KPX hyphen W -10
+KPX hyphen V -55
+KPX hyphen T -60
+KPX hyphen A -15
+KPX A T_h -55
+KPX A ydieresis.sc -55
+KPX A udieresis.sc -40
+KPX A ucircumflex.sc -40
+KPX A oslash.sc -40
+KPX A odieresis.sc -40
+KPX A ograve.sc -40
+KPX A ccedilla.sc -40
+KPX A y.sc -55
+KPX A w.sc -60
+KPX A v.sc -105
+KPX A u.sc -40
+KPX A t.sc -45
+KPX A q.sc -35
+KPX A o.sc -40
+KPX A g.sc -45
+KPX A c.sc -40
+KPX A ycircumflex.sc -55
+KPX A wgrave.sc -60
+KPX A wdieresis.sc -60
+KPX A wcircumflex.sc -60
+KPX A wacute.sc -60
+KPX A uring.sc -40
+KPX A uogonek.sc -40
+KPX A umacron.sc -40
+KPX A uhungarumlaut.sc -40
+KPX A ubreve.sc -40
+KPX A uni021B.sc -45
+KPX A tcaron.sc -45
+KPX A omacron.sc -40
+KPX A ohungarumlaut.sc -40
+KPX A obreve.sc -40
+KPX A gdotaccent.sc -45
+KPX A gcommaaccent.sc -45
+KPX A gcircumflex.sc -45
+KPX A gbreve.sc -45
+KPX A cdotaccent.sc -40
+KPX A ccircumflex.sc -40
+KPX A ccaron.sc -40
+KPX A cacute.sc -40
+KPX A oogonek.sc -40
+KPX A gcaron.sc -45
+KPX A gacute.sc -45
+KPX A guilsinglleft -70
+KPX A quotedblright -85
+KPX A quoteright -80
+KPX A wdieresis -60
+KPX A Wdieresis -70
+KPX A wacute -60
+KPX A Wacute -70
+KPX A wgrave -60
+KPX A Wgrave -70
+KPX A ringhalfleft -85
+KPX A ringhalfright -85
+KPX A uni021B -15
+KPX A uni021A -55
+KPX A Gacute -55
+KPX A oogonek -15
+KPX A Oogonek -45
+KPX A Gcaron -55
+KPX A Ydieresis -65
+KPX A ycircumflex -70
+KPX A Ycircumflex -65
+KPX A wcircumflex -60
+KPX A Wcircumflex -70
+KPX A uogonek -25
+KPX A Uogonek -45
+KPX A uhungarumlaut -25
+KPX A Uhungarumlaut -45
+KPX A uring -25
+KPX A Uring -45
+KPX A ubreve -25
+KPX A Ubreve -45
+KPX A umacron -25
+KPX A Umacron -45
+KPX A tcaron -15
+KPX A Tcaron -55
+KPX A ohungarumlaut -15
+KPX A Ohungarumlaut -45
+KPX A obreve -15
+KPX A Obreve -45
+KPX A omacron -15
+KPX A Omacron -45
+KPX A Gcommaaccent -55
+KPX A Gdotaccent -55
+KPX A Gbreve -55
+KPX A Gcircumflex -55
+KPX A ecaron -15
+KPX A eogonek -15
+KPX A edotaccent -15
+KPX A ebreve -15
+KPX A emacron -15
+KPX A dcaron -15
+KPX A ccaron -15
+KPX A Ccaron -50
+KPX A cdotaccent -15
+KPX A Cdotaccent -50
+KPX A ccircumflex -15
+KPX A Ccircumflex -50
+KPX A cacute -15
+KPX A Cacute -50
+KPX A ydieresis -70
+KPX A udieresis -25
+KPX A ucircumflex -25
+KPX A oslash -15
+KPX A odieresis -15
+KPX A ograve -15
+KPX A edieresis -15
+KPX A ccedilla -15
+KPX A Udieresis -45
+KPX A Ucircumflex -45
+KPX A Oslash -45
+KPX A Odieresis -45
+KPX A Ograve -45
+KPX A Ccedilla -50
+KPX A guillemotleft -50
+KPX A y -70
+KPX A w -60
+KPX A v -70
+KPX A u -25
+KPX A t -15
+KPX A q -20
+KPX A o -15
+KPX A e -15
+KPX A d -15
+KPX A c -15
+KPX A Y -65
+KPX A W -70
+KPX A V -125
+KPX A U -45
+KPX A T -55
+KPX A Q -40
+KPX A O -45
+KPX A G -55
+KPX A C -50
+KPX A period 10
+KPX A hyphen -10
+KPX B ae.sc -35
+KPX B aring.sc -30
+KPX B adieresis.sc -30
+KPX B atilde.sc -30
+KPX B acircumflex.sc -30
+KPX B aacute.sc -30
+KPX B agrave.sc -30
+KPX B w.sc -15
+KPX B v.sc -15
+KPX B a.sc -30
+KPX B wgrave.sc -15
+KPX B wdieresis.sc -15
+KPX B wcircumflex.sc -15
+KPX B wacute.sc -15
+KPX B aeacute.sc -35
+KPX B aogonek.sc -30
+KPX B amacron.sc -30
+KPX B abreve.sc -30
+KPX B ahookabove.sc -30
+KPX B adotbelow.sc -30
+KPX B acircumflextilde.sc -30
+KPX B acircumflexhookabove.sc -30
+KPX B acircumflexgrave.sc -30
+KPX B acircumflexdotbelow.sc -30
+KPX B acircumflexacute.sc -30
+KPX B abrevetilde.sc -30
+KPX B abrevehookabove.sc -30
+KPX B abrevegrave.sc -30
+KPX B abrevedotbelow.sc -30
+KPX B abreveacute.sc -30
+KPX B Abrevedotbelow -35
+KPX B Abrevetilde -35
+KPX B Abrevehookabove -35
+KPX B Abrevegrave -35
+KPX B Abreveacute -35
+KPX B Acircumflexdotbelow -35
+KPX B Acircumflextilde -35
+KPX B Acircumflexhookabove -35
+KPX B Acircumflexgrave -35
+KPX B Acircumflexacute -35
+KPX B Ahookabove -35
+KPX B Adotbelow -35
+KPX B Wdieresis -20
+KPX B Wacute -20
+KPX B Wgrave -20
+KPX B AEacute -40
+KPX B Wcircumflex -20
+KPX B Aogonek -35
+KPX B Abreve -35
+KPX B Amacron -35
+KPX B AE -40
+KPX B Aring -35
+KPX B Adieresis -35
+KPX B Atilde -35
+KPX B Acircumflex -35
+KPX B Aacute -35
+KPX B Agrave -35
+KPX B W -20
+KPX B V -20
+KPX B A -35
+KPX C oslash.sc -15
+KPX C odieresis.sc -15
+KPX C otilde.sc -15
+KPX C ocircumflex.sc -15
+KPX C oacute.sc -15
+KPX C ograve.sc -15
+KPX C aring.sc 10
+KPX C adieresis.sc 10
+KPX C atilde.sc 10
+KPX C acircumflex.sc 10
+KPX C aacute.sc 10
+KPX C agrave.sc 10
+KPX C o.sc -15
+KPX C k.sc 10
+KPX C h.sc 15
+KPX C a.sc 10
+KPX C omacron.sc -15
+KPX C ohungarumlaut.sc -15
+KPX C obreve.sc -15
+KPX C kcommaaccent.sc 10
+KPX C hcircumflex.sc 15
+KPX C aogonek.sc 10
+KPX C amacron.sc 10
+KPX C abreve.sc 10
+KPX C oogonek.sc -15
+KPX C ohorntilde.sc -15
+KPX C ohornhookabove.sc -15
+KPX C ohorngrave.sc -15
+KPX C ohorndotbelow.sc -15
+KPX C ohornacute.sc -15
+KPX C ohookabove.sc -15
+KPX C odotbelow.sc -15
+KPX C ocircumflextilde.sc -15
+KPX C ocircumflexhookabove.sc -15
+KPX C ocircumflexgrave.sc -15
+KPX C ocircumflexdotbelow.sc -15
+KPX C ocircumflexacute.sc -15
+KPX C ahookabove.sc 10
+KPX C adotbelow.sc 10
+KPX C acircumflextilde.sc 10
+KPX C acircumflexhookabove.sc 10
+KPX C acircumflexgrave.sc 10
+KPX C acircumflexdotbelow.sc 10
+KPX C acircumflexacute.sc 10
+KPX C abrevetilde.sc 10
+KPX C abrevehookabove.sc 10
+KPX C abrevegrave.sc 10
+KPX C abrevedotbelow.sc 10
+KPX C abreveacute.sc 10
+KPX C Ohorndotbelow -15
+KPX C Ohorntilde -15
+KPX C Ohornhookabove -15
+KPX C Ohorngrave -15
+KPX C Ohornacute -15
+KPX C Ocircumflexdotbelow -15
+KPX C Ocircumflextilde -15
+KPX C Ocircumflexhookabove -15
+KPX C Ocircumflexgrave -15
+KPX C Ocircumflexacute -15
+KPX C Ohookabove -15
+KPX C Odotbelow -15
+KPX C Abrevedotbelow 10
+KPX C Abrevetilde 10
+KPX C Abrevehookabove 10
+KPX C Abrevegrave 10
+KPX C Abreveacute 10
+KPX C Acircumflexdotbelow 10
+KPX C Acircumflextilde 10
+KPX C Acircumflexhookabove 10
+KPX C Acircumflexgrave 10
+KPX C Acircumflexacute 10
+KPX C Ahookabove 10
+KPX C Adotbelow 10
+KPX C Oogonek -15
+KPX C Ohungarumlaut -15
+KPX C Obreve -15
+KPX C Omacron -15
+KPX C Kcommaaccent 10
+KPX C Hcircumflex 15
+KPX C Aogonek 10
+KPX C Abreve 10
+KPX C Amacron 10
+KPX C Oslash -15
+KPX C Odieresis -15
+KPX C Otilde -15
+KPX C Ocircumflex -15
+KPX C Oacute -15
+KPX C Ograve -15
+KPX C Aring 10
+KPX C Adieresis 10
+KPX C Atilde 10
+KPX C Acircumflex 10
+KPX C Aacute 10
+KPX C Agrave 10
+KPX C O -15
+KPX C K 10
+KPX C H 15
+KPX C A 10
+KPX D ydieresis.sc -25
+KPX D aring.sc -55
+KPX D adieresis.sc -55
+KPX D atilde.sc -55
+KPX D acircumflex.sc -55
+KPX D aacute.sc -55
+KPX D agrave.sc -55
+KPX D y.sc -25
+KPX D x.sc -30
+KPX D w.sc -30
+KPX D v.sc -35
+KPX D j.sc -20
+KPX D a.sc -55
+KPX D ycircumflex.sc -25
+KPX D wgrave.sc -30
+KPX D wdieresis.sc -30
+KPX D wcircumflex.sc -30
+KPX D wacute.sc -30
+KPX D jcircumflex.sc -20
+KPX D aogonek.sc -55
+KPX D amacron.sc -55
+KPX D abreve.sc -55
+KPX D Jacute -25
+KPX D jacute.sc -20
+KPX D ahookabove.sc -55
+KPX D adotbelow.sc -55
+KPX D acircumflextilde.sc -55
+KPX D acircumflexhookabove.sc -55
+KPX D acircumflexgrave.sc -55
+KPX D acircumflexdotbelow.sc -55
+KPX D acircumflexacute.sc -55
+KPX D abrevehookabove.sc -55
+KPX D abrevegrave.sc -55
+KPX D abrevedotbelow.sc -55
+KPX D abreveacute.sc -55
+KPX D Abrevedotbelow -65
+KPX D Abrevehookabove -65
+KPX D Abrevegrave -65
+KPX D Abreveacute -65
+KPX D Acircumflexdotbelow -65
+KPX D Acircumflextilde -65
+KPX D Acircumflexhookabove -65
+KPX D Acircumflexgrave -65
+KPX D Acircumflexacute -65
+KPX D Ahookabove -65
+KPX D Adotbelow -65
+KPX D Wdieresis -35
+KPX D Wacute -35
+KPX D Wgrave -35
+KPX D Ydieresis -30
+KPX D Ycircumflex -30
+KPX D Wcircumflex -35
+KPX D Jcircumflex -25
+KPX D Aogonek -65
+KPX D Abreve -65
+KPX D Amacron -65
+KPX D Aring -65
+KPX D Adieresis -65
+KPX D Atilde -65
+KPX D Acircumflex -65
+KPX D Aacute -65
+KPX D Agrave -65
+KPX D Y -30
+KPX D X -35
+KPX D W -35
+KPX D V -40
+KPX D J -25
+KPX D A -65
+KPX F ae.sc -25
+KPX F aring.sc -25
+KPX F adieresis.sc -25
+KPX F atilde.sc -25
+KPX F acircumflex.sc -25
+KPX F aacute.sc -40
+KPX F agrave.sc -25
+KPX F j.sc 15
+KPX F a.sc -55
+KPX F jcircumflex.sc 10
+KPX F aeacute.sc -25
+KPX F aogonek.sc -55
+KPX F amacron.sc -25
+KPX F abreve.sc -25
+KPX F jacute -10
+KPX F Jacute 20
+KPX F oe.sc -10
+KPX F jacute.sc 15
+KPX F ahookabove.sc -25
+KPX F acircumflexdotbelow.sc -25
+KPX F abrevedotbelow.sc -25
+KPX F ohorndotbelow -10
+KPX F ohorntilde -10
+KPX F ohornhookabove -10
+KPX F ohorngrave -10
+KPX F ohornacute -10
+KPX F ocircumflexdotbelow -10
+KPX F ohookabove -10
+KPX F ecircumflexdotbelow -10
+KPX F etilde -10
+KPX F ehookabove -10
+KPX F abrevedotbelow -20
+KPX F acircumflexdotbelow -20
+KPX F ahookabove -20
+KPX F rdotaccent -10
+KPX F aeacute -40
+KPX F AEacute -35
+KPX F oogonek -15
+KPX F rcaron -10
+KPX F rcommaaccent -15
+KPX F racute -10
+KPX F oe -20
+KPX F OE -15
+KPX F ohungarumlaut -10
+KPX F obreve -10
+KPX F omacron -10
+KPX F jcircumflex -5
+KPX F Jcircumflex 20
+KPX F ecaron -10
+KPX F eogonek -20
+KPX F edotaccent -10
+KPX F ebreve -10
+KPX F emacron -10
+KPX F aogonek -35
+KPX F Aogonek -65
+KPX F abreve -20
+KPX F amacron -20
+KPX F Amacron -65
+KPX F oslash -15
+KPX F odieresis -10
+KPX F otilde -10
+KPX F ocircumflex -10
+KPX F oacute -10
+KPX F ograve -10
+KPX F edieresis -10
+KPX F ecircumflex -10
+KPX F eacute -15
+KPX F egrave -10
+KPX F ae -40
+KPX F aring -20
+KPX F adieresis -20
+KPX F atilde -20
+KPX F acircumflex -20
+KPX F aacute -25
+KPX F agrave -20
+KPX F AE -35
+KPX F Aring -65
+KPX F Adieresis -65
+KPX F r -15
+KPX F o -15
+KPX F j -10
+KPX F e -20
+KPX F a -35
+KPX F J 20
+KPX F A -65
+KPX F period -35
+KPX F hyphen 20
+KPX F comma -45
+KPX G T_h -15
+KPX G ydieresis.sc -15
+KPX G ae.sc -15
+KPX G aring.sc -15
+KPX G adieresis.sc -15
+KPX G atilde.sc -15
+KPX G acircumflex.sc -15
+KPX G aacute.sc -15
+KPX G agrave.sc -15
+KPX G y.sc -15
+KPX G w.sc -15
+KPX G v.sc -15
+KPX G t.sc -15
+KPX G a.sc -15
+KPX G ycircumflex.sc -15
+KPX G wgrave.sc -15
+KPX G wdieresis.sc -15
+KPX G wcircumflex.sc -15
+KPX G wacute.sc -15
+KPX G uni021B.sc -15
+KPX G tcaron.sc -15
+KPX G aeacute.sc -15
+KPX G aogonek.sc -15
+KPX G amacron.sc -15
+KPX G abreve.sc -15
+KPX G ahookabove.sc -15
+KPX G adotbelow.sc -15
+KPX G acircumflextilde.sc -15
+KPX G acircumflexhookabove.sc -15
+KPX G acircumflexgrave.sc -15
+KPX G acircumflexdotbelow.sc -15
+KPX G acircumflexacute.sc -15
+KPX G abrevetilde.sc -15
+KPX G abrevehookabove.sc -15
+KPX G abrevegrave.sc -15
+KPX G abrevedotbelow.sc -15
+KPX G abreveacute.sc -15
+KPX G Abrevedotbelow -15
+KPX G Abrevetilde -15
+KPX G Abrevehookabove -15
+KPX G Abrevegrave -15
+KPX G Abreveacute -15
+KPX G Acircumflexdotbelow -15
+KPX G Acircumflextilde -15
+KPX G Acircumflexhookabove -15
+KPX G Acircumflexgrave -15
+KPX G Acircumflexacute -15
+KPX G Ahookabove -15
+KPX G Adotbelow -15
+KPX G Wdieresis -15
+KPX G Wacute -15
+KPX G Wgrave -15
+KPX G uni021A -15
+KPX G AEacute -15
+KPX G Ydieresis -15
+KPX G Ycircumflex -15
+KPX G Wcircumflex -15
+KPX G Tcaron -15
+KPX G Aogonek -15
+KPX G Abreve -15
+KPX G Amacron -15
+KPX G AE -15
+KPX G Aring -15
+KPX G Adieresis -15
+KPX G Atilde -15
+KPX G Acircumflex -15
+KPX G Aacute -15
+KPX G Agrave -15
+KPX G Y -15
+KPX G W -15
+KPX G V -20
+KPX G T -15
+KPX G A -15
+KPX J ae.sc -20
+KPX J aring.sc -25
+KPX J adieresis.sc -25
+KPX J a.sc -25
+KPX J aeacute.sc -20
+KPX J aogonek.sc -25
+KPX J amacron.sc -25
+KPX J AEacute -25
+KPX J Aogonek -30
+KPX J Amacron -30
+KPX J AE -25
+KPX J Aring -30
+KPX J Adieresis -30
+KPX J A -30
+KPX K T_h 20
+KPX K oslash.sc -35
+KPX K odieresis.sc -35
+KPX K ccedilla.sc -40
+KPX K t.sc 15
+KPX K o.sc -35
+KPX K g.sc -40
+KPX K c.sc -40
+KPX K uni021B.sc 15
+KPX K tcaron.sc 15
+KPX K omacron.sc -35
+KPX K ohungarumlaut.sc -35
+KPX K obreve.sc -35
+KPX K gdotaccent.sc -40
+KPX K gcommaaccent.sc -40
+KPX K gcircumflex.sc -40
+KPX K gbreve.sc -40
+KPX K cdotaccent.sc -40
+KPX K ccircumflex.sc -40
+KPX K ccaron.sc -40
+KPX K cacute.sc -40
+KPX K oogonek.sc -35
+KPX K oe.sc -35
+KPX K gcaron.sc -40
+KPX K gacute.sc -40
+KPX K ytilde -70
+KPX K ydotbelow -70
+KPX K ygrave -70
+KPX K ecircumflexdotbelow -10
+KPX K ecircumflexhookabove -10
+KPX K ecircumflexgrave -10
+KPX K ecircumflexacute -10
+KPX K etilde -10
+KPX K ehookabove -10
+KPX K edotbelow -10
+KPX K uni021A 20
+KPX K Gacute -50
+KPX K oogonek -10
+KPX K Oogonek -40
+KPX K Gcaron -50
+KPX K ycircumflex -70
+KPX K uogonek -25
+KPX K uhungarumlaut -25
+KPX K uring -25
+KPX K ubreve -25
+KPX K umacron -25
+KPX K Tcaron 20
+KPX K OE -40
+KPX K ohungarumlaut -10
+KPX K Ohungarumlaut -40
+KPX K obreve -10
+KPX K Obreve -40
+KPX K omacron -10
+KPX K Omacron -40
+KPX K Gcommaaccent -50
+KPX K Gdotaccent -50
+KPX K Gbreve -50
+KPX K Gcircumflex -50
+KPX K ecaron -10
+KPX K eogonek -10
+KPX K edotaccent -10
+KPX K ebreve -10
+KPX K emacron -10
+KPX K Ccaron -50
+KPX K Cdotaccent -50
+KPX K Ccircumflex -50
+KPX K Cacute -50
+KPX K ydieresis -70
+KPX K yacute -70
+KPX K udieresis -25
+KPX K ucircumflex -25
+KPX K oslash -10
+KPX K odieresis -10
+KPX K edieresis -10
+KPX K ecircumflex -10
+KPX K eacute -10
+KPX K egrave -10
+KPX K Oslash -40
+KPX K Odieresis -40
+KPX K Ccedilla -50
+KPX K y -70
+KPX K u -25
+KPX K o -10
+KPX K e -10
+KPX K T 20
+KPX K O -40
+KPX K G -50
+KPX K C -50
+KPX K hyphen -45
+KPX L T_h -65
+KPX L ydieresis.sc -65
+KPX L yacute.sc -65
+KPX L udieresis.sc -20
+KPX L ucircumflex.sc -20
+KPX L uacute.sc -20
+KPX L ugrave.sc -20
+KPX L ccedilla.sc -10
+KPX L ae.sc 15
+KPX L aring.sc 15
+KPX L adieresis.sc 15
+KPX L atilde.sc 15
+KPX L acircumflex.sc 15
+KPX L aacute.sc 15
+KPX L agrave.sc 15
+KPX L y.sc -65
+KPX L w.sc -55
+KPX L v.sc -80
+KPX L u.sc -20
+KPX L t.sc -55
+KPX L g.sc -15
+KPX L c.sc -10
+KPX L a.sc 15
+KPX L ycircumflex.sc -65
+KPX L wgrave.sc -55
+KPX L wdieresis.sc -55
+KPX L wcircumflex.sc -55
+KPX L wacute.sc -55
+KPX L utilde.sc -20
+KPX L uring.sc -20
+KPX L uogonek.sc -20
+KPX L umacron.sc -20
+KPX L uhungarumlaut.sc -20
+KPX L ubreve.sc -20
+KPX L uni021B.sc -55
+KPX L tcaron.sc -55
+KPX L gdotaccent.sc -15
+KPX L gcommaaccent.sc -15
+KPX L gcircumflex.sc -15
+KPX L gbreve.sc -15
+KPX L cdotaccent.sc -10
+KPX L ccircumflex.sc -10
+KPX L ccaron.sc -10
+KPX L cacute.sc -10
+KPX L aeacute.sc 15
+KPX L aogonek.sc 15
+KPX L amacron.sc 15
+KPX L abreve.sc 15
+KPX L uhorntilde.sc -20
+KPX L uhornhookabove.sc -20
+KPX L uhorngrave.sc -20
+KPX L uhorndotbelow.sc -20
+KPX L uhornacute.sc -20
+KPX L uhookabove.sc -20
+KPX L udotbelow.sc -20
+KPX L gcaron.sc -15
+KPX L gacute.sc -15
+KPX L ahookabove.sc 15
+KPX L adotbelow.sc 15
+KPX L acircumflextilde.sc 15
+KPX L acircumflexhookabove.sc 15
+KPX L acircumflexgrave.sc 15
+KPX L acircumflexdotbelow.sc 15
+KPX L acircumflexacute.sc 15
+KPX L abrevetilde.sc 15
+KPX L abrevehookabove.sc 15
+KPX L abrevegrave.sc 15
+KPX L abrevedotbelow.sc 15
+KPX L abreveacute.sc 15
+KPX L quotedblright -80
+KPX L quoteright -80
+KPX L uhorndotbelow -20
+KPX L Uhorndotbelow -25
+KPX L uhorntilde -20
+KPX L Uhorntilde -25
+KPX L uhornhookabove -20
+KPX L Uhornhookabove -25
+KPX L uhorngrave -20
+KPX L Uhorngrave -25
+KPX L uhornacute -20
+KPX L Uhornacute -25
+KPX L uhookabove -20
+KPX L Uhookabove -25
+KPX L udotbelow -20
+KPX L Udotbelow -25
+KPX L Abrevedotbelow 15
+KPX L Abrevetilde 15
+KPX L Abrevehookabove 15
+KPX L Abrevegrave 15
+KPX L Abreveacute 15
+KPX L Acircumflexdotbelow 15
+KPX L Acircumflextilde 15
+KPX L Acircumflexhookabove 15
+KPX L Acircumflexgrave 15
+KPX L Acircumflexacute 15
+KPX L Ahookabove 15
+KPX L Adotbelow 15
+KPX L Wdieresis -65
+KPX L Wacute -65
+KPX L Wgrave -65
+KPX L uni021A -65
+KPX L AEacute 20
+KPX L Gacute -15
+KPX L Gcaron -15
+KPX L Ydieresis -75
+KPX L ycircumflex -55
+KPX L Ycircumflex -75
+KPX L Wcircumflex -65
+KPX L uogonek -20
+KPX L Uogonek -25
+KPX L uhungarumlaut -20
+KPX L Uhungarumlaut -25
+KPX L uring -20
+KPX L Uring -25
+KPX L ubreve -20
+KPX L Ubreve -25
+KPX L umacron -20
+KPX L Umacron -25
+KPX L utilde -20
+KPX L Utilde -25
+KPX L Tcaron -65
+KPX L Gcommaaccent -15
+KPX L Gdotaccent -15
+KPX L Gbreve -15
+KPX L Gcircumflex -15
+KPX L Ccaron -10
+KPX L Cdotaccent -10
+KPX L Ccircumflex -10
+KPX L Cacute -10
+KPX L Aogonek 15
+KPX L Abreve 15
+KPX L Amacron 15
+KPX L ydieresis -55
+KPX L yacute -55
+KPX L udieresis -20
+KPX L ucircumflex -20
+KPX L uacute -20
+KPX L ugrave -20
+KPX L Yacute -75
+KPX L Udieresis -25
+KPX L Ucircumflex -25
+KPX L Uacute -25
+KPX L Ugrave -25
+KPX L Ccedilla -10
+KPX L AE 20
+KPX L Aring 15
+KPX L Adieresis 15
+KPX L Atilde 15
+KPX L Acircumflex 15
+KPX L Aacute 15
+KPX L Agrave 15
+KPX L y -55
+KPX L u -20
+KPX L Y -75
+KPX L W -65
+KPX L V -95
+KPX L U -25
+KPX L T -65
+KPX L G -15
+KPX L C -10
+KPX L A 15
+KPX L hyphen 20
+KPX N oslash.sc -15
+KPX N odieresis.sc -15
+KPX N otilde.sc -15
+KPX N ocircumflex.sc -15
+KPX N oacute.sc -15
+KPX N ograve.sc -15
+KPX N ccedilla.sc -15
+KPX N ae.sc -15
+KPX N aring.sc -20
+KPX N adieresis.sc -20
+KPX N atilde.sc -20
+KPX N acircumflex.sc -20
+KPX N aacute.sc -20
+KPX N agrave.sc -20
+KPX N o.sc -15
+KPX N g.sc -20
+KPX N c.sc -15
+KPX N a.sc -20
+KPX N omacron.sc -15
+KPX N ohungarumlaut.sc -15
+KPX N obreve.sc -15
+KPX N gdotaccent.sc -20
+KPX N gcommaaccent.sc -20
+KPX N gcircumflex.sc -20
+KPX N gbreve.sc -20
+KPX N cdotaccent.sc -15
+KPX N ccircumflex.sc -15
+KPX N ccaron.sc -15
+KPX N cacute.sc -15
+KPX N aeacute.sc -15
+KPX N aogonek.sc -20
+KPX N amacron.sc -20
+KPX N abreve.sc -20
+KPX N oogonek.sc -15
+KPX N ohorntilde.sc -15
+KPX N ohornhookabove.sc -15
+KPX N ohorngrave.sc -15
+KPX N ohorndotbelow.sc -15
+KPX N ohornacute.sc -15
+KPX N ohookabove.sc -15
+KPX N odotbelow.sc -15
+KPX N ocircumflextilde.sc -15
+KPX N ocircumflexhookabove.sc -15
+KPX N ocircumflexgrave.sc -15
+KPX N ocircumflexdotbelow.sc -15
+KPX N ocircumflexacute.sc -15
+KPX N gcaron.sc -20
+KPX N gacute.sc -20
+KPX N ahookabove.sc -20
+KPX N adotbelow.sc -20
+KPX N acircumflextilde.sc -20
+KPX N acircumflexhookabove.sc -20
+KPX N acircumflexgrave.sc -20
+KPX N acircumflexdotbelow.sc -20
+KPX N acircumflexacute.sc -20
+KPX N abrevegrave.sc -20
+KPX N abrevedotbelow.sc -20
+KPX N abreveacute.sc -20
+KPX N uhorndotbelow -30
+KPX N uhorntilde -30
+KPX N uhornhookabove -30
+KPX N uhorngrave -30
+KPX N uhornacute -30
+KPX N uhookabove -30
+KPX N udotbelow -30
+KPX N ohorndotbelow -20
+KPX N Ohorndotbelow -20
+KPX N ohorntilde -20
+KPX N Ohorntilde -20
+KPX N ohornhookabove -20
+KPX N Ohornhookabove -20
+KPX N ohorngrave -20
+KPX N Ohorngrave -20
+KPX N ohornacute -20
+KPX N Ohornacute -20
+KPX N ocircumflexdotbelow -20
+KPX N Ocircumflexdotbelow -20
+KPX N ocircumflextilde -20
+KPX N Ocircumflextilde -20
+KPX N ocircumflexhookabove -20
+KPX N Ocircumflexhookabove -20
+KPX N ocircumflexgrave -20
+KPX N Ocircumflexgrave -20
+KPX N ocircumflexacute -20
+KPX N Ocircumflexacute -20
+KPX N ohookabove -20
+KPX N Ohookabove -20
+KPX N odotbelow -20
+KPX N Odotbelow -20
+KPX N ecircumflexdotbelow -25
+KPX N ecircumflexhookabove -25
+KPX N ecircumflexgrave -25
+KPX N ecircumflexacute -25
+KPX N ehookabove -25
+KPX N edotbelow -25
+KPX N abrevedotbelow -30
+KPX N Abrevedotbelow -25
+KPX N abrevegrave -30
+KPX N Abrevegrave -25
+KPX N abreveacute -30
+KPX N Abreveacute -25
+KPX N acircumflexdotbelow -30
+KPX N Acircumflexdotbelow -25
+KPX N acircumflextilde -30
+KPX N Acircumflextilde -25
+KPX N acircumflexhookabove -30
+KPX N Acircumflexhookabove -25
+KPX N acircumflexgrave -30
+KPX N Acircumflexgrave -25
+KPX N acircumflexacute -30
+KPX N Acircumflexacute -25
+KPX N ahookabove -30
+KPX N Ahookabove -25
+KPX N adotbelow -30
+KPX N Adotbelow -25
+KPX N aeacute -30
+KPX N AEacute -20
+KPX N Gacute -25
+KPX N oogonek -20
+KPX N Oogonek -20
+KPX N Gcaron -25
+KPX N uogonek -30
+KPX N uhungarumlaut -30
+KPX N uring -30
+KPX N ubreve -30
+KPX N umacron -30
+KPX N utilde -30
+KPX N ohungarumlaut -20
+KPX N Ohungarumlaut -20
+KPX N obreve -20
+KPX N Obreve -20
+KPX N omacron -20
+KPX N Omacron -20
+KPX N Gcommaaccent -25
+KPX N Gdotaccent -25
+KPX N Gbreve -25
+KPX N Gcircumflex -25
+KPX N ecaron -25
+KPX N eogonek -25
+KPX N edotaccent -25
+KPX N ebreve -25
+KPX N emacron -25
+KPX N Ccaron -20
+KPX N Cdotaccent -20
+KPX N Ccircumflex -20
+KPX N Cacute -20
+KPX N aogonek -30
+KPX N Aogonek -25
+KPX N abreve -30
+KPX N Abreve -25
+KPX N amacron -30
+KPX N Amacron -25
+KPX N udieresis -30
+KPX N ucircumflex -30
+KPX N uacute -30
+KPX N ugrave -30
+KPX N oslash -20
+KPX N odieresis -20
+KPX N otilde -20
+KPX N ocircumflex -20
+KPX N oacute -20
+KPX N ograve -20
+KPX N edieresis -25
+KPX N ecircumflex -25
+KPX N eacute -25
+KPX N egrave -25
+KPX N ae -30
+KPX N aring -30
+KPX N adieresis -30
+KPX N atilde -30
+KPX N acircumflex -30
+KPX N aacute -30
+KPX N agrave -30
+KPX N Oslash -20
+KPX N Odieresis -20
+KPX N Otilde -20
+KPX N Ocircumflex -20
+KPX N Oacute -20
+KPX N Ograve -20
+KPX N Ccedilla -20
+KPX N AE -20
+KPX N Aring -25
+KPX N Adieresis -25
+KPX N Atilde -25
+KPX N Acircumflex -25
+KPX N Aacute -25
+KPX N Agrave -25
+KPX N u -30
+KPX N o -20
+KPX N e -25
+KPX N a -30
+KPX N O -20
+KPX N G -25
+KPX N C -20
+KPX N A -25
+KPX N comma -10
+KPX O ydieresis.sc -30
+KPX O ae.sc -45
+KPX O aring.sc -40
+KPX O adieresis.sc -40
+KPX O atilde.sc -40
+KPX O aacute.sc -40
+KPX O agrave.sc -40
+KPX O y.sc -30
+KPX O x.sc -35
+KPX O w.sc -25
+KPX O v.sc -40
+KPX O a.sc -40
+KPX O ycircumflex.sc -30
+KPX O wgrave.sc -25
+KPX O wdieresis.sc -25
+KPX O wcircumflex.sc -25
+KPX O wacute.sc -25
+KPX O aeacute.sc -45
+KPX O aogonek.sc -40
+KPX O amacron.sc -40
+KPX O abreve.sc -40
+KPX O ahookabove.sc -40
+KPX O adotbelow.sc -40
+KPX O abrevetilde.sc -40
+KPX O abrevehookabove.sc -40
+KPX O abrevegrave.sc -40
+KPX O abrevedotbelow.sc -40
+KPX O abreveacute.sc -40
+KPX O Abrevedotbelow -50
+KPX O Abrevetilde -50
+KPX O Abrevehookabove -50
+KPX O Abrevegrave -50
+KPX O Abreveacute -50
+KPX O Ahookabove -50
+KPX O Adotbelow -50
+KPX O Wdieresis -30
+KPX O Wacute -30
+KPX O Wgrave -30
+KPX O AEacute -55
+KPX O Ydieresis -35
+KPX O Ycircumflex -35
+KPX O Wcircumflex -30
+KPX O Aogonek -50
+KPX O Abreve -50
+KPX O Amacron -50
+KPX O AE -55
+KPX O Aring -50
+KPX O Adieresis -50
+KPX O Atilde -50
+KPX O Aacute -50
+KPX O Agrave -50
+KPX O Y -35
+KPX O X -40
+KPX O W -30
+KPX O V -50
+KPX O A -50
+KPX P ae.sc -70
+KPX P aring.sc -75
+KPX P adieresis.sc -75
+KPX P aacute.sc -75
+KPX P a.sc -75
+KPX P aeacute.sc -70
+KPX P aogonek.sc -75
+KPX P amacron.sc -75
+KPX P aeacute -30
+KPX P AEacute -85
+KPX P oogonek -35
+KPX P oe -35
+KPX P ohungarumlaut -35
+KPX P obreve -35
+KPX P omacron -35
+KPX P ecaron -35
+KPX P eogonek -35
+KPX P edotaccent -35
+KPX P ebreve -35
+KPX P emacron -35
+KPX P aogonek -30
+KPX P Aogonek -90
+KPX P amacron -30
+KPX P Amacron -90
+KPX P oslash -35
+KPX P odieresis -35
+KPX P ocircumflex -35
+KPX P edieresis -35
+KPX P ecircumflex -35
+KPX P egrave -35
+KPX P ae -30
+KPX P aring -30
+KPX P adieresis -30
+KPX P aacute -30
+KPX P AE -85
+KPX P Aring -90
+KPX P Adieresis -90
+KPX P Aacute -90
+KPX P o -35
+KPX P e -35
+KPX P a -30
+KPX P A -90
+KPX P period -85
+KPX P hyphen -30
+KPX P comma -95
+KPX R T_h -25
+KPX R ydieresis.sc -25
+KPX R udieresis.sc -35
+KPX R ucircumflex.sc -35
+KPX R uacute.sc -35
+KPX R ugrave.sc -35
+KPX R oslash.sc -30
+KPX R odieresis.sc -30
+KPX R otilde.sc -30
+KPX R ocircumflex.sc -30
+KPX R oacute.sc -30
+KPX R ograve.sc -30
+KPX R ccedilla.sc -30
+KPX R y.sc -25
+KPX R w.sc -35
+KPX R v.sc -35
+KPX R u.sc -35
+KPX R t.sc -20
+KPX R o.sc -30
+KPX R g.sc -30
+KPX R c.sc -30
+KPX R ycircumflex.sc -25
+KPX R wgrave.sc -35
+KPX R wdieresis.sc -35
+KPX R wcircumflex.sc -35
+KPX R wacute.sc -35
+KPX R utilde.sc -35
+KPX R uring.sc -35
+KPX R uogonek.sc -35
+KPX R umacron.sc -35
+KPX R uhungarumlaut.sc -35
+KPX R ubreve.sc -35
+KPX R uni021B.sc -20
+KPX R tcaron.sc -20
+KPX R omacron.sc -30
+KPX R ohungarumlaut.sc -30
+KPX R obreve.sc -30
+KPX R gdotaccent.sc -30
+KPX R gcommaaccent.sc -30
+KPX R gcircumflex.sc -30
+KPX R gbreve.sc -30
+KPX R cdotaccent.sc -30
+KPX R ccircumflex.sc -30
+KPX R ccaron.sc -30
+KPX R cacute.sc -30
+KPX R uhorntilde.sc -35
+KPX R uhornhookabove.sc -35
+KPX R uhorngrave.sc -35
+KPX R uhorndotbelow.sc -35
+KPX R uhornacute.sc -35
+KPX R uhookabove.sc -35
+KPX R udotbelow.sc -35
+KPX R oogonek.sc -30
+KPX R ohorntilde.sc -30
+KPX R ohornhookabove.sc -30
+KPX R ohorngrave.sc -30
+KPX R ohorndotbelow.sc -30
+KPX R ohornacute.sc -30
+KPX R ohookabove.sc -30
+KPX R oe.sc -25
+KPX R odotbelow.sc -30
+KPX R ocircumflextilde.sc -30
+KPX R ocircumflexhookabove.sc -30
+KPX R ocircumflexgrave.sc -30
+KPX R ocircumflexdotbelow.sc -30
+KPX R ocircumflexacute.sc -30
+KPX R gcaron.sc -30
+KPX R gacute.sc -30
+KPX R uhorndotbelow -20
+KPX R Uhorndotbelow -40
+KPX R uhorntilde -20
+KPX R Uhorntilde -40
+KPX R uhornhookabove -20
+KPX R Uhornhookabove -40
+KPX R uhorngrave -20
+KPX R Uhorngrave -40
+KPX R uhornacute -20
+KPX R Uhornacute -40
+KPX R uhookabove -20
+KPX R Uhookabove -40
+KPX R udotbelow -20
+KPX R Udotbelow -40
+KPX R ohorndotbelow -10
+KPX R Ohorndotbelow -35
+KPX R ohorntilde -10
+KPX R Ohorntilde -35
+KPX R ohornhookabove -10
+KPX R Ohornhookabove -35
+KPX R ohorngrave -10
+KPX R Ohorngrave -35
+KPX R ohornacute -10
+KPX R Ohornacute -35
+KPX R ocircumflexdotbelow -10
+KPX R Ocircumflexdotbelow -35
+KPX R ocircumflextilde -10
+KPX R Ocircumflextilde -35
+KPX R ocircumflexhookabove -10
+KPX R Ocircumflexhookabove -35
+KPX R ocircumflexgrave -10
+KPX R Ocircumflexgrave -35
+KPX R ocircumflexacute -10
+KPX R Ocircumflexacute -35
+KPX R ohookabove -10
+KPX R Ohookabove -35
+KPX R odotbelow -10
+KPX R Odotbelow -35
+KPX R ecircumflexdotbelow -10
+KPX R ecircumflextilde -10
+KPX R ecircumflexhookabove -10
+KPX R ecircumflexgrave -10
+KPX R ecircumflexacute -10
+KPX R etilde -10
+KPX R ehookabove -10
+KPX R edotbelow -10
+KPX R abrevedotbelow 10
+KPX R abrevegrave 10
+KPX R abreveacute 10
+KPX R acircumflexdotbelow 10
+KPX R acircumflextilde 10
+KPX R acircumflexhookabove 10
+KPX R acircumflexgrave 10
+KPX R acircumflexacute 10
+KPX R ahookabove 10
+KPX R adotbelow 10
+KPX R Wdieresis -40
+KPX R Wacute -40
+KPX R Wgrave -40
+KPX R uni021A -25
+KPX R Gacute -35
+KPX R oogonek -10
+KPX R Oogonek -35
+KPX R Gcaron -35
+KPX R Ydieresis -30
+KPX R ycircumflex -25
+KPX R Ycircumflex -30
+KPX R Wcircumflex -40
+KPX R uogonek -20
+KPX R Uogonek -40
+KPX R uhungarumlaut -20
+KPX R Uhungarumlaut -40
+KPX R uring -20
+KPX R Uring -40
+KPX R ubreve -20
+KPX R Ubreve -40
+KPX R umacron -20
+KPX R Umacron -40
+KPX R utilde -20
+KPX R Utilde -40
+KPX R Tcaron -25
+KPX R oe -15
+KPX R OE -30
+KPX R ohungarumlaut -10
+KPX R Ohungarumlaut -35
+KPX R obreve -10
+KPX R Obreve -35
+KPX R omacron -10
+KPX R Omacron -35
+KPX R Gcommaaccent -35
+KPX R Gdotaccent -35
+KPX R Gbreve -35
+KPX R Gcircumflex -35
+KPX R ecaron -10
+KPX R eogonek -10
+KPX R edotaccent -10
+KPX R ebreve -10
+KPX R emacron -10
+KPX R Ccaron -35
+KPX R Cdotaccent -35
+KPX R Ccircumflex -35
+KPX R Cacute -35
+KPX R aogonek 10
+KPX R abreve 10
+KPX R amacron 10
+KPX R ydieresis -25
+KPX R udieresis -20
+KPX R ucircumflex -20
+KPX R uacute -20
+KPX R ugrave -20
+KPX R oslash -10
+KPX R odieresis -10
+KPX R otilde -10
+KPX R ocircumflex -10
+KPX R oacute -10
+KPX R ograve -10
+KPX R edieresis -10
+KPX R ecircumflex -10
+KPX R eacute -10
+KPX R egrave -10
+KPX R aring 10
+KPX R adieresis 10
+KPX R atilde 10
+KPX R acircumflex 10
+KPX R aacute 10
+KPX R agrave 10
+KPX R Udieresis -40
+KPX R Ucircumflex -40
+KPX R Uacute -40
+KPX R Ugrave -40
+KPX R Oslash -35
+KPX R Odieresis -35
+KPX R Otilde -35
+KPX R Ocircumflex -35
+KPX R Oacute -35
+KPX R Ograve -35
+KPX R Ccedilla -35
+KPX R y -25
+KPX R u -20
+KPX R o -10
+KPX R e -10
+KPX R a 10
+KPX R Y -30
+KPX R W -40
+KPX R V -40
+KPX R U -40
+KPX R T -25
+KPX R O -35
+KPX R G -35
+KPX R C -35
+KPX R hyphen -20
+KPX S ae.sc -25
+KPX S aring.sc -20
+KPX S adieresis.sc -20
+KPX S atilde.sc -20
+KPX S acircumflex.sc -20
+KPX S aacute.sc -20
+KPX S agrave.sc -20
+KPX S a.sc -20
+KPX S aeacute.sc -25
+KPX S aogonek.sc -20
+KPX S amacron.sc -20
+KPX S abreve.sc -20
+KPX S ahookabove.sc -20
+KPX S adotbelow.sc -20
+KPX S acircumflextilde.sc -20
+KPX S acircumflexhookabove.sc -20
+KPX S acircumflexgrave.sc -20
+KPX S acircumflexdotbelow.sc -20
+KPX S acircumflexacute.sc -20
+KPX S abrevetilde.sc -20
+KPX S abrevegrave.sc -20
+KPX S abrevedotbelow.sc -20
+KPX S abreveacute.sc -20
+KPX S Abrevedotbelow -25
+KPX S Abrevetilde -25
+KPX S Abrevegrave -25
+KPX S Abreveacute -25
+KPX S Acircumflexdotbelow -25
+KPX S Acircumflextilde -25
+KPX S Acircumflexhookabove -25
+KPX S Acircumflexgrave -25
+KPX S Acircumflexacute -25
+KPX S Ahookabove -25
+KPX S Adotbelow -25
+KPX S uni021B -15
+KPX S AEacute -30
+KPX S tcaron -15
+KPX S Aogonek -25
+KPX S Abreve -25
+KPX S Amacron -25
+KPX S AE -30
+KPX S Aring -25
+KPX S Adieresis -25
+KPX S Atilde -25
+KPX S Acircumflex -25
+KPX S Aacute -25
+KPX S Agrave -25
+KPX S t -15
+KPX S A -25
+KPX T ydieresis.sc 15
+KPX T yacute.sc 20
+KPX T oslash.sc -10
+KPX T odieresis.sc -5
+KPX T otilde.sc -5
+KPX T ocircumflex.sc -5
+KPX T oacute.sc -5
+KPX T ograve.sc -5
+KPX T ccedilla.sc -10
+KPX T ae.sc -55
+KPX T aring.sc -25
+KPX T adieresis.sc -25
+KPX T atilde.sc -25
+KPX T acircumflex.sc -25
+KPX T aacute.sc -35
+KPX T agrave.sc -25
+KPX T y.sc 25
+KPX T w.sc 25
+KPX T v.sc 25
+KPX T o.sc -10
+KPX T j.sc 15
+KPX T g.sc -15
+KPX T c.sc -10
+KPX T a.sc -45
+KPX T ygrave.sc 15
+KPX T ycircumflex.sc 15
+KPX T wgrave.sc 15
+KPX T wdieresis.sc 15
+KPX T wcircumflex.sc 15
+KPX T wacute.sc 20
+KPX T omacron.sc -5
+KPX T ohungarumlaut.sc -5
+KPX T obreve.sc -5
+KPX T jcircumflex.sc 10
+KPX T gdotaccent.sc -5
+KPX T gcommaaccent.sc -15
+KPX T gcircumflex.sc -5
+KPX T gbreve.sc -5
+KPX T cdotaccent.sc -5
+KPX T ccircumflex.sc -5
+KPX T ccaron.sc -5
+KPX T cacute.sc -5
+KPX T aeacute.sc -55
+KPX T aogonek.sc -45
+KPX T amacron.sc -25
+KPX T abreve.sc -25
+KPX T jacute -10
+KPX T Jacute 20
+KPX T ytilde.sc 15
+KPX T yhookabove.sc 15
+KPX T oogonek.sc -10
+KPX T ohorntilde.sc -5
+KPX T ohornhookabove.sc -5
+KPX T ohorngrave.sc -5
+KPX T ohorndotbelow.sc -5
+KPX T ohornacute.sc -5
+KPX T ohookabove.sc -5
+KPX T oe.sc -25
+KPX T odotbelow.sc -10
+KPX T ocircumflexdotbelow.sc -5
+KPX T jacute.sc 15
+KPX T gcaron.sc -5
+KPX T gacute.sc -10
+KPX T ahookabove.sc -25
+KPX T adotbelow.sc -45
+KPX T acircumflexdotbelow.sc -25
+KPX T abrevedotbelow.sc -25
+KPX T guilsinglleft -125
+KPX T ytilde -50
+KPX T yhookabove -50
+KPX T ygrave -50
+KPX T uhorndotbelow -50
+KPX T uhorntilde -50
+KPX T uhornhookabove -50
+KPX T uhorngrave -50
+KPX T uhornacute -50
+KPX T uhookabove -50
+KPX T udotbelow -100
+KPX T ohorndotbelow -45
+KPX T Ohorndotbelow -10
+KPX T ohorntilde -45
+KPX T ohornhookabove -45
+KPX T Ohornhookabove -10
+KPX T ohorngrave -45
+KPX T Ohorngrave -10
+KPX T ohornacute -45
+KPX T Ohornacute -10
+KPX T ocircumflexdotbelow -45
+KPX T Ocircumflexdotbelow -10
+KPX T Ocircumflexhookabove -10
+KPX T Ocircumflexgrave -10
+KPX T Ocircumflexacute -10
+KPX T ohookabove -45
+KPX T Ohookabove -10
+KPX T odotbelow -90
+KPX T Odotbelow -10
+KPX T idotbelow -10
+KPX T ihookabove -5
+KPX T ecircumflexdotbelow -45
+KPX T etilde -45
+KPX T ehookabove -45
+KPX T edotbelow -90
+KPX T abrevedotbelow -35
+KPX T Abrevedotbelow -55
+KPX T Abrevehookabove -55
+KPX T Abrevegrave -55
+KPX T Abreveacute -55
+KPX T acircumflexdotbelow -35
+KPX T Acircumflexdotbelow -55
+KPX T Acircumflexhookabove -55
+KPX T Acircumflexgrave -55
+KPX T Acircumflexacute -55
+KPX T ahookabove -35
+KPX T Ahookabove -55
+KPX T adotbelow -70
+KPX T Adotbelow -55
+KPX T wdieresis -50
+KPX T Wdieresis 30
+KPX T wacute -70
+KPX T Wacute 30
+KPX T wgrave -50
+KPX T Wgrave 30
+KPX T rdotaccent -30
+KPX T uni0219 -65
+KPX T aeacute -60
+KPX T AEacute -80
+KPX T gacute -60
+KPX T Gacute -15
+KPX T oogonek -90
+KPX T Oogonek -10
+KPX T gcaron -40
+KPX T Gcaron -15
+KPX T Ydieresis 30
+KPX T ycircumflex -50
+KPX T Ycircumflex 30
+KPX T wcircumflex -50
+KPX T Wcircumflex 30
+KPX T uogonek -100
+KPX T uhungarumlaut -50
+KPX T uring -50
+KPX T ubreve -50
+KPX T umacron -50
+KPX T utilde -50
+KPX T scaron -35
+KPX T scedilla -65
+KPX T scircumflex -35
+KPX T sacute -50
+KPX T rcaron -30
+KPX T rcommaaccent -60
+KPX T racute -45
+KPX T oe -50
+KPX T OE -35
+KPX T ohungarumlaut -45
+KPX T Ohungarumlaut -10
+KPX T obreve -45
+KPX T Obreve -10
+KPX T omacron -45
+KPX T Omacron -10
+KPX T jcircumflex -5
+KPX T Jcircumflex 20
+KPX T iogonek -10
+KPX T ibreve -5
+KPX T imacron -5
+KPX T itilde -5
+KPX T gcommaaccent -80
+KPX T Gcommaaccent -15
+KPX T gdotaccent -40
+KPX T Gdotaccent -15
+KPX T gbreve -40
+KPX T Gbreve -15
+KPX T gcircumflex -40
+KPX T Gcircumflex -15
+KPX T ecaron -45
+KPX T eogonek -90
+KPX T edotaccent -45
+KPX T ebreve -45
+KPX T emacron -45
+KPX T ccaron -45
+KPX T Ccaron -10
+KPX T cdotaccent -45
+KPX T Cdotaccent -10
+KPX T ccircumflex -45
+KPX T Ccircumflex -10
+KPX T cacute -70
+KPX T Cacute -10
+KPX T aogonek -70
+KPX T Aogonek -55
+KPX T abreve -35
+KPX T Abreve -55
+KPX T amacron -35
+KPX T Amacron -55
+KPX T ydieresis -50
+KPX T yacute -70
+KPX T udieresis -50
+KPX T ucircumflex -50
+KPX T uacute -75
+KPX T ugrave -50
+KPX T oslash -90
+KPX T odieresis -45
+KPX T otilde -45
+KPX T ocircumflex -45
+KPX T oacute -70
+KPX T ograve -45
+KPX T idieresis -5
+KPX T icircumflex -5
+KPX T iacute -10
+KPX T igrave -5
+KPX T edieresis -45
+KPX T ecircumflex -45
+KPX T eacute -70
+KPX T egrave -45
+KPX T ccedilla -90
+KPX T ae -60
+KPX T aring -35
+KPX T adieresis -35
+KPX T atilde -35
+KPX T acircumflex -35
+KPX T aacute -55
+KPX T agrave -35
+KPX T Oslash -10
+KPX T Odieresis -10
+KPX T Otilde -10
+KPX T Ocircumflex -10
+KPX T Oacute -10
+KPX T Ograve -10
+KPX T Ccedilla -10
+KPX T AE -80
+KPX T Aring -55
+KPX T Adieresis -55
+KPX T Atilde -55
+KPX T Acircumflex -55
+KPX T Aacute -55
+KPX T Agrave -55
+KPX T guillemotleft -100
+KPX T y -95
+KPX T w -95
+KPX T v -95
+KPX T u -100
+KPX T s -65
+KPX T r -60
+KPX T o -90
+KPX T j -10
+KPX T i -10
+KPX T g -80
+KPX T e -90
+KPX T c -90
+KPX T a -70
+KPX T Y 30
+KPX T W 30
+KPX T V 30
+KPX T O -10
+KPX T J 20
+KPX T G -15
+KPX T C -10
+KPX T A -55
+KPX T semicolon -70
+KPX T colon -65
+KPX T period -65
+KPX T hyphen -60
+KPX T comma -70
+KPX U ae.sc -45
+KPX U aring.sc -20
+KPX U adieresis.sc -20
+KPX U atilde.sc -20
+KPX U acircumflex.sc -20
+KPX U aacute.sc -30
+KPX U agrave.sc -20
+KPX U a.sc -40
+KPX U aeacute.sc -45
+KPX U aogonek.sc -40
+KPX U amacron.sc -20
+KPX U abreve.sc -20
+KPX U ahookabove.sc -20
+KPX U adotbelow.sc -40
+KPX U acircumflexdotbelow.sc -20
+KPX U abrevedotbelow.sc -20
+KPX U Abrevedotbelow -50
+KPX U Abrevehookabove -50
+KPX U Abrevegrave -50
+KPX U Abreveacute -50
+KPX U Acircumflexdotbelow -50
+KPX U Acircumflextilde -50
+KPX U Acircumflexhookabove -50
+KPX U Acircumflexgrave -50
+KPX U Acircumflexacute -50
+KPX U Ahookabove -50
+KPX U Adotbelow -50
+KPX U rdotaccent -15
+KPX U AEacute -55
+KPX U rcaron -15
+KPX U rcommaaccent -25
+KPX U racute -20
+KPX U ncaron -10
+KPX U ncommaaccent -20
+KPX U nacute -15
+KPX U Aogonek -50
+KPX U Abreve -50
+KPX U Amacron -50
+KPX U ntilde -10
+KPX U AE -55
+KPX U Aring -50
+KPX U Adieresis -50
+KPX U Atilde -50
+KPX U Acircumflex -50
+KPX U Aacute -50
+KPX U Agrave -50
+KPX U r -25
+KPX U p -25
+KPX U n -20
+KPX U m -20
+KPX U A -50
+KPX U period -15
+KPX U comma -25
+KPX V zcaron -73
+KPX V zdotaccent -73
+KPX V zacute -73
+KPX V z -73
+KPX V ccaron -90
+KPX V cdotaccent -90
+KPX V ccircumflex -90
+KPX V cacute -90
+KPX V ccedilla -90
+KPX V c -90
+KPX V scaron -75
+KPX V scedilla -75
+KPX V scircumflex -75
+KPX V sacute -75
+KPX V s -75
+KPX V T_h 30
+KPX V oslash.sc -40
+KPX V odieresis.sc -20
+KPX V otilde.sc -20
+KPX V ocircumflex.sc -20
+KPX V oacute.sc -30
+KPX V ograve.sc -20
+KPX V ccedilla.sc -45
+KPX V ae.sc -55
+KPX V aring.sc -50
+KPX V adieresis.sc -50
+KPX V atilde.sc -50
+KPX V acircumflex.sc -50
+KPX V aacute.sc -70
+KPX V agrave.sc -50
+KPX V t.sc 25
+KPX V s.sc -20
+KPX V o.sc -40
+KPX V g.sc -45
+KPX V c.sc -45
+KPX V a.sc -95
+KPX V uni021B.sc 25
+KPX V tcaron.sc 15
+KPX V uni0219.sc -20
+KPX V scircumflex.sc -10
+KPX V scedilla.sc -20
+KPX V sacute.sc -15
+KPX V omacron.sc -20
+KPX V ohungarumlaut.sc -20
+KPX V obreve.sc -20
+KPX V gdotaccent.sc -25
+KPX V gcommaaccent.sc -45
+KPX V gcircumflex.sc -25
+KPX V gbreve.sc -25
+KPX V cdotaccent.sc -25
+KPX V ccircumflex.sc -25
+KPX V ccaron.sc -25
+KPX V cacute.sc -35
+KPX V aeacute.sc -55
+KPX V aogonek.sc -95
+KPX V amacron.sc -50
+KPX V abreve.sc -50
+KPX V scaron.sc -10
+KPX V oogonek.sc -40
+KPX V ohorntilde.sc -20
+KPX V ohornhookabove.sc -20
+KPX V ohorngrave.sc -20
+KPX V ohorndotbelow.sc -20
+KPX V ohornacute.sc -20
+KPX V ohookabove.sc -20
+KPX V oe.sc -25
+KPX V odotbelow.sc -40
+KPX V ocircumflexdotbelow.sc -20
+KPX V gcaron.sc -25
+KPX V gacute.sc -35
+KPX V ahookabove.sc -50
+KPX V adotbelow.sc -95
+KPX V acircumflexdotbelow.sc -50
+KPX V abrevedotbelow.sc -50
+KPX V guilsinglleft -110
+KPX V ytilde -20
+KPX V yhookabove -20
+KPX V ygrave -20
+KPX V uhorndotbelow -25
+KPX V uhorntilde -25
+KPX V uhornhookabove -25
+KPX V uhorngrave -25
+KPX V uhornacute -25
+KPX V uhookabove -25
+KPX V udotbelow -50
+KPX V ohorndotbelow -45
+KPX V Ohorndotbelow -50
+KPX V ohorntilde -45
+KPX V Ohorntilde -50
+KPX V ohornhookabove -45
+KPX V Ohornhookabove -50
+KPX V ohorngrave -45
+KPX V Ohorngrave -50
+KPX V ohornacute -45
+KPX V Ohornacute -50
+KPX V ocircumflexdotbelow -45
+KPX V Ocircumflexdotbelow -50
+KPX V Ocircumflextilde -50
+KPX V Ocircumflexhookabove -50
+KPX V Ocircumflexgrave -50
+KPX V Ocircumflexacute -50
+KPX V ohookabove -45
+KPX V Ohookabove -50
+KPX V odotbelow -85
+KPX V Odotbelow -50
+KPX V ecircumflexdotbelow -45
+KPX V etilde -45
+KPX V ehookabove -45
+KPX V edotbelow -85
+KPX V abrevedotbelow -45
+KPX V Abrevedotbelow -115
+KPX V Abrevehookabove -115
+KPX V Abrevegrave -115
+KPX V Abreveacute -115
+KPX V acircumflexdotbelow -45
+KPX V Acircumflexdotbelow -115
+KPX V Acircumflextilde -115
+KPX V Acircumflexhookabove -115
+KPX V Acircumflexgrave -115
+KPX V Acircumflexacute -115
+KPX V ahookabove -45
+KPX V Ahookabove -115
+KPX V adotbelow -85
+KPX V Adotbelow -115
+KPX V rdotaccent -25
+KPX V uni021A 30
+KPX V uni0218 -25
+KPX V aeacute -60
+KPX V AEacute -80
+KPX V gacute -60
+KPX V Gacute -55
+KPX V oogonek -85
+KPX V Oogonek -50
+KPX V gcaron -40
+KPX V Gcaron -55
+KPX V ycircumflex -20
+KPX V uogonek -50
+KPX V uhungarumlaut -25
+KPX V uring -25
+KPX V ubreve -25
+KPX V umacron -25
+KPX V utilde -25
+KPX V Tcaron 30
+KPX V Scaron -25
+KPX V Scedilla -25
+KPX V Scircumflex -25
+KPX V Sacute -25
+KPX V rcaron -25
+KPX V rcommaaccent -50
+KPX V racute -40
+KPX V oe -50
+KPX V OE -35
+KPX V ohungarumlaut -45
+KPX V Ohungarumlaut -50
+KPX V obreve -45
+KPX V Obreve -50
+KPX V omacron -45
+KPX V Omacron -50
+KPX V gcommaaccent -80
+KPX V Gcommaaccent -55
+KPX V gdotaccent -40
+KPX V Gdotaccent -55
+KPX V gbreve -40
+KPX V Gbreve -55
+KPX V gcircumflex -40
+KPX V Gcircumflex -55
+KPX V ecaron -45
+KPX V eogonek -85
+KPX V edotaccent -45
+KPX V ebreve -45
+KPX V emacron -45
+KPX V Ccaron -55
+KPX V Cdotaccent -55
+KPX V Ccircumflex -55
+KPX V Cacute -55
+KPX V aogonek -85
+KPX V Aogonek -115
+KPX V abreve -45
+KPX V Abreve -115
+KPX V amacron -45
+KPX V Amacron -115
+KPX V ydieresis -20
+KPX V yacute -25
+KPX V udieresis -25
+KPX V ucircumflex -25
+KPX V uacute -40
+KPX V ugrave -25
+KPX V oslash -85
+KPX V odieresis -45
+KPX V otilde -45
+KPX V ocircumflex -45
+KPX V oacute -65
+KPX V ograve -45
+KPX V edieresis -45
+KPX V ecircumflex -45
+KPX V eacute -65
+KPX V egrave -45
+KPX V ae -60
+KPX V aring -45
+KPX V adieresis -45
+KPX V atilde -45
+KPX V acircumflex -45
+KPX V aacute -65
+KPX V agrave -45
+KPX V Oslash -50
+KPX V Odieresis -50
+KPX V Otilde -50
+KPX V Ocircumflex -50
+KPX V Oacute -50
+KPX V Ograve -50
+KPX V Ccedilla -55
+KPX V AE -80
+KPX V Aring -115
+KPX V Adieresis -115
+KPX V Atilde -115
+KPX V Acircumflex -115
+KPX V Aacute -115
+KPX V Agrave -115
+KPX V guillemotleft -90
+KPX V y -35
+KPX V u -50
+KPX V r -50
+KPX V o -85
+KPX V g -80
+KPX V e -85
+KPX V a -85
+KPX V T 30
+KPX V S -25
+KPX V O -50
+KPX V G -55
+KPX V C -55
+KPX V A -115
+KPX V semicolon -75
+KPX V colon -65
+KPX V period -90
+KPX V hyphen -50
+KPX V comma -100
+KPX W zcaron -53
+KPX W zdotaccent -53
+KPX W zacute -53
+KPX W z -53
+KPX W ccaron -66
+KPX W cdotaccent -66
+KPX W ccircumflex -66
+KPX W cacute -66
+KPX W ccedilla -66
+KPX W c -66
+KPX W scaron -70
+KPX W scedilla -70
+KPX W scircumflex -70
+KPX W sacute -70
+KPX W s -70
+KPX W T_h 30
+KPX W oslash.sc -30
+KPX W odieresis.sc -15
+KPX W otilde.sc -15
+KPX W ocircumflex.sc -15
+KPX W oacute.sc -20
+KPX W ograve.sc -15
+KPX W ccedilla.sc -30
+KPX W ae.sc -55
+KPX W aring.sc -35
+KPX W adieresis.sc -35
+KPX W atilde.sc -35
+KPX W acircumflex.sc -35
+KPX W aacute.sc -50
+KPX W agrave.sc -35
+KPX W t.sc 25
+KPX W s.sc -20
+KPX W o.sc -30
+KPX W g.sc -35
+KPX W c.sc -30
+KPX W a.sc -65
+KPX W uni021B.sc 25
+KPX W tcaron.sc 15
+KPX W uni0219.sc -20
+KPX W scircumflex.sc -10
+KPX W scedilla.sc -20
+KPX W sacute.sc -15
+KPX W omacron.sc -15
+KPX W ohungarumlaut.sc -15
+KPX W obreve.sc -15
+KPX W gdotaccent.sc -15
+KPX W gcommaaccent.sc -35
+KPX W gcircumflex.sc -15
+KPX W gbreve.sc -15
+KPX W cdotaccent.sc -15
+KPX W ccircumflex.sc -15
+KPX W ccaron.sc -15
+KPX W cacute.sc -20
+KPX W aeacute.sc -55
+KPX W aogonek.sc -65
+KPX W amacron.sc -35
+KPX W abreve.sc -35
+KPX W scaron.sc -10
+KPX W oogonek.sc -30
+KPX W ohorntilde.sc -15
+KPX W ohornhookabove.sc -15
+KPX W ohorngrave.sc -15
+KPX W ohorndotbelow.sc -15
+KPX W ohornacute.sc -15
+KPX W ohookabove.sc -15
+KPX W oe.sc -25
+KPX W ocircumflexdotbelow.sc -15
+KPX W gcaron.sc -15
+KPX W gacute.sc -25
+KPX W ahookabove.sc -35
+KPX W acircumflexdotbelow.sc -35
+KPX W abrevedotbelow.sc -35
+KPX W guilsinglleft -85
+KPX W ytilde -10
+KPX W yhookabove -10
+KPX W ygrave -10
+KPX W uhorndotbelow -20
+KPX W uhorntilde -20
+KPX W uhornhookabove -20
+KPX W uhorngrave -20
+KPX W uhornacute -20
+KPX W uhookabove -20
+KPX W ohorndotbelow -25
+KPX W ohorntilde -25
+KPX W ohornhookabove -25
+KPX W ohorngrave -25
+KPX W ohornacute -25
+KPX W ocircumflexdotbelow -25
+KPX W ohookabove -25
+KPX W ecircumflexdotbelow -30
+KPX W etilde -30
+KPX W ehookabove -30
+KPX W abrevedotbelow -30
+KPX W acircumflexdotbelow -30
+KPX W ahookabove -30
+KPX W rdotaccent -20
+KPX W uni021A 30
+KPX W uni0218 -25
+KPX W aeacute -60
+KPX W AEacute -80
+KPX W gacute -40
+KPX W Gacute -40
+KPX W oogonek -50
+KPX W Oogonek -35
+KPX W gcaron -30
+KPX W Gcaron -40
+KPX W ycircumflex -10
+KPX W uogonek -35
+KPX W uhungarumlaut -20
+KPX W uring -20
+KPX W ubreve -20
+KPX W umacron -20
+KPX W utilde -20
+KPX W Tcaron 30
+KPX W Scaron -25
+KPX W Scedilla -25
+KPX W Scircumflex -25
+KPX W Sacute -25
+KPX W rcaron -20
+KPX W rcommaaccent -35
+KPX W racute -25
+KPX W oe -50
+KPX W OE -35
+KPX W ohungarumlaut -25
+KPX W Ohungarumlaut -35
+KPX W obreve -25
+KPX W Obreve -35
+KPX W omacron -25
+KPX W Omacron -35
+KPX W gcommaaccent -55
+KPX W Gcommaaccent -40
+KPX W gdotaccent -30
+KPX W Gdotaccent -40
+KPX W gbreve -30
+KPX W Gbreve -40
+KPX W gcircumflex -30
+KPX W Gcircumflex -40
+KPX W ecaron -30
+KPX W eogonek -55
+KPX W edotaccent -30
+KPX W ebreve -30
+KPX W emacron -30
+KPX W Ccaron -35
+KPX W Cdotaccent -35
+KPX W Ccircumflex -35
+KPX W Cacute -35
+KPX W aogonek -60
+KPX W Aogonek -80
+KPX W abreve -30
+KPX W amacron -30
+KPX W Amacron -80
+KPX W ydieresis -10
+KPX W yacute -15
+KPX W udieresis -20
+KPX W ucircumflex -20
+KPX W uacute -25
+KPX W ugrave -20
+KPX W oslash -50
+KPX W odieresis -25
+KPX W otilde -25
+KPX W ocircumflex -25
+KPX W oacute -40
+KPX W ograve -25
+KPX W edieresis -30
+KPX W ecircumflex -30
+KPX W eacute -40
+KPX W egrave -30
+KPX W ae -60
+KPX W aring -30
+KPX W adieresis -30
+KPX W atilde -30
+KPX W acircumflex -30
+KPX W aacute -45
+KPX W agrave -30
+KPX W Oslash -35
+KPX W Odieresis -35
+KPX W Ccedilla -35
+KPX W AE -80
+KPX W Aring -80
+KPX W Adieresis -80
+KPX W guillemotleft -60
+KPX W y -20
+KPX W u -35
+KPX W r -35
+KPX W o -50
+KPX W g -55
+KPX W e -55
+KPX W a -60
+KPX W T 30
+KPX W S -25
+KPX W O -35
+KPX W G -40
+KPX W C -35
+KPX W A -80
+KPX W semicolon -55
+KPX W colon -40
+KPX W period -50
+KPX W hyphen -20
+KPX W comma -60
+KPX X oslash.sc -30
+KPX X odieresis.sc -30
+KPX X otilde.sc -30
+KPX X ocircumflex.sc -30
+KPX X oacute.sc -30
+KPX X ograve.sc -30
+KPX X ccedilla.sc -35
+KPX X q.sc -30
+KPX X o.sc -30
+KPX X c.sc -35
+KPX X omacron.sc -30
+KPX X ohungarumlaut.sc -30
+KPX X obreve.sc -30
+KPX X cdotaccent.sc -35
+KPX X ccircumflex.sc -35
+KPX X ccaron.sc -35
+KPX X cacute.sc -35
+KPX X oogonek.sc -30
+KPX X ohorntilde.sc -30
+KPX X ohornhookabove.sc -30
+KPX X ohorngrave.sc -30
+KPX X ohorndotbelow.sc -30
+KPX X ohornacute.sc -30
+KPX X ohookabove.sc -30
+KPX X odotbelow.sc -30
+KPX X ocircumflexhookabove.sc -30
+KPX X ocircumflexgrave.sc -30
+KPX X ocircumflexdotbelow.sc -30
+KPX X ocircumflexacute.sc -30
+KPX X uhorndotbelow -25
+KPX X uhornhookabove -25
+KPX X uhorngrave -25
+KPX X uhornacute -25
+KPX X uhookabove -25
+KPX X udotbelow -25
+KPX X ohorndotbelow -15
+KPX X Ohorndotbelow -35
+KPX X ohorntilde -15
+KPX X Ohorntilde -35
+KPX X ohornhookabove -15
+KPX X Ohornhookabove -35
+KPX X ohorngrave -15
+KPX X Ohorngrave -35
+KPX X ohornacute -15
+KPX X Ohornacute -35
+KPX X ocircumflexdotbelow -15
+KPX X Ocircumflexdotbelow -35
+KPX X ocircumflexhookabove -15
+KPX X Ocircumflexhookabove -35
+KPX X ocircumflexgrave -15
+KPX X Ocircumflexgrave -35
+KPX X ocircumflexacute -15
+KPX X Ocircumflexacute -35
+KPX X ohookabove -15
+KPX X Ohookabove -35
+KPX X odotbelow -15
+KPX X Odotbelow -35
+KPX X ecircumflexdotbelow -15
+KPX X ecircumflexhookabove -15
+KPX X ecircumflexgrave -15
+KPX X ecircumflexacute -15
+KPX X etilde -15
+KPX X ehookabove -15
+KPX X edotbelow -15
+KPX X oogonek -15
+KPX X Oogonek -35
+KPX X ycircumflex -60
+KPX X uogonek -25
+KPX X uhungarumlaut -25
+KPX X uring -25
+KPX X ubreve -25
+KPX X umacron -25
+KPX X utilde -25
+KPX X ohungarumlaut -15
+KPX X Ohungarumlaut -35
+KPX X obreve -15
+KPX X Obreve -35
+KPX X omacron -15
+KPX X Omacron -35
+KPX X ecaron -15
+KPX X eogonek -15
+KPX X edotaccent -15
+KPX X ebreve -15
+KPX X emacron -15
+KPX X Ccaron -40
+KPX X Cdotaccent -40
+KPX X Ccircumflex -40
+KPX X Cacute -40
+KPX X ydieresis -60
+KPX X udieresis -25
+KPX X ucircumflex -25
+KPX X uacute -25
+KPX X ugrave -25
+KPX X oslash -15
+KPX X odieresis -15
+KPX X otilde -15
+KPX X ocircumflex -15
+KPX X oacute -15
+KPX X ograve -15
+KPX X edieresis -15
+KPX X ecircumflex -15
+KPX X eacute -15
+KPX X egrave -15
+KPX X Oslash -35
+KPX X Odieresis -35
+KPX X Otilde -35
+KPX X Ocircumflex -35
+KPX X Oacute -35
+KPX X Ograve -35
+KPX X Ccedilla -40
+KPX X y -60
+KPX X u -25
+KPX X o -15
+KPX X e -15
+KPX X Q -35
+KPX X O -35
+KPX X C -40
+KPX X hyphen -20
+KPX Y zcaron -50
+KPX Y zdotaccent -50
+KPX Y zacute -50
+KPX Y z -50
+KPX Y ccaron -75
+KPX Y cdotaccent -75
+KPX Y ccircumflex -75
+KPX Y cacute -75
+KPX Y ccedilla -75
+KPX Y c -75
+KPX Y scaron -50
+KPX Y scedilla -50
+KPX Y scircumflex -50
+KPX Y sacute -50
+KPX Y s -50
+KPX Y T_h 35
+KPX Y oslash.sc -40
+KPX Y odieresis.sc -20
+KPX Y otilde.sc -20
+KPX Y ocircumflex.sc -20
+KPX Y oacute.sc -30
+KPX Y ograve.sc -20
+KPX Y ccedilla.sc -40
+KPX Y ae.sc -55
+KPX Y aring.sc -15
+KPX Y adieresis.sc -15
+KPX Y atilde.sc -15
+KPX Y acircumflex.sc -15
+KPX Y aacute.sc -25
+KPX Y agrave.sc -15
+KPX Y t.sc 30
+KPX Y s.sc -20
+KPX Y o.sc -40
+KPX Y g.sc -40
+KPX Y c.sc -40
+KPX Y a.sc -35
+KPX Y uni021B.sc 30
+KPX Y tcaron.sc 15
+KPX Y uni0219.sc -20
+KPX Y scircumflex.sc -10
+KPX Y scedilla.sc -20
+KPX Y sacute.sc -15
+KPX Y omacron.sc -20
+KPX Y ohungarumlaut.sc -20
+KPX Y obreve.sc -20
+KPX Y gdotaccent.sc -20
+KPX Y gcommaaccent.sc -40
+KPX Y gcircumflex.sc -20
+KPX Y gbreve.sc -20
+KPX Y cdotaccent.sc -20
+KPX Y ccircumflex.sc -20
+KPX Y ccaron.sc -20
+KPX Y cacute.sc -30
+KPX Y aeacute.sc -55
+KPX Y aogonek.sc -35
+KPX Y amacron.sc -15
+KPX Y abreve.sc -15
+KPX Y scaron.sc -10
+KPX Y oogonek.sc -40
+KPX Y ohorntilde.sc -20
+KPX Y ohornhookabove.sc -20
+KPX Y ohorngrave.sc -20
+KPX Y ohorndotbelow.sc -20
+KPX Y ohornacute.sc -20
+KPX Y ohookabove.sc -20
+KPX Y oe.sc -25
+KPX Y ocircumflexdotbelow.sc -20
+KPX Y gcaron.sc -20
+KPX Y gacute.sc -30
+KPX Y ahookabove.sc -15
+KPX Y acircumflexdotbelow.sc -15
+KPX Y abrevedotbelow.sc -15
+KPX Y guilsinglleft -105
+KPX Y uhorndotbelow -25
+KPX Y uhorntilde -25
+KPX Y uhornhookabove -25
+KPX Y uhorngrave -25
+KPX Y uhornacute -25
+KPX Y uhookabove -25
+KPX Y ohorndotbelow -35
+KPX Y ohorntilde -35
+KPX Y ohornhookabove -35
+KPX Y ohorngrave -35
+KPX Y ohornacute -35
+KPX Y ocircumflexdotbelow -35
+KPX Y ohookabove -35
+KPX Y ecircumflexdotbelow -35
+KPX Y etilde -35
+KPX Y ehookabove -35
+KPX Y abrevedotbelow -30
+KPX Y acircumflexdotbelow -30
+KPX Y ahookabove -30
+KPX Y uni021A 35
+KPX Y uni0218 -25
+KPX Y aeacute -60
+KPX Y AEacute -80
+KPX Y gacute -50
+KPX Y Gacute -45
+KPX Y oogonek -70
+KPX Y Oogonek -45
+KPX Y gcaron -35
+KPX Y Gcaron -45
+KPX Y uogonek -50
+KPX Y uhungarumlaut -25
+KPX Y uring -25
+KPX Y ubreve -25
+KPX Y umacron -25
+KPX Y utilde -25
+KPX Y Tcaron 35
+KPX Y Scaron -25
+KPX Y Scedilla -25
+KPX Y Scircumflex -25
+KPX Y Sacute -25
+KPX Y oe -50
+KPX Y OE -35
+KPX Y ohungarumlaut -35
+KPX Y Ohungarumlaut -45
+KPX Y obreve -35
+KPX Y Obreve -45
+KPX Y omacron -35
+KPX Y Omacron -45
+KPX Y gcommaaccent -65
+KPX Y Gcommaaccent -45
+KPX Y gdotaccent -35
+KPX Y Gdotaccent -45
+KPX Y gbreve -35
+KPX Y Gbreve -45
+KPX Y gcircumflex -35
+KPX Y Gcircumflex -45
+KPX Y ecaron -35
+KPX Y eogonek -70
+KPX Y edotaccent -35
+KPX Y ebreve -35
+KPX Y emacron -35
+KPX Y Ccaron -45
+KPX Y Cdotaccent -45
+KPX Y Ccircumflex -45
+KPX Y Cacute -45
+KPX Y aogonek -55
+KPX Y Aogonek -40
+KPX Y abreve -30
+KPX Y amacron -30
+KPX Y Amacron -40
+KPX Y udieresis -25
+KPX Y ucircumflex -25
+KPX Y uacute -40
+KPX Y ugrave -25
+KPX Y oslash -70
+KPX Y odieresis -35
+KPX Y otilde -35
+KPX Y ocircumflex -35
+KPX Y oacute -55
+KPX Y ograve -35
+KPX Y edieresis -35
+KPX Y ecircumflex -35
+KPX Y eacute -55
+KPX Y egrave -35
+KPX Y ae -60
+KPX Y aring -30
+KPX Y adieresis -30
+KPX Y atilde -30
+KPX Y acircumflex -30
+KPX Y aacute -40
+KPX Y agrave -30
+KPX Y Oslash -45
+KPX Y Odieresis -45
+KPX Y Ccedilla -45
+KPX Y AE -80
+KPX Y Aring -40
+KPX Y Adieresis -40
+KPX Y guillemotleft -80
+KPX Y v -35
+KPX Y u -50
+KPX Y p -50
+KPX Y o -70
+KPX Y g -65
+KPX Y e -70
+KPX Y a -55
+KPX Y T 35
+KPX Y S -25
+KPX Y O -45
+KPX Y G -45
+KPX Y C -45
+KPX Y A -40
+KPX Y semicolon -60
+KPX Y colon -55
+KPX Y period -50
+KPX Y hyphen -45
+KPX Y comma -55
+KPX Z ycircumflex -50
+KPX Z ydieresis -50
+KPX Z y -50
+KPX Z v -45
+KPX a jacute -25
+KPX a wdieresis -20
+KPX a wacute -20
+KPX a wgrave -20
+KPX a ycircumflex -20
+KPX a wcircumflex -20
+KPX a jcircumflex -25
+KPX a ydieresis -20
+KPX a y -20
+KPX a w -20
+KPX a v -20
+KPX a j -25
+KPX b wdieresis -20
+KPX b wacute -20
+KPX b wgrave -20
+KPX b ycircumflex -20
+KPX b wcircumflex -20
+KPX b ydieresis -20
+KPX b y -20
+KPX b w -20
+KPX b v -20
+KPX e quoteright 15
+KPX e V -85
+KPX f jacute 10
+KPX f quoteright 20
+KPX f ohorndotbelow -5
+KPX f ohorntilde -5
+KPX f ohornhookabove -5
+KPX f ohorngrave -5
+KPX f ohornacute -5
+KPX f ocircumflexdotbelow -5
+KPX f ohookabove -5
+KPX f ihookabove 10
+KPX f ecircumflexdotbelow -10
+KPX f etilde -10
+KPX f ehookabove -10
+KPX f abrevedotbelow -10
+KPX f acircumflexdotbelow -10
+KPX f ahookabove -10
+KPX f uni021B 15
+KPX f aeacute -15
+KPX f oogonek -10
+KPX f tcaron 10
+KPX f oe -15
+KPX f ohungarumlaut -5
+KPX f obreve -5
+KPX f omacron -5
+KPX f lslash 25
+KPX f lcaron 15
+KPX f lcommaaccent 25
+KPX f lacute 20
+KPX f jcircumflex 10
+KPX f iogonek 15
+KPX f ibreve 10
+KPX f imacron 10
+KPX f itilde 10
+KPX f ecaron -10
+KPX f eogonek -15
+KPX f edotaccent -10
+KPX f ebreve -10
+KPX f emacron -10
+KPX f aogonek -15
+KPX f abreve -10
+KPX f amacron -10
+KPX f oslash -10
+KPX f odieresis -5
+KPX f otilde -5
+KPX f ocircumflex -5
+KPX f oacute -10
+KPX f ograve -5
+KPX f idieresis 10
+KPX f icircumflex 10
+KPX f iacute 10
+KPX f igrave 10
+KPX f edieresis -10
+KPX f ecircumflex -10
+KPX f eacute -10
+KPX f egrave -10
+KPX f ae -15
+KPX f aring -10
+KPX f adieresis -10
+KPX f atilde -10
+KPX f acircumflex -10
+KPX f aacute -10
+KPX f agrave -10
+KPX f t 15
+KPX f o -10
+KPX f l 25
+KPX f j 15
+KPX f i 15
+KPX f e -15
+KPX f a -15
+KPX g rdotaccent 15
+KPX g rcaron 15
+KPX g rcommaaccent 15
+KPX g racute 15
+KPX g ecaron -15
+KPX g eogonek -15
+KPX g edotaccent -15
+KPX g ebreve -15
+KPX g emacron -15
+KPX g edieresis -15
+KPX g egrave -15
+KPX g r 15
+KPX g e -15
+KPX h ycircumflex -25
+KPX h ydieresis -25
+KPX h y -25
+KPX i T_h -15
+KPX i jacute -30
+KPX i uni021A -15
+KPX i Tcaron -15
+KPX i jcircumflex -30
+KPX i j -30
+KPX i T -15
+KPX k ecircumflexdotbelow -15
+KPX k ecircumflexhookabove -15
+KPX k ecircumflexgrave -15
+KPX k ecircumflexacute -15
+KPX k etilde -15
+KPX k ehookabove -15
+KPX k edotbelow -15
+KPX k uni0219 15
+KPX k oogonek -15
+KPX k scaron 15
+KPX k scedilla 15
+KPX k scircumflex 15
+KPX k sacute 15
+KPX k ohungarumlaut -15
+KPX k obreve -15
+KPX k omacron -15
+KPX k ecaron -15
+KPX k eogonek -15
+KPX k edotaccent -15
+KPX k ebreve -15
+KPX k emacron -15
+KPX k oslash -15
+KPX k odieresis -15
+KPX k edieresis -15
+KPX k ecircumflex -15
+KPX k eacute -15
+KPX k egrave -15
+KPX k s 15
+KPX k o -15
+KPX k e -15
+KPX k W -30
+KPX k V -45
+KPX k period 10
+KPX k hyphen -35
+KPX l ycircumflex -20
+KPX l ydieresis -20
+KPX l yacute -20
+KPX l y -20
+KPX l v -20
+KPX m ytilde -25
+KPX m wdieresis -25
+KPX m wacute -25
+KPX m wgrave -25
+KPX m ycircumflex -25
+KPX m wcircumflex -25
+KPX m ydieresis -25
+KPX m y -25
+KPX m w -25
+KPX m v -25
+KPX m p -25
+KPX n T_h -60
+KPX n wdieresis -25
+KPX n wacute -25
+KPX n wgrave -25
+KPX n uni021A -60
+KPX n ycircumflex -25
+KPX n wcircumflex -25
+KPX n Tcaron -60
+KPX n ydieresis -25
+KPX n y -25
+KPX n w -25
+KPX n v -25
+KPX n p -20
+KPX n T -60
+KPX o T_h -90
+KPX o wdieresis -20
+KPX o wacute -20
+KPX o wgrave -20
+KPX o uni021A -90
+KPX o ycircumflex -20
+KPX o wcircumflex -20
+KPX o Tcaron -90
+KPX o ydieresis -20
+KPX o y -20
+KPX o x -15
+KPX o w -20
+KPX o v -15
+KPX o T -90
+KPX p ycircumflex -15
+KPX p ydieresis -15
+KPX p y -15
+KPX q uhookabove -15
+KPX q udotbelow -15
+KPX q uogonek -15
+KPX q uhungarumlaut -15
+KPX q uring -15
+KPX q ubreve -15
+KPX q umacron -15
+KPX q utilde -15
+KPX q ccaron -20
+KPX q cdotaccent -20
+KPX q ccircumflex -20
+KPX q cacute -20
+KPX q udieresis -15
+KPX q ucircumflex -15
+KPX q uacute -15
+KPX q ugrave -15
+KPX q ccedilla -20
+KPX q u -15
+KPX q c -20
+KPX r ffl 20
+KPX r ffi 20
+KPX r fl 20
+KPX r fi 20
+KPX r ff 20
+KPX r jacute 20
+KPX r f_k 20
+KPX r quoteright 45
+KPX r uhorndotbelow 25
+KPX r uhorntilde 25
+KPX r uhornhookabove 25
+KPX r uhorngrave 25
+KPX r uhornacute 25
+KPX r uhookabove 25
+KPX r udotbelow 25
+KPX r idotbelow 20
+KPX r ihookabove 20
+KPX r wdieresis 30
+KPX r wacute 30
+KPX r wgrave 30
+KPX r rdotaccent 25
+KPX r uni021B 25
+KPX r uni0219 15
+KPX r gacute 10
+KPX r gcaron 10
+KPX r ycircumflex 35
+KPX r wcircumflex 30
+KPX r uogonek 25
+KPX r uhungarumlaut 25
+KPX r uring 25
+KPX r ubreve 25
+KPX r umacron 25
+KPX r utilde 25
+KPX r tcaron 25
+KPX r scaron 15
+KPX r scedilla 15
+KPX r scircumflex 15
+KPX r sacute 15
+KPX r rcaron 25
+KPX r rcommaaccent 25
+KPX r racute 25
+KPX r ncaron 25
+KPX r ncommaaccent 25
+KPX r nacute 25
+KPX r lslash -10
+KPX r lcaron -10
+KPX r lcommaaccent -10
+KPX r lacute -10
+KPX r jcircumflex 20
+KPX r iogonek 20
+KPX r ibreve 20
+KPX r imacron 20
+KPX r itilde 20
+KPX r gcommaaccent 10
+KPX r gdotaccent 10
+KPX r gbreve 10
+KPX r gcircumflex 10
+KPX r ydieresis 35
+KPX r udieresis 25
+KPX r ucircumflex 25
+KPX r uacute 25
+KPX r ugrave 25
+KPX r ntilde 25
+KPX r idieresis 20
+KPX r icircumflex 20
+KPX r iacute 20
+KPX r igrave 20
+KPX r y 35
+KPX r x 30
+KPX r w 30
+KPX r v 35
+KPX r u 25
+KPX r t 25
+KPX r s 15
+KPX r r 25
+KPX r p 25
+KPX r n 25
+KPX r m 25
+KPX r l -10
+KPX r j 20
+KPX r i 20
+KPX r g 10
+KPX r f 20
+KPX r colon 15
+KPX r period -20
+KPX r hyphen 20
+KPX r comma -25
+KPX t quoteright 20
+KPX t abrevedotbelow 10
+KPX t abrevehookabove 10
+KPX t abrevegrave 10
+KPX t abreveacute 10
+KPX t acircumflexdotbelow 10
+KPX t acircumflexhookabove 10
+KPX t acircumflexgrave 10
+KPX t acircumflexacute 10
+KPX t ahookabove 10
+KPX t adotbelow 10
+KPX t hcircumflex 20
+KPX t aogonek 10
+KPX t abreve 10
+KPX t amacron 10
+KPX t aring 10
+KPX t adieresis 10
+KPX t atilde 10
+KPX t acircumflex 10
+KPX t aacute 10
+KPX t agrave 10
+KPX t h 20
+KPX t a 10
+KPX t colon 15
+KPX v ohorndotbelow -20
+KPX v ohorntilde -20
+KPX v ohornhookabove -20
+KPX v ohorngrave -20
+KPX v ohornacute -20
+KPX v ocircumflexdotbelow -20
+KPX v ocircumflextilde -20
+KPX v ocircumflexhookabove -20
+KPX v ocircumflexgrave -20
+KPX v ocircumflexacute -20
+KPX v ohookabove -20
+KPX v odotbelow -20
+KPX v ecircumflexdotbelow -25
+KPX v ecircumflexhookabove -25
+KPX v ecircumflexgrave -25
+KPX v ecircumflexacute -25
+KPX v etilde -25
+KPX v ehookabove -25
+KPX v edotbelow -25
+KPX v abrevedotbelow -20
+KPX v abrevehookabove -20
+KPX v abrevegrave -20
+KPX v abreveacute -20
+KPX v acircumflexdotbelow -20
+KPX v acircumflextilde -20
+KPX v acircumflexhookabove -20
+KPX v acircumflexgrave -20
+KPX v acircumflexacute -20
+KPX v ahookabove -20
+KPX v adotbelow -20
+KPX v aeacute -20
+KPX v oogonek -20
+KPX v oe -25
+KPX v ohungarumlaut -20
+KPX v obreve -20
+KPX v omacron -20
+KPX v lslash -15
+KPX v lcaron -15
+KPX v lcommaaccent -15
+KPX v lacute -15
+KPX v ecaron -25
+KPX v eogonek -25
+KPX v edotaccent -25
+KPX v ebreve -25
+KPX v emacron -25
+KPX v ccaron -40
+KPX v cdotaccent -40
+KPX v ccircumflex -40
+KPX v cacute -40
+KPX v aogonek -20
+KPX v abreve -20
+KPX v amacron -20
+KPX v oslash -20
+KPX v odieresis -20
+KPX v otilde -20
+KPX v ocircumflex -20
+KPX v oacute -20
+KPX v ograve -20
+KPX v edieresis -25
+KPX v ecircumflex -25
+KPX v eacute -25
+KPX v egrave -25
+KPX v ccedilla -40
+KPX v ae -20
+KPX v aring -20
+KPX v adieresis -20
+KPX v atilde -20
+KPX v acircumflex -20
+KPX v aacute -20
+KPX v agrave -20
+KPX v o -20
+KPX v l -15
+KPX v e -25
+KPX v c -40
+KPX v a -20
+KPX v period -60
+KPX v hyphen -15
+KPX v comma -70
+KPX w aeacute -20
+KPX w gacute -10
+KPX w oogonek -25
+KPX w gcaron -10
+KPX w oe -25
+KPX w ohungarumlaut -25
+KPX w obreve -25
+KPX w omacron -25
+KPX w lslash -20
+KPX w lcaron -20
+KPX w lcommaaccent -20
+KPX w lacute -20
+KPX w gcommaaccent -10
+KPX w gdotaccent -10
+KPX w gbreve -10
+KPX w gcircumflex -10
+KPX w ecaron -30
+KPX w eogonek -30
+KPX w edotaccent -30
+KPX w ebreve -30
+KPX w emacron -30
+KPX w ccaron -35
+KPX w cdotaccent -35
+KPX w ccircumflex -35
+KPX w cacute -35
+KPX w aogonek -20
+KPX w amacron -20
+KPX w oslash -25
+KPX w odieresis -25
+KPX w edieresis -30
+KPX w ccedilla -35
+KPX w ae -20
+KPX w aring -20
+KPX w adieresis -20
+KPX w o -25
+KPX w l -20
+KPX w g -10
+KPX w e -30
+KPX w c -35
+KPX w a -20
+KPX w period -45
+KPX w comma -55
+KPX x ohorndotbelow -15
+KPX x ohorntilde -15
+KPX x ohornhookabove -15
+KPX x ohorngrave -15
+KPX x ohornacute -15
+KPX x ocircumflexdotbelow -15
+KPX x ocircumflexhookabove -15
+KPX x ocircumflexgrave -15
+KPX x ocircumflexacute -15
+KPX x ohookabove -15
+KPX x odotbelow -15
+KPX x ecircumflexdotbelow -15
+KPX x ecircumflexhookabove -15
+KPX x ecircumflexgrave -15
+KPX x ecircumflexacute -15
+KPX x etilde -15
+KPX x ehookabove -15
+KPX x edotbelow -15
+KPX x oogonek -15
+KPX x ohungarumlaut -15
+KPX x obreve -15
+KPX x omacron -15
+KPX x ecaron -15
+KPX x eogonek -15
+KPX x edotaccent -15
+KPX x ebreve -15
+KPX x emacron -15
+KPX x ccaron -15
+KPX x cdotaccent -15
+KPX x ccircumflex -15
+KPX x cacute -15
+KPX x oslash -15
+KPX x odieresis -15
+KPX x otilde -15
+KPX x ocircumflex -15
+KPX x oacute -15
+KPX x ograve -15
+KPX x edieresis -15
+KPX x ecircumflex -15
+KPX x eacute -15
+KPX x egrave -15
+KPX x ccedilla -15
+KPX x q -20
+KPX x o -15
+KPX x e -15
+KPX x c -15
+KPX y ecircumflexdotbelow -35
+KPX y ecircumflextilde -35
+KPX y ecircumflexhookabove -35
+KPX y ecircumflexgrave -35
+KPX y ecircumflexacute -35
+KPX y aeacute -20
+KPX y gacute -15
+KPX y oogonek -30
+KPX y gcaron -15
+KPX y oe -25
+KPX y ohungarumlaut -30
+KPX y obreve -30
+KPX y omacron -30
+KPX y lslash -15
+KPX y lcaron -15
+KPX y lcommaaccent -15
+KPX y lacute -15
+KPX y gcommaaccent -15
+KPX y gdotaccent -15
+KPX y gbreve -15
+KPX y gcircumflex -15
+KPX y ecaron -35
+KPX y eogonek -35
+KPX y edotaccent -35
+KPX y ebreve -35
+KPX y emacron -35
+KPX y ccaron -35
+KPX y cdotaccent -35
+KPX y ccircumflex -35
+KPX y cacute -35
+KPX y aogonek -25
+KPX y amacron -25
+KPX y oslash -30
+KPX y odieresis -30
+KPX y edieresis -35
+KPX y ecircumflex -35
+KPX y ccedilla -35
+KPX y ae -20
+KPX y aring -25
+KPX y adieresis -25
+KPX y o -30
+KPX y l -15
+KPX y g -15
+KPX y e -35
+KPX y c -35
+KPX y a -25
+KPX y period -60
+KPX y hyphen -10
+KPX y comma -65
+KPX guillemotright T_h -100
+KPX guillemotright Wdieresis -55
+KPX guillemotright Wacute -55
+KPX guillemotright Wgrave -55
+KPX guillemotright uni021A -100
+KPX guillemotright AEacute -65
+KPX guillemotright Ydieresis -105
+KPX guillemotright Ycircumflex -105
+KPX guillemotright Wcircumflex -55
+KPX guillemotright Tcaron -100
+KPX guillemotright Aogonek -50
+KPX guillemotright Amacron -50
+KPX guillemotright AE -65
+KPX guillemotright Aring -50
+KPX guillemotright Adieresis -50
+KPX guillemotright Y -105
+KPX guillemotright W -55
+KPX guillemotright V -100
+KPX guillemotright T -100
+KPX guillemotright A -50
+KPX Agrave y.sc -55
+KPX Agrave u.sc -40
+KPX Agrave o.sc -40
+KPX Agrave y -70
+KPX Agrave u -25
+KPX Agrave o -15
+KPX Agrave Y -65
+KPX Agrave U -45
+KPX Agrave O -45
+KPX Aacute T_h -55
+KPX Aacute y.sc -55
+KPX Aacute u.sc -40
+KPX Aacute t.sc -45
+KPX Aacute o.sc -40
+KPX Aacute c.sc -40
+KPX Aacute y -70
+KPX Aacute u -25
+KPX Aacute t -15
+KPX Aacute o -15
+KPX Aacute c -15
+KPX Aacute Y -65
+KPX Aacute U -45
+KPX Aacute T -55
+KPX Aacute O -45
+KPX Aacute C -50
+KPX Acircumflex y.sc -55
+KPX Acircumflex u.sc -40
+KPX Acircumflex y -70
+KPX Acircumflex u -25
+KPX Acircumflex Y -65
+KPX Acircumflex U -45
+KPX Atilde y.sc -55
+KPX Atilde o.sc -40
+KPX Atilde y -70
+KPX Atilde o -15
+KPX Atilde Y -65
+KPX Atilde O -45
+KPX Adieresis T_h -55
+KPX Adieresis ydieresis.sc -55
+KPX Adieresis udieresis.sc -40
+KPX Adieresis ucircumflex.sc -40
+KPX Adieresis oslash.sc -40
+KPX Adieresis odieresis.sc -40
+KPX Adieresis ccedilla.sc -40
+KPX Adieresis y.sc -55
+KPX Adieresis w.sc -60
+KPX Adieresis v.sc -105
+KPX Adieresis u.sc -40
+KPX Adieresis t.sc -45
+KPX Adieresis q.sc -35
+KPX Adieresis o.sc -40
+KPX Adieresis g.sc -45
+KPX Adieresis c.sc -40
+KPX Adieresis ycircumflex.sc -55
+KPX Adieresis wgrave.sc -60
+KPX Adieresis wdieresis.sc -60
+KPX Adieresis wcircumflex.sc -60
+KPX Adieresis wacute.sc -60
+KPX Adieresis uring.sc -40
+KPX Adieresis uogonek.sc -40
+KPX Adieresis umacron.sc -40
+KPX Adieresis uhungarumlaut.sc -40
+KPX Adieresis ubreve.sc -40
+KPX Adieresis uni021B.sc -45
+KPX Adieresis tcaron.sc -45
+KPX Adieresis omacron.sc -40
+KPX Adieresis ohungarumlaut.sc -40
+KPX Adieresis obreve.sc -40
+KPX Adieresis gdotaccent.sc -45
+KPX Adieresis gcommaaccent.sc -45
+KPX Adieresis gcircumflex.sc -45
+KPX Adieresis gbreve.sc -45
+KPX Adieresis cdotaccent.sc -40
+KPX Adieresis ccircumflex.sc -40
+KPX Adieresis ccaron.sc -40
+KPX Adieresis cacute.sc -40
+KPX Adieresis oogonek.sc -40
+KPX Adieresis gcaron.sc -45
+KPX Adieresis gacute.sc -45
+KPX Adieresis guilsinglleft -70
+KPX Adieresis quotedblright -85
+KPX Adieresis quoteright -80
+KPX Adieresis wdieresis -60
+KPX Adieresis Wdieresis -70
+KPX Adieresis wacute -60
+KPX Adieresis Wacute -70
+KPX Adieresis wgrave -60
+KPX Adieresis Wgrave -70
+KPX Adieresis uni021B -15
+KPX Adieresis uni021A -55
+KPX Adieresis Gacute -55
+KPX Adieresis oogonek -15
+KPX Adieresis Oogonek -45
+KPX Adieresis Gcaron -55
+KPX Adieresis Ydieresis -65
+KPX Adieresis ycircumflex -70
+KPX Adieresis Ycircumflex -65
+KPX Adieresis wcircumflex -60
+KPX Adieresis Wcircumflex -70
+KPX Adieresis uogonek -25
+KPX Adieresis Uogonek -45
+KPX Adieresis uhungarumlaut -25
+KPX Adieresis Uhungarumlaut -45
+KPX Adieresis uring -25
+KPX Adieresis Uring -45
+KPX Adieresis ubreve -25
+KPX Adieresis Ubreve -45
+KPX Adieresis umacron -25
+KPX Adieresis Umacron -45
+KPX Adieresis tcaron -15
+KPX Adieresis Tcaron -55
+KPX Adieresis ohungarumlaut -15
+KPX Adieresis Ohungarumlaut -45
+KPX Adieresis obreve -15
+KPX Adieresis Obreve -45
+KPX Adieresis omacron -15
+KPX Adieresis Omacron -45
+KPX Adieresis Gcommaaccent -55
+KPX Adieresis Gdotaccent -55
+KPX Adieresis Gbreve -55
+KPX Adieresis Gcircumflex -55
+KPX Adieresis ecaron -15
+KPX Adieresis eogonek -15
+KPX Adieresis edotaccent -15
+KPX Adieresis ebreve -15
+KPX Adieresis emacron -15
+KPX Adieresis dcaron -15
+KPX Adieresis ccaron -15
+KPX Adieresis Ccaron -50
+KPX Adieresis cdotaccent -15
+KPX Adieresis Cdotaccent -50
+KPX Adieresis ccircumflex -15
+KPX Adieresis Ccircumflex -50
+KPX Adieresis cacute -15
+KPX Adieresis Cacute -50
+KPX Adieresis ydieresis -70
+KPX Adieresis udieresis -25
+KPX Adieresis ucircumflex -25
+KPX Adieresis oslash -15
+KPX Adieresis odieresis -15
+KPX Adieresis edieresis -15
+KPX Adieresis ccedilla -15
+KPX Adieresis Udieresis -45
+KPX Adieresis Ucircumflex -45
+KPX Adieresis Oslash -45
+KPX Adieresis Odieresis -45
+KPX Adieresis Ccedilla -50
+KPX Adieresis guillemotleft -50
+KPX Adieresis y -70
+KPX Adieresis w -60
+KPX Adieresis v -70
+KPX Adieresis u -25
+KPX Adieresis t -15
+KPX Adieresis q -20
+KPX Adieresis o -15
+KPX Adieresis e -15
+KPX Adieresis d -15
+KPX Adieresis c -15
+KPX Adieresis Y -65
+KPX Adieresis W -70
+KPX Adieresis V -125
+KPX Adieresis U -45
+KPX Adieresis T -55
+KPX Adieresis Q -40
+KPX Adieresis O -45
+KPX Adieresis G -55
+KPX Adieresis C -50
+KPX Adieresis period 10
+KPX Adieresis hyphen -10
+KPX Aring T_h -55
+KPX Aring ydieresis.sc -55
+KPX Aring udieresis.sc -40
+KPX Aring ucircumflex.sc -40
+KPX Aring oslash.sc -40
+KPX Aring odieresis.sc -40
+KPX Aring ccedilla.sc -40
+KPX Aring y.sc -55
+KPX Aring w.sc -60
+KPX Aring v.sc -105
+KPX Aring u.sc -40
+KPX Aring t.sc -45
+KPX Aring q.sc -35
+KPX Aring o.sc -40
+KPX Aring g.sc -45
+KPX Aring c.sc -40
+KPX Aring ycircumflex.sc -55
+KPX Aring wgrave.sc -60
+KPX Aring wdieresis.sc -60
+KPX Aring wcircumflex.sc -60
+KPX Aring wacute.sc -60
+KPX Aring uring.sc -40
+KPX Aring uogonek.sc -40
+KPX Aring umacron.sc -40
+KPX Aring uhungarumlaut.sc -40
+KPX Aring ubreve.sc -40
+KPX Aring uni021B.sc -45
+KPX Aring tcaron.sc -45
+KPX Aring omacron.sc -40
+KPX Aring ohungarumlaut.sc -40
+KPX Aring obreve.sc -40
+KPX Aring gdotaccent.sc -45
+KPX Aring gcommaaccent.sc -45
+KPX Aring gcircumflex.sc -45
+KPX Aring gbreve.sc -45
+KPX Aring cdotaccent.sc -40
+KPX Aring ccircumflex.sc -40
+KPX Aring ccaron.sc -40
+KPX Aring cacute.sc -40
+KPX Aring oogonek.sc -40
+KPX Aring gcaron.sc -45
+KPX Aring gacute.sc -45
+KPX Aring guilsinglleft -70
+KPX Aring quotedblright -85
+KPX Aring quoteright -80
+KPX Aring wdieresis -60
+KPX Aring Wdieresis -70
+KPX Aring wacute -60
+KPX Aring Wacute -70
+KPX Aring wgrave -60
+KPX Aring Wgrave -70
+KPX Aring uni021B -15
+KPX Aring uni021A -55
+KPX Aring Gacute -55
+KPX Aring oogonek -15
+KPX Aring Oogonek -45
+KPX Aring Gcaron -55
+KPX Aring Ydieresis -65
+KPX Aring ycircumflex -70
+KPX Aring Ycircumflex -65
+KPX Aring wcircumflex -60
+KPX Aring Wcircumflex -70
+KPX Aring uogonek -25
+KPX Aring Uogonek -45
+KPX Aring uhungarumlaut -25
+KPX Aring Uhungarumlaut -45
+KPX Aring uring -25
+KPX Aring Uring -45
+KPX Aring ubreve -25
+KPX Aring Ubreve -45
+KPX Aring umacron -25
+KPX Aring Umacron -45
+KPX Aring tcaron -15
+KPX Aring Tcaron -55
+KPX Aring ohungarumlaut -15
+KPX Aring Ohungarumlaut -45
+KPX Aring obreve -15
+KPX Aring Obreve -45
+KPX Aring omacron -15
+KPX Aring Omacron -45
+KPX Aring Gcommaaccent -55
+KPX Aring Gdotaccent -55
+KPX Aring Gbreve -55
+KPX Aring Gcircumflex -55
+KPX Aring ecaron -15
+KPX Aring eogonek -15
+KPX Aring edotaccent -15
+KPX Aring ebreve -15
+KPX Aring emacron -15
+KPX Aring dcaron -15
+KPX Aring ccaron -15
+KPX Aring Ccaron -50
+KPX Aring cdotaccent -15
+KPX Aring Cdotaccent -50
+KPX Aring ccircumflex -15
+KPX Aring Ccircumflex -50
+KPX Aring cacute -15
+KPX Aring Cacute -50
+KPX Aring ydieresis -70
+KPX Aring udieresis -25
+KPX Aring ucircumflex -25
+KPX Aring oslash -15
+KPX Aring odieresis -15
+KPX Aring edieresis -15
+KPX Aring ccedilla -15
+KPX Aring Udieresis -45
+KPX Aring Ucircumflex -45
+KPX Aring Oslash -45
+KPX Aring Odieresis -45
+KPX Aring Ccedilla -50
+KPX Aring guillemotleft -50
+KPX Aring y -70
+KPX Aring w -60
+KPX Aring v -70
+KPX Aring u -25
+KPX Aring t -15
+KPX Aring q -20
+KPX Aring o -15
+KPX Aring e -15
+KPX Aring d -15
+KPX Aring c -15
+KPX Aring Y -65
+KPX Aring W -70
+KPX Aring V -125
+KPX Aring U -45
+KPX Aring T -55
+KPX Aring Q -40
+KPX Aring O -45
+KPX Aring G -55
+KPX Aring C -50
+KPX Aring period 10
+KPX Aring hyphen -10
+KPX Ccedilla oslash.sc -15
+KPX Ccedilla odieresis.sc -15
+KPX Ccedilla aring.sc 10
+KPX Ccedilla adieresis.sc 10
+KPX Ccedilla o.sc -15
+KPX Ccedilla k.sc 10
+KPX Ccedilla h.sc 15
+KPX Ccedilla a.sc 10
+KPX Ccedilla omacron.sc -15
+KPX Ccedilla ohungarumlaut.sc -15
+KPX Ccedilla obreve.sc -15
+KPX Ccedilla kcommaaccent.sc 10
+KPX Ccedilla hcircumflex.sc 15
+KPX Ccedilla aogonek.sc 10
+KPX Ccedilla amacron.sc 10
+KPX Ccedilla oogonek.sc -15
+KPX Ccedilla Oogonek -15
+KPX Ccedilla Ohungarumlaut -15
+KPX Ccedilla Obreve -15
+KPX Ccedilla Omacron -15
+KPX Ccedilla Kcommaaccent 10
+KPX Ccedilla Hcircumflex 15
+KPX Ccedilla Aogonek 10
+KPX Ccedilla Amacron 10
+KPX Ccedilla Oslash -15
+KPX Ccedilla Odieresis -15
+KPX Ccedilla Aring 10
+KPX Ccedilla Adieresis 10
+KPX Ccedilla O -15
+KPX Ccedilla K 10
+KPX Ccedilla H 15
+KPX Ccedilla A 10
+KPX Ntilde oslash.sc -15
+KPX Ntilde odieresis.sc -15
+KPX Ntilde ccedilla.sc -15
+KPX Ntilde ae.sc -15
+KPX Ntilde aring.sc -20
+KPX Ntilde adieresis.sc -20
+KPX Ntilde o.sc -15
+KPX Ntilde g.sc -20
+KPX Ntilde c.sc -15
+KPX Ntilde a.sc -20
+KPX Ntilde omacron.sc -15
+KPX Ntilde ohungarumlaut.sc -15
+KPX Ntilde obreve.sc -15
+KPX Ntilde gdotaccent.sc -20
+KPX Ntilde gcommaaccent.sc -20
+KPX Ntilde gcircumflex.sc -20
+KPX Ntilde gbreve.sc -20
+KPX Ntilde cdotaccent.sc -15
+KPX Ntilde ccircumflex.sc -15
+KPX Ntilde ccaron.sc -15
+KPX Ntilde cacute.sc -15
+KPX Ntilde aeacute.sc -15
+KPX Ntilde aogonek.sc -20
+KPX Ntilde amacron.sc -20
+KPX Ntilde oogonek.sc -15
+KPX Ntilde gcaron.sc -20
+KPX Ntilde gacute.sc -20
+KPX Ntilde aeacute -30
+KPX Ntilde AEacute -20
+KPX Ntilde Gacute -25
+KPX Ntilde oogonek -20
+KPX Ntilde Oogonek -20
+KPX Ntilde Gcaron -25
+KPX Ntilde uogonek -30
+KPX Ntilde uhungarumlaut -30
+KPX Ntilde uring -30
+KPX Ntilde ubreve -30
+KPX Ntilde umacron -30
+KPX Ntilde ohungarumlaut -20
+KPX Ntilde Ohungarumlaut -20
+KPX Ntilde obreve -20
+KPX Ntilde Obreve -20
+KPX Ntilde omacron -20
+KPX Ntilde Omacron -20
+KPX Ntilde Gcommaaccent -25
+KPX Ntilde Gdotaccent -25
+KPX Ntilde Gbreve -25
+KPX Ntilde Gcircumflex -25
+KPX Ntilde ecaron -25
+KPX Ntilde eogonek -25
+KPX Ntilde edotaccent -25
+KPX Ntilde ebreve -25
+KPX Ntilde emacron -25
+KPX Ntilde Ccaron -20
+KPX Ntilde Cdotaccent -20
+KPX Ntilde Ccircumflex -20
+KPX Ntilde Cacute -20
+KPX Ntilde aogonek -30
+KPX Ntilde Aogonek -25
+KPX Ntilde amacron -30
+KPX Ntilde Amacron -25
+KPX Ntilde udieresis -30
+KPX Ntilde ucircumflex -30
+KPX Ntilde oslash -20
+KPX Ntilde odieresis -20
+KPX Ntilde edieresis -25
+KPX Ntilde ae -30
+KPX Ntilde aring -30
+KPX Ntilde adieresis -30
+KPX Ntilde Oslash -20
+KPX Ntilde Odieresis -20
+KPX Ntilde Ccedilla -20
+KPX Ntilde AE -20
+KPX Ntilde Aring -25
+KPX Ntilde Adieresis -25
+KPX Ntilde u -30
+KPX Ntilde o -20
+KPX Ntilde e -25
+KPX Ntilde a -30
+KPX Ntilde O -20
+KPX Ntilde G -25
+KPX Ntilde C -20
+KPX Ntilde A -25
+KPX Ntilde comma -10
+KPX Ograve a.sc -40
+KPX Ograve A -50
+KPX Oacute a.sc -40
+KPX Oacute A -50
+KPX Odieresis ydieresis.sc -30
+KPX Odieresis ae.sc -45
+KPX Odieresis aring.sc -40
+KPX Odieresis adieresis.sc -40
+KPX Odieresis y.sc -30
+KPX Odieresis x.sc -35
+KPX Odieresis w.sc -25
+KPX Odieresis v.sc -40
+KPX Odieresis a.sc -40
+KPX Odieresis ycircumflex.sc -30
+KPX Odieresis wgrave.sc -25
+KPX Odieresis wdieresis.sc -25
+KPX Odieresis wcircumflex.sc -25
+KPX Odieresis wacute.sc -25
+KPX Odieresis aeacute.sc -45
+KPX Odieresis aogonek.sc -40
+KPX Odieresis amacron.sc -40
+KPX Odieresis Wdieresis -30
+KPX Odieresis Wacute -30
+KPX Odieresis Wgrave -30
+KPX Odieresis AEacute -55
+KPX Odieresis Ydieresis -35
+KPX Odieresis Ycircumflex -35
+KPX Odieresis Wcircumflex -30
+KPX Odieresis Aogonek -50
+KPX Odieresis Amacron -50
+KPX Odieresis AE -55
+KPX Odieresis Aring -50
+KPX Odieresis Adieresis -50
+KPX Odieresis Y -35
+KPX Odieresis X -40
+KPX Odieresis W -30
+KPX Odieresis V -50
+KPX Odieresis A -50
+KPX Oslash ydieresis.sc -30
+KPX Oslash ae.sc -45
+KPX Oslash aring.sc -40
+KPX Oslash adieresis.sc -40
+KPX Oslash y.sc -30
+KPX Oslash x.sc -35
+KPX Oslash w.sc -25
+KPX Oslash v.sc -40
+KPX Oslash a.sc -40
+KPX Oslash ycircumflex.sc -30
+KPX Oslash wgrave.sc -25
+KPX Oslash wdieresis.sc -25
+KPX Oslash wcircumflex.sc -25
+KPX Oslash wacute.sc -25
+KPX Oslash aeacute.sc -45
+KPX Oslash aogonek.sc -40
+KPX Oslash amacron.sc -40
+KPX Oslash Wdieresis -30
+KPX Oslash Wacute -30
+KPX Oslash Wgrave -30
+KPX Oslash AEacute -55
+KPX Oslash Ydieresis -35
+KPX Oslash Ycircumflex -35
+KPX Oslash Wcircumflex -30
+KPX Oslash Aogonek -50
+KPX Oslash Amacron -50
+KPX Oslash AE -55
+KPX Oslash Aring -50
+KPX Oslash Adieresis -50
+KPX Oslash Y -35
+KPX Oslash X -40
+KPX Oslash W -30
+KPX Oslash V -50
+KPX Oslash A -50
+KPX Ugrave aring.sc -20
+KPX Ugrave adieresis.sc -20
+KPX Ugrave atilde.sc -20
+KPX Ugrave acircumflex.sc -20
+KPX Ugrave aacute.sc -30
+KPX Ugrave agrave.sc -20
+KPX Ugrave a.sc -40
+KPX Ugrave amacron.sc -20
+KPX Ugrave abreve.sc -20
+KPX Ugrave ahookabove.sc -20
+KPX Ugrave acircumflexdotbelow.sc -20
+KPX Ugrave abrevedotbelow.sc -20
+KPX Ugrave rdotaccent -15
+KPX Ugrave rcaron -15
+KPX Ugrave racute -20
+KPX Ugrave ncaron -10
+KPX Ugrave nacute -15
+KPX Ugrave ntilde -10
+KPX Ugrave n -20
+KPX Ugrave m -20
+KPX Ugrave A -50
+KPX Uacute aring.sc -20
+KPX Uacute adieresis.sc -20
+KPX Uacute atilde.sc -20
+KPX Uacute acircumflex.sc -20
+KPX Uacute aacute.sc -30
+KPX Uacute agrave.sc -20
+KPX Uacute a.sc -40
+KPX Uacute amacron.sc -20
+KPX Uacute abreve.sc -20
+KPX Uacute ahookabove.sc -20
+KPX Uacute acircumflexdotbelow.sc -20
+KPX Uacute abrevedotbelow.sc -20
+KPX Uacute rdotaccent -15
+KPX Uacute rcaron -15
+KPX Uacute racute -20
+KPX Uacute ncaron -10
+KPX Uacute nacute -15
+KPX Uacute ntilde -10
+KPX Uacute p -25
+KPX Uacute n -20
+KPX Uacute m -20
+KPX Uacute A -50
+KPX Ucircumflex ae.sc -45
+KPX Ucircumflex aring.sc -20
+KPX Ucircumflex adieresis.sc -20
+KPX Ucircumflex atilde.sc -20
+KPX Ucircumflex acircumflex.sc -20
+KPX Ucircumflex aacute.sc -30
+KPX Ucircumflex agrave.sc -20
+KPX Ucircumflex a.sc -40
+KPX Ucircumflex aeacute.sc -45
+KPX Ucircumflex aogonek.sc -40
+KPX Ucircumflex amacron.sc -20
+KPX Ucircumflex abreve.sc -20
+KPX Ucircumflex ahookabove.sc -20
+KPX Ucircumflex acircumflexdotbelow.sc -20
+KPX Ucircumflex abrevedotbelow.sc -20
+KPX Ucircumflex rdotaccent -15
+KPX Ucircumflex AEacute -55
+KPX Ucircumflex rcaron -15
+KPX Ucircumflex rcommaaccent -25
+KPX Ucircumflex racute -20
+KPX Ucircumflex ncaron -10
+KPX Ucircumflex ncommaaccent -20
+KPX Ucircumflex nacute -15
+KPX Ucircumflex Aogonek -50
+KPX Ucircumflex Amacron -50
+KPX Ucircumflex ntilde -10
+KPX Ucircumflex AE -55
+KPX Ucircumflex Aring -50
+KPX Ucircumflex Adieresis -50
+KPX Ucircumflex r -25
+KPX Ucircumflex p -25
+KPX Ucircumflex n -20
+KPX Ucircumflex m -20
+KPX Ucircumflex A -50
+KPX Ucircumflex period -15
+KPX Ucircumflex comma -25
+KPX Udieresis ae.sc -45
+KPX Udieresis aring.sc -20
+KPX Udieresis adieresis.sc -20
+KPX Udieresis atilde.sc -20
+KPX Udieresis acircumflex.sc -20
+KPX Udieresis aacute.sc -30
+KPX Udieresis agrave.sc -20
+KPX Udieresis a.sc -40
+KPX Udieresis aeacute.sc -45
+KPX Udieresis aogonek.sc -40
+KPX Udieresis amacron.sc -20
+KPX Udieresis abreve.sc -20
+KPX Udieresis ahookabove.sc -20
+KPX Udieresis acircumflexdotbelow.sc -20
+KPX Udieresis abrevedotbelow.sc -20
+KPX Udieresis rdotaccent -15
+KPX Udieresis AEacute -55
+KPX Udieresis rcaron -15
+KPX Udieresis rcommaaccent -25
+KPX Udieresis racute -20
+KPX Udieresis ncaron -10
+KPX Udieresis ncommaaccent -20
+KPX Udieresis nacute -15
+KPX Udieresis Aogonek -50
+KPX Udieresis Amacron -50
+KPX Udieresis ntilde -10
+KPX Udieresis AE -55
+KPX Udieresis Aring -50
+KPX Udieresis Adieresis -50
+KPX Udieresis r -25
+KPX Udieresis p -25
+KPX Udieresis n -20
+KPX Udieresis m -20
+KPX Udieresis A -50
+KPX Udieresis period -15
+KPX Udieresis comma -25
+KPX Yacute zcaron -50
+KPX Yacute zdotaccent -50
+KPX Yacute zacute -50
+KPX Yacute z -50
+KPX Yacute ccaron -75
+KPX Yacute cdotaccent -75
+KPX Yacute ccircumflex -75
+KPX Yacute cacute -75
+KPX Yacute ccedilla -75
+KPX Yacute c -75
+KPX Yacute scaron -50
+KPX Yacute scedilla -50
+KPX Yacute scircumflex -50
+KPX Yacute sacute -50
+KPX Yacute s -50
+KPX Yacute T_h 35
+KPX Yacute odieresis.sc -20
+KPX Yacute otilde.sc -20
+KPX Yacute ocircumflex.sc -20
+KPX Yacute oacute.sc -30
+KPX Yacute ograve.sc -20
+KPX Yacute ae.sc -55
+KPX Yacute aring.sc -15
+KPX Yacute adieresis.sc -15
+KPX Yacute atilde.sc -15
+KPX Yacute acircumflex.sc -15
+KPX Yacute aacute.sc -25
+KPX Yacute agrave.sc -15
+KPX Yacute t.sc 30
+KPX Yacute c.sc -40
+KPX Yacute tcaron.sc 15
+KPX Yacute scircumflex.sc -10
+KPX Yacute sacute.sc -15
+KPX Yacute omacron.sc -20
+KPX Yacute ohungarumlaut.sc -20
+KPX Yacute obreve.sc -20
+KPX Yacute gdotaccent.sc -20
+KPX Yacute gcircumflex.sc -20
+KPX Yacute gbreve.sc -20
+KPX Yacute cdotaccent.sc -20
+KPX Yacute ccircumflex.sc -20
+KPX Yacute ccaron.sc -20
+KPX Yacute cacute.sc -30
+KPX Yacute aeacute.sc -55
+KPX Yacute amacron.sc -15
+KPX Yacute abreve.sc -15
+KPX Yacute scaron.sc -10
+KPX Yacute ohorntilde.sc -20
+KPX Yacute ohornhookabove.sc -20
+KPX Yacute ohorngrave.sc -20
+KPX Yacute ohorndotbelow.sc -20
+KPX Yacute ohornacute.sc -20
+KPX Yacute ohookabove.sc -20
+KPX Yacute oe.sc -25
+KPX Yacute ocircumflexdotbelow.sc -20
+KPX Yacute gcaron.sc -20
+KPX Yacute gacute.sc -30
+KPX Yacute ahookabove.sc -15
+KPX Yacute acircumflexdotbelow.sc -15
+KPX Yacute abrevedotbelow.sc -15
+KPX Yacute uhorndotbelow -25
+KPX Yacute uhorntilde -25
+KPX Yacute uhornhookabove -25
+KPX Yacute uhorngrave -25
+KPX Yacute uhornacute -25
+KPX Yacute uhookabove -25
+KPX Yacute ohorndotbelow -35
+KPX Yacute ohorntilde -35
+KPX Yacute ohornhookabove -35
+KPX Yacute ohorngrave -35
+KPX Yacute ohornacute -35
+KPX Yacute ocircumflexdotbelow -35
+KPX Yacute ohookabove -35
+KPX Yacute ecircumflexdotbelow -35
+KPX Yacute etilde -35
+KPX Yacute ehookabove -35
+KPX Yacute abrevedotbelow -30
+KPX Yacute acircumflexdotbelow -30
+KPX Yacute ahookabove -30
+KPX Yacute aeacute -60
+KPX Yacute AEacute -80
+KPX Yacute gacute -50
+KPX Yacute gcaron -35
+KPX Yacute uhungarumlaut -25
+KPX Yacute uring -25
+KPX Yacute ubreve -25
+KPX Yacute umacron -25
+KPX Yacute utilde -25
+KPX Yacute oe -50
+KPX Yacute OE -35
+KPX Yacute ohungarumlaut -35
+KPX Yacute obreve -35
+KPX Yacute omacron -35
+KPX Yacute gdotaccent -35
+KPX Yacute gbreve -35
+KPX Yacute gcircumflex -35
+KPX Yacute ecaron -35
+KPX Yacute edotaccent -35
+KPX Yacute ebreve -35
+KPX Yacute emacron -35
+KPX Yacute abreve -30
+KPX Yacute amacron -30
+KPX Yacute udieresis -25
+KPX Yacute ucircumflex -25
+KPX Yacute uacute -40
+KPX Yacute ugrave -25
+KPX Yacute odieresis -35
+KPX Yacute otilde -35
+KPX Yacute ocircumflex -35
+KPX Yacute oacute -55
+KPX Yacute ograve -35
+KPX Yacute edieresis -35
+KPX Yacute ecircumflex -35
+KPX Yacute eacute -55
+KPX Yacute egrave -35
+KPX Yacute ae -60
+KPX Yacute aring -30
+KPX Yacute adieresis -30
+KPX Yacute atilde -30
+KPX Yacute acircumflex -30
+KPX Yacute aacute -40
+KPX Yacute agrave -30
+KPX Yacute AE -80
+KPX Yacute T 35
+KPX Yacute C -45
+KPX agrave y -20
+KPX aacute y -20
+KPX acircumflex y -20
+KPX atilde y -20
+KPX adieresis jacute -25
+KPX adieresis wdieresis -20
+KPX adieresis wacute -20
+KPX adieresis wgrave -20
+KPX adieresis ycircumflex -20
+KPX adieresis wcircumflex -20
+KPX adieresis jcircumflex -25
+KPX adieresis ydieresis -20
+KPX adieresis y -20
+KPX adieresis w -20
+KPX adieresis v -20
+KPX adieresis j -25
+KPX aring jacute -25
+KPX aring wdieresis -20
+KPX aring wacute -20
+KPX aring wgrave -20
+KPX aring ycircumflex -20
+KPX aring wcircumflex -20
+KPX aring jcircumflex -25
+KPX aring ydieresis -20
+KPX aring y -20
+KPX aring w -20
+KPX aring v -20
+KPX aring j -25
+KPX ae ycircumflex -10
+KPX ae ydieresis -10
+KPX ae y -10
+KPX edieresis quoteright 15
+KPX iacute T_h -15
+KPX iacute T -15
+KPX icircumflex T_h -15
+KPX icircumflex jacute -30
+KPX icircumflex uni021A -15
+KPX icircumflex Tcaron -15
+KPX icircumflex jcircumflex -30
+KPX icircumflex j -30
+KPX icircumflex T -15
+KPX idieresis T_h -15
+KPX idieresis jacute -30
+KPX idieresis uni021A -15
+KPX idieresis Tcaron -15
+KPX idieresis jcircumflex -30
+KPX idieresis j -30
+KPX idieresis T -15
+KPX ntilde T_h -60
+KPX ntilde wdieresis -25
+KPX ntilde wacute -25
+KPX ntilde wgrave -25
+KPX ntilde uni021A -60
+KPX ntilde ycircumflex -25
+KPX ntilde wcircumflex -25
+KPX ntilde Tcaron -60
+KPX ntilde ydieresis -25
+KPX ntilde y -25
+KPX ntilde w -25
+KPX ntilde v -25
+KPX ntilde p -20
+KPX ntilde T -60
+KPX oacute T_h -90
+KPX oacute T -90
+KPX odieresis T_h -90
+KPX odieresis wdieresis -20
+KPX odieresis wacute -20
+KPX odieresis wgrave -20
+KPX odieresis uni021A -90
+KPX odieresis ycircumflex -20
+KPX odieresis wcircumflex -20
+KPX odieresis Tcaron -90
+KPX odieresis ydieresis -20
+KPX odieresis y -20
+KPX odieresis x -15
+KPX odieresis w -20
+KPX odieresis v -15
+KPX odieresis T -90
+KPX oslash T_h -90
+KPX oslash wdieresis -20
+KPX oslash wacute -20
+KPX oslash wgrave -20
+KPX oslash uni021A -90
+KPX oslash ycircumflex -20
+KPX oslash wcircumflex -20
+KPX oslash Tcaron -90
+KPX oslash ydieresis -20
+KPX oslash y -20
+KPX oslash x -15
+KPX oslash w -20
+KPX oslash v -15
+KPX oslash T -90
+KPX yacute aeacute -20
+KPX yacute oe -25
+KPX yacute ae -20
+KPX yacute c -35
+KPX ydieresis aeacute -20
+KPX ydieresis gacute -15
+KPX ydieresis oogonek -30
+KPX ydieresis gcaron -15
+KPX ydieresis oe -25
+KPX ydieresis ohungarumlaut -30
+KPX ydieresis obreve -30
+KPX ydieresis omacron -30
+KPX ydieresis lslash -15
+KPX ydieresis lcaron -15
+KPX ydieresis lcommaaccent -15
+KPX ydieresis lacute -15
+KPX ydieresis gcommaaccent -15
+KPX ydieresis gdotaccent -15
+KPX ydieresis gbreve -15
+KPX ydieresis gcircumflex -15
+KPX ydieresis ecaron -35
+KPX ydieresis eogonek -35
+KPX ydieresis edotaccent -35
+KPX ydieresis ebreve -35
+KPX ydieresis emacron -35
+KPX ydieresis ccaron -35
+KPX ydieresis cdotaccent -35
+KPX ydieresis ccircumflex -35
+KPX ydieresis cacute -35
+KPX ydieresis aogonek -25
+KPX ydieresis amacron -25
+KPX ydieresis oslash -30
+KPX ydieresis odieresis -30
+KPX ydieresis edieresis -35
+KPX ydieresis ccedilla -35
+KPX ydieresis ae -20
+KPX ydieresis aring -25
+KPX ydieresis adieresis -25
+KPX ydieresis o -30
+KPX ydieresis l -15
+KPX ydieresis g -15
+KPX ydieresis e -35
+KPX ydieresis c -35
+KPX ydieresis a -25
+KPX ydieresis period -60
+KPX ydieresis hyphen -10
+KPX ydieresis comma -65
+KPX Amacron T_h -55
+KPX Amacron ydieresis.sc -55
+KPX Amacron udieresis.sc -40
+KPX Amacron ucircumflex.sc -40
+KPX Amacron oslash.sc -40
+KPX Amacron odieresis.sc -40
+KPX Amacron ccedilla.sc -40
+KPX Amacron y.sc -55
+KPX Amacron w.sc -60
+KPX Amacron v.sc -105
+KPX Amacron u.sc -40
+KPX Amacron t.sc -45
+KPX Amacron q.sc -35
+KPX Amacron o.sc -40
+KPX Amacron g.sc -45
+KPX Amacron c.sc -40
+KPX Amacron ycircumflex.sc -55
+KPX Amacron wgrave.sc -60
+KPX Amacron wdieresis.sc -60
+KPX Amacron wcircumflex.sc -60
+KPX Amacron wacute.sc -60
+KPX Amacron uring.sc -40
+KPX Amacron uogonek.sc -40
+KPX Amacron umacron.sc -40
+KPX Amacron uhungarumlaut.sc -40
+KPX Amacron ubreve.sc -40
+KPX Amacron uni021B.sc -45
+KPX Amacron tcaron.sc -45
+KPX Amacron omacron.sc -40
+KPX Amacron ohungarumlaut.sc -40
+KPX Amacron obreve.sc -40
+KPX Amacron gdotaccent.sc -45
+KPX Amacron gcommaaccent.sc -45
+KPX Amacron gcircumflex.sc -45
+KPX Amacron gbreve.sc -45
+KPX Amacron cdotaccent.sc -40
+KPX Amacron ccircumflex.sc -40
+KPX Amacron ccaron.sc -40
+KPX Amacron cacute.sc -40
+KPX Amacron oogonek.sc -40
+KPX Amacron gcaron.sc -45
+KPX Amacron gacute.sc -45
+KPX Amacron guilsinglleft -70
+KPX Amacron quotedblright -85
+KPX Amacron quoteright -80
+KPX Amacron wdieresis -60
+KPX Amacron Wdieresis -70
+KPX Amacron wacute -60
+KPX Amacron Wacute -70
+KPX Amacron wgrave -60
+KPX Amacron Wgrave -70
+KPX Amacron uni021B -15
+KPX Amacron uni021A -55
+KPX Amacron Gacute -55
+KPX Amacron oogonek -15
+KPX Amacron Oogonek -45
+KPX Amacron Gcaron -55
+KPX Amacron Ydieresis -65
+KPX Amacron ycircumflex -70
+KPX Amacron Ycircumflex -65
+KPX Amacron wcircumflex -60
+KPX Amacron Wcircumflex -70
+KPX Amacron uogonek -25
+KPX Amacron Uogonek -45
+KPX Amacron uhungarumlaut -25
+KPX Amacron Uhungarumlaut -45
+KPX Amacron uring -25
+KPX Amacron Uring -45
+KPX Amacron ubreve -25
+KPX Amacron Ubreve -45
+KPX Amacron umacron -25
+KPX Amacron Umacron -45
+KPX Amacron tcaron -15
+KPX Amacron Tcaron -55
+KPX Amacron ohungarumlaut -15
+KPX Amacron Ohungarumlaut -45
+KPX Amacron obreve -15
+KPX Amacron Obreve -45
+KPX Amacron omacron -15
+KPX Amacron Omacron -45
+KPX Amacron Gcommaaccent -55
+KPX Amacron Gdotaccent -55
+KPX Amacron Gbreve -55
+KPX Amacron Gcircumflex -55
+KPX Amacron ecaron -15
+KPX Amacron eogonek -15
+KPX Amacron edotaccent -15
+KPX Amacron ebreve -15
+KPX Amacron emacron -15
+KPX Amacron dcaron -15
+KPX Amacron ccaron -15
+KPX Amacron Ccaron -50
+KPX Amacron cdotaccent -15
+KPX Amacron Cdotaccent -50
+KPX Amacron ccircumflex -15
+KPX Amacron Ccircumflex -50
+KPX Amacron cacute -15
+KPX Amacron Cacute -50
+KPX Amacron ydieresis -70
+KPX Amacron udieresis -25
+KPX Amacron ucircumflex -25
+KPX Amacron oslash -15
+KPX Amacron odieresis -15
+KPX Amacron edieresis -15
+KPX Amacron ccedilla -15
+KPX Amacron Udieresis -45
+KPX Amacron Ucircumflex -45
+KPX Amacron Oslash -45
+KPX Amacron Odieresis -45
+KPX Amacron Ccedilla -50
+KPX Amacron guillemotleft -50
+KPX Amacron y -70
+KPX Amacron w -60
+KPX Amacron v -70
+KPX Amacron u -25
+KPX Amacron t -15
+KPX Amacron q -20
+KPX Amacron o -15
+KPX Amacron e -15
+KPX Amacron d -15
+KPX Amacron c -15
+KPX Amacron Y -65
+KPX Amacron W -70
+KPX Amacron V -125
+KPX Amacron U -45
+KPX Amacron T -55
+KPX Amacron Q -40
+KPX Amacron O -45
+KPX Amacron G -55
+KPX Amacron C -50
+KPX Amacron period 10
+KPX Amacron hyphen -10
+KPX amacron jacute -25
+KPX amacron wdieresis -20
+KPX amacron wacute -20
+KPX amacron wgrave -20
+KPX amacron ycircumflex -20
+KPX amacron wcircumflex -20
+KPX amacron jcircumflex -25
+KPX amacron ydieresis -20
+KPX amacron y -20
+KPX amacron w -20
+KPX amacron v -20
+KPX amacron j -25
+KPX Aogonek T_h -55
+KPX Aogonek ydieresis.sc -55
+KPX Aogonek udieresis.sc -40
+KPX Aogonek ucircumflex.sc -40
+KPX Aogonek oslash.sc -40
+KPX Aogonek odieresis.sc -40
+KPX Aogonek ccedilla.sc -40
+KPX Aogonek y.sc -55
+KPX Aogonek w.sc -60
+KPX Aogonek v.sc -105
+KPX Aogonek u.sc -40
+KPX Aogonek t.sc -45
+KPX Aogonek q.sc -35
+KPX Aogonek o.sc -40
+KPX Aogonek g.sc -45
+KPX Aogonek c.sc -40
+KPX Aogonek ycircumflex.sc -55
+KPX Aogonek wgrave.sc -60
+KPX Aogonek wdieresis.sc -60
+KPX Aogonek wcircumflex.sc -60
+KPX Aogonek wacute.sc -60
+KPX Aogonek uring.sc -40
+KPX Aogonek uogonek.sc -40
+KPX Aogonek umacron.sc -40
+KPX Aogonek uhungarumlaut.sc -40
+KPX Aogonek ubreve.sc -40
+KPX Aogonek uni021B.sc -45
+KPX Aogonek tcaron.sc -45
+KPX Aogonek omacron.sc -40
+KPX Aogonek ohungarumlaut.sc -40
+KPX Aogonek obreve.sc -40
+KPX Aogonek gdotaccent.sc -45
+KPX Aogonek gcommaaccent.sc -45
+KPX Aogonek gcircumflex.sc -45
+KPX Aogonek gbreve.sc -45
+KPX Aogonek cdotaccent.sc -40
+KPX Aogonek ccircumflex.sc -40
+KPX Aogonek ccaron.sc -40
+KPX Aogonek cacute.sc -40
+KPX Aogonek oogonek.sc -40
+KPX Aogonek gcaron.sc -45
+KPX Aogonek gacute.sc -45
+KPX Aogonek guilsinglleft -70
+KPX Aogonek quotedblright -85
+KPX Aogonek quoteright -80
+KPX Aogonek wdieresis -60
+KPX Aogonek Wdieresis -70
+KPX Aogonek wacute -60
+KPX Aogonek Wacute -70
+KPX Aogonek wgrave -60
+KPX Aogonek Wgrave -70
+KPX Aogonek uni021B -15
+KPX Aogonek uni021A -55
+KPX Aogonek Gacute -55
+KPX Aogonek oogonek -15
+KPX Aogonek Oogonek -45
+KPX Aogonek Gcaron -55
+KPX Aogonek Ydieresis -65
+KPX Aogonek Ycircumflex -65
+KPX Aogonek wcircumflex -60
+KPX Aogonek Wcircumflex -70
+KPX Aogonek uogonek -25
+KPX Aogonek Uogonek -45
+KPX Aogonek uhungarumlaut -25
+KPX Aogonek Uhungarumlaut -45
+KPX Aogonek uring -25
+KPX Aogonek Uring -45
+KPX Aogonek ubreve -25
+KPX Aogonek Ubreve -45
+KPX Aogonek umacron -25
+KPX Aogonek Umacron -45
+KPX Aogonek tcaron -15
+KPX Aogonek Tcaron -55
+KPX Aogonek ohungarumlaut -15
+KPX Aogonek Ohungarumlaut -45
+KPX Aogonek obreve -15
+KPX Aogonek Obreve -45
+KPX Aogonek omacron -15
+KPX Aogonek Omacron -45
+KPX Aogonek Gcommaaccent -55
+KPX Aogonek Gdotaccent -55
+KPX Aogonek Gbreve -55
+KPX Aogonek Gcircumflex -55
+KPX Aogonek ecaron -15
+KPX Aogonek eogonek -15
+KPX Aogonek edotaccent -15
+KPX Aogonek ebreve -15
+KPX Aogonek emacron -15
+KPX Aogonek dcaron -15
+KPX Aogonek ccaron -15
+KPX Aogonek Ccaron -50
+KPX Aogonek cdotaccent -15
+KPX Aogonek Cdotaccent -50
+KPX Aogonek ccircumflex -15
+KPX Aogonek Ccircumflex -50
+KPX Aogonek cacute -15
+KPX Aogonek Cacute -50
+KPX Aogonek udieresis -25
+KPX Aogonek ucircumflex -25
+KPX Aogonek oslash -15
+KPX Aogonek odieresis -15
+KPX Aogonek edieresis -15
+KPX Aogonek ccedilla -15
+KPX Aogonek Udieresis -45
+KPX Aogonek Ucircumflex -45
+KPX Aogonek Oslash -45
+KPX Aogonek Odieresis -45
+KPX Aogonek Ccedilla -50
+KPX Aogonek guillemotleft -50
+KPX Aogonek w -60
+KPX Aogonek v -70
+KPX Aogonek u -25
+KPX Aogonek t -15
+KPX Aogonek q -20
+KPX Aogonek o -15
+KPX Aogonek e -15
+KPX Aogonek d -15
+KPX Aogonek c -15
+KPX Aogonek Y -65
+KPX Aogonek W -70
+KPX Aogonek V -125
+KPX Aogonek U -45
+KPX Aogonek T -55
+KPX Aogonek Q -40
+KPX Aogonek O -45
+KPX Aogonek G -55
+KPX Aogonek C -50
+KPX Aogonek period 10
+KPX Aogonek hyphen -10
+KPX aogonek wdieresis -20
+KPX aogonek wacute -20
+KPX aogonek wgrave -20
+KPX aogonek wcircumflex -20
+KPX aogonek w -20
+KPX aogonek v -20
+KPX Cacute oslash.sc -15
+KPX Cacute odieresis.sc -15
+KPX Cacute aring.sc 10
+KPX Cacute adieresis.sc 10
+KPX Cacute o.sc -15
+KPX Cacute k.sc 10
+KPX Cacute h.sc 15
+KPX Cacute a.sc 10
+KPX Cacute omacron.sc -15
+KPX Cacute ohungarumlaut.sc -15
+KPX Cacute obreve.sc -15
+KPX Cacute kcommaaccent.sc 10
+KPX Cacute hcircumflex.sc 15
+KPX Cacute aogonek.sc 10
+KPX Cacute amacron.sc 10
+KPX Cacute oogonek.sc -15
+KPX Cacute Oogonek -15
+KPX Cacute Ohungarumlaut -15
+KPX Cacute Obreve -15
+KPX Cacute Omacron -15
+KPX Cacute Kcommaaccent 10
+KPX Cacute Hcircumflex 15
+KPX Cacute Aogonek 10
+KPX Cacute Amacron 10
+KPX Cacute Oslash -15
+KPX Cacute Odieresis -15
+KPX Cacute Aring 10
+KPX Cacute Adieresis 10
+KPX Cacute O -15
+KPX Cacute K 10
+KPX Cacute H 15
+KPX Cacute A 10
+KPX Ccircumflex oslash.sc -15
+KPX Ccircumflex odieresis.sc -15
+KPX Ccircumflex aring.sc 10
+KPX Ccircumflex adieresis.sc 10
+KPX Ccircumflex o.sc -15
+KPX Ccircumflex k.sc 10
+KPX Ccircumflex h.sc 15
+KPX Ccircumflex a.sc 10
+KPX Ccircumflex omacron.sc -15
+KPX Ccircumflex ohungarumlaut.sc -15
+KPX Ccircumflex obreve.sc -15
+KPX Ccircumflex kcommaaccent.sc 10
+KPX Ccircumflex hcircumflex.sc 15
+KPX Ccircumflex aogonek.sc 10
+KPX Ccircumflex amacron.sc 10
+KPX Ccircumflex oogonek.sc -15
+KPX Ccircumflex Oogonek -15
+KPX Ccircumflex Ohungarumlaut -15
+KPX Ccircumflex Obreve -15
+KPX Ccircumflex Omacron -15
+KPX Ccircumflex Kcommaaccent 10
+KPX Ccircumflex Hcircumflex 15
+KPX Ccircumflex Aogonek 10
+KPX Ccircumflex Amacron 10
+KPX Ccircumflex Oslash -15
+KPX Ccircumflex Odieresis -15
+KPX Ccircumflex Aring 10
+KPX Ccircumflex Adieresis 10
+KPX Ccircumflex O -15
+KPX Ccircumflex K 10
+KPX Ccircumflex H 15
+KPX Ccircumflex A 10
+KPX Cdotaccent oslash.sc -15
+KPX Cdotaccent odieresis.sc -15
+KPX Cdotaccent aring.sc 10
+KPX Cdotaccent adieresis.sc 10
+KPX Cdotaccent o.sc -15
+KPX Cdotaccent k.sc 10
+KPX Cdotaccent h.sc 15
+KPX Cdotaccent a.sc 10
+KPX Cdotaccent omacron.sc -15
+KPX Cdotaccent ohungarumlaut.sc -15
+KPX Cdotaccent obreve.sc -15
+KPX Cdotaccent kcommaaccent.sc 10
+KPX Cdotaccent hcircumflex.sc 15
+KPX Cdotaccent aogonek.sc 10
+KPX Cdotaccent amacron.sc 10
+KPX Cdotaccent oogonek.sc -15
+KPX Cdotaccent Oogonek -15
+KPX Cdotaccent Ohungarumlaut -15
+KPX Cdotaccent Obreve -15
+KPX Cdotaccent Omacron -15
+KPX Cdotaccent Kcommaaccent 10
+KPX Cdotaccent Hcircumflex 15
+KPX Cdotaccent Aogonek 10
+KPX Cdotaccent Amacron 10
+KPX Cdotaccent Oslash -15
+KPX Cdotaccent Odieresis -15
+KPX Cdotaccent Aring 10
+KPX Cdotaccent Adieresis 10
+KPX Cdotaccent O -15
+KPX Cdotaccent K 10
+KPX Cdotaccent H 15
+KPX Cdotaccent A 10
+KPX Ccaron oslash.sc -15
+KPX Ccaron odieresis.sc -15
+KPX Ccaron aring.sc 10
+KPX Ccaron adieresis.sc 10
+KPX Ccaron o.sc -15
+KPX Ccaron k.sc 10
+KPX Ccaron h.sc 15
+KPX Ccaron a.sc 10
+KPX Ccaron omacron.sc -15
+KPX Ccaron ohungarumlaut.sc -15
+KPX Ccaron obreve.sc -15
+KPX Ccaron kcommaaccent.sc 10
+KPX Ccaron hcircumflex.sc 15
+KPX Ccaron aogonek.sc 10
+KPX Ccaron amacron.sc 10
+KPX Ccaron oogonek.sc -15
+KPX Ccaron Oogonek -15
+KPX Ccaron Ohungarumlaut -15
+KPX Ccaron Obreve -15
+KPX Ccaron Omacron -15
+KPX Ccaron Kcommaaccent 10
+KPX Ccaron Hcircumflex 15
+KPX Ccaron Aogonek 10
+KPX Ccaron Amacron 10
+KPX Ccaron Oslash -15
+KPX Ccaron Odieresis -15
+KPX Ccaron Aring 10
+KPX Ccaron Adieresis 10
+KPX Ccaron O -15
+KPX Ccaron K 10
+KPX Ccaron H 15
+KPX Ccaron A 10
+KPX Dcaron ydieresis.sc -25
+KPX Dcaron aring.sc -55
+KPX Dcaron adieresis.sc -55
+KPX Dcaron y.sc -25
+KPX Dcaron x.sc -30
+KPX Dcaron w.sc -30
+KPX Dcaron v.sc -35
+KPX Dcaron j.sc -20
+KPX Dcaron a.sc -55
+KPX Dcaron ycircumflex.sc -25
+KPX Dcaron wgrave.sc -30
+KPX Dcaron wdieresis.sc -30
+KPX Dcaron wcircumflex.sc -30
+KPX Dcaron wacute.sc -30
+KPX Dcaron jcircumflex.sc -20
+KPX Dcaron aogonek.sc -55
+KPX Dcaron amacron.sc -55
+KPX Dcaron Jacute -25
+KPX Dcaron jacute.sc -20
+KPX Dcaron Wdieresis -35
+KPX Dcaron Wacute -35
+KPX Dcaron Wgrave -35
+KPX Dcaron Ydieresis -30
+KPX Dcaron Ycircumflex -30
+KPX Dcaron Wcircumflex -35
+KPX Dcaron Jcircumflex -25
+KPX Dcaron Aogonek -65
+KPX Dcaron Amacron -65
+KPX Dcaron Aring -65
+KPX Dcaron Adieresis -65
+KPX Dcaron Y -30
+KPX Dcaron X -35
+KPX Dcaron W -35
+KPX Dcaron V -40
+KPX Dcaron J -25
+KPX Dcaron A -65
+KPX dcaron quotedblright 40
+KPX dcaron quotedblleft 40
+KPX dcaron quoteright 40
+KPX dcaron quoteleft 40
+KPX dcaron lcaron 35
+KPX dcaron lcommaaccent 35
+KPX dcaron lacute 35
+KPX dcaron kcommaaccent 35
+KPX dcaron hcircumflex 35
+KPX dcaron thorn 35
+KPX dcaron l 35
+KPX dcaron k 35
+KPX dcaron h 35
+KPX dcaron b 35
+KPX dcaron backslash 40
+KPX Dcroat atilde.sc -55
+KPX Dcroat acircumflex.sc -55
+KPX Dcroat aacute.sc -55
+KPX Dcroat agrave.sc -55
+KPX Dcroat a.sc -55
+KPX Dcroat abreve.sc -55
+KPX Dcroat ahookabove.sc -55
+KPX Dcroat adotbelow.sc -55
+KPX Dcroat acircumflextilde.sc -55
+KPX Dcroat acircumflexhookabove.sc -55
+KPX Dcroat acircumflexgrave.sc -55
+KPX Dcroat acircumflexdotbelow.sc -55
+KPX Dcroat acircumflexacute.sc -55
+KPX Dcroat abrevetilde.sc -55
+KPX Dcroat abrevehookabove.sc -55
+KPX Dcroat abrevegrave.sc -55
+KPX Dcroat abrevedotbelow.sc -55
+KPX Dcroat abreveacute.sc -55
+KPX Dcroat Abrevedotbelow -65
+KPX Dcroat Abrevetilde -65
+KPX Dcroat Abrevehookabove -65
+KPX Dcroat Abrevegrave -65
+KPX Dcroat Abreveacute -65
+KPX Dcroat Acircumflexdotbelow -65
+KPX Dcroat Acircumflextilde -65
+KPX Dcroat Acircumflexhookabove -65
+KPX Dcroat Acircumflexgrave -65
+KPX Dcroat Acircumflexacute -65
+KPX Dcroat Ahookabove -65
+KPX Dcroat Adotbelow -65
+KPX Dcroat Abreve -65
+KPX Dcroat Atilde -65
+KPX Dcroat Acircumflex -65
+KPX Dcroat Aacute -65
+KPX Dcroat Agrave -65
+KPX Dcroat A -65
+KPX emacron quoteright 15
+KPX ebreve quoteright 15
+KPX edotaccent quoteright 15
+KPX eogonek quoteright 15
+KPX ecaron quoteright 15
+KPX Gcircumflex T_h -15
+KPX Gcircumflex ydieresis.sc -15
+KPX Gcircumflex ae.sc -15
+KPX Gcircumflex aring.sc -15
+KPX Gcircumflex adieresis.sc -15
+KPX Gcircumflex y.sc -15
+KPX Gcircumflex w.sc -15
+KPX Gcircumflex v.sc -15
+KPX Gcircumflex t.sc -15
+KPX Gcircumflex a.sc -15
+KPX Gcircumflex ycircumflex.sc -15
+KPX Gcircumflex wgrave.sc -15
+KPX Gcircumflex wdieresis.sc -15
+KPX Gcircumflex wcircumflex.sc -15
+KPX Gcircumflex wacute.sc -15
+KPX Gcircumflex uni021B.sc -15
+KPX Gcircumflex tcaron.sc -15
+KPX Gcircumflex aeacute.sc -15
+KPX Gcircumflex aogonek.sc -15
+KPX Gcircumflex amacron.sc -15
+KPX Gcircumflex Wdieresis -15
+KPX Gcircumflex Wacute -15
+KPX Gcircumflex Wgrave -15
+KPX Gcircumflex uni021A -15
+KPX Gcircumflex AEacute -15
+KPX Gcircumflex Ydieresis -15
+KPX Gcircumflex Ycircumflex -15
+KPX Gcircumflex Wcircumflex -15
+KPX Gcircumflex Tcaron -15
+KPX Gcircumflex Aogonek -15
+KPX Gcircumflex Amacron -15
+KPX Gcircumflex AE -15
+KPX Gcircumflex Aring -15
+KPX Gcircumflex Adieresis -15
+KPX Gcircumflex Y -15
+KPX Gcircumflex W -15
+KPX Gcircumflex V -20
+KPX Gcircumflex T -15
+KPX Gcircumflex A -15
+KPX gcircumflex rdotaccent 15
+KPX gcircumflex rcaron 15
+KPX gcircumflex rcommaaccent 15
+KPX gcircumflex racute 15
+KPX gcircumflex ecaron -15
+KPX gcircumflex eogonek -15
+KPX gcircumflex edotaccent -15
+KPX gcircumflex ebreve -15
+KPX gcircumflex emacron -15
+KPX gcircumflex edieresis -15
+KPX gcircumflex r 15
+KPX gcircumflex e -15
+KPX Gbreve T_h -15
+KPX Gbreve ydieresis.sc -15
+KPX Gbreve ae.sc -15
+KPX Gbreve aring.sc -15
+KPX Gbreve adieresis.sc -15
+KPX Gbreve y.sc -15
+KPX Gbreve w.sc -15
+KPX Gbreve v.sc -15
+KPX Gbreve t.sc -15
+KPX Gbreve a.sc -15
+KPX Gbreve ycircumflex.sc -15
+KPX Gbreve wgrave.sc -15
+KPX Gbreve wdieresis.sc -15
+KPX Gbreve wcircumflex.sc -15
+KPX Gbreve wacute.sc -15
+KPX Gbreve uni021B.sc -15
+KPX Gbreve tcaron.sc -15
+KPX Gbreve aeacute.sc -15
+KPX Gbreve aogonek.sc -15
+KPX Gbreve amacron.sc -15
+KPX Gbreve Wdieresis -15
+KPX Gbreve Wacute -15
+KPX Gbreve Wgrave -15
+KPX Gbreve uni021A -15
+KPX Gbreve AEacute -15
+KPX Gbreve Ydieresis -15
+KPX Gbreve Ycircumflex -15
+KPX Gbreve Wcircumflex -15
+KPX Gbreve Tcaron -15
+KPX Gbreve Aogonek -15
+KPX Gbreve Amacron -15
+KPX Gbreve AE -15
+KPX Gbreve Aring -15
+KPX Gbreve Adieresis -15
+KPX Gbreve Y -15
+KPX Gbreve W -15
+KPX Gbreve V -20
+KPX Gbreve T -15
+KPX Gbreve A -15
+KPX gbreve rdotaccent 15
+KPX gbreve rcaron 15
+KPX gbreve rcommaaccent 15
+KPX gbreve racute 15
+KPX gbreve ecaron -15
+KPX gbreve eogonek -15
+KPX gbreve edotaccent -15
+KPX gbreve ebreve -15
+KPX gbreve emacron -15
+KPX gbreve edieresis -15
+KPX gbreve r 15
+KPX gbreve e -15
+KPX Gdotaccent T_h -15
+KPX Gdotaccent ydieresis.sc -15
+KPX Gdotaccent ae.sc -15
+KPX Gdotaccent aring.sc -15
+KPX Gdotaccent adieresis.sc -15
+KPX Gdotaccent y.sc -15
+KPX Gdotaccent w.sc -15
+KPX Gdotaccent v.sc -15
+KPX Gdotaccent t.sc -15
+KPX Gdotaccent a.sc -15
+KPX Gdotaccent ycircumflex.sc -15
+KPX Gdotaccent wgrave.sc -15
+KPX Gdotaccent wdieresis.sc -15
+KPX Gdotaccent wcircumflex.sc -15
+KPX Gdotaccent wacute.sc -15
+KPX Gdotaccent uni021B.sc -15
+KPX Gdotaccent tcaron.sc -15
+KPX Gdotaccent aeacute.sc -15
+KPX Gdotaccent aogonek.sc -15
+KPX Gdotaccent amacron.sc -15
+KPX Gdotaccent Wdieresis -15
+KPX Gdotaccent Wacute -15
+KPX Gdotaccent Wgrave -15
+KPX Gdotaccent uni021A -15
+KPX Gdotaccent AEacute -15
+KPX Gdotaccent Ydieresis -15
+KPX Gdotaccent Ycircumflex -15
+KPX Gdotaccent Wcircumflex -15
+KPX Gdotaccent Tcaron -15
+KPX Gdotaccent Aogonek -15
+KPX Gdotaccent Amacron -15
+KPX Gdotaccent AE -15
+KPX Gdotaccent Aring -15
+KPX Gdotaccent Adieresis -15
+KPX Gdotaccent Y -15
+KPX Gdotaccent W -15
+KPX Gdotaccent V -20
+KPX Gdotaccent T -15
+KPX Gdotaccent A -15
+KPX gdotaccent rdotaccent 15
+KPX gdotaccent rcaron 15
+KPX gdotaccent rcommaaccent 15
+KPX gdotaccent racute 15
+KPX gdotaccent ecaron -15
+KPX gdotaccent eogonek -15
+KPX gdotaccent edotaccent -15
+KPX gdotaccent ebreve -15
+KPX gdotaccent emacron -15
+KPX gdotaccent edieresis -15
+KPX gdotaccent r 15
+KPX gdotaccent e -15
+KPX Gcommaaccent T_h -15
+KPX Gcommaaccent ydieresis.sc -15
+KPX Gcommaaccent ae.sc -15
+KPX Gcommaaccent aring.sc -15
+KPX Gcommaaccent adieresis.sc -15
+KPX Gcommaaccent y.sc -15
+KPX Gcommaaccent w.sc -15
+KPX Gcommaaccent v.sc -15
+KPX Gcommaaccent t.sc -15
+KPX Gcommaaccent a.sc -15
+KPX Gcommaaccent ycircumflex.sc -15
+KPX Gcommaaccent wgrave.sc -15
+KPX Gcommaaccent wdieresis.sc -15
+KPX Gcommaaccent wcircumflex.sc -15
+KPX Gcommaaccent wacute.sc -15
+KPX Gcommaaccent uni021B.sc -15
+KPX Gcommaaccent tcaron.sc -15
+KPX Gcommaaccent aeacute.sc -15
+KPX Gcommaaccent aogonek.sc -15
+KPX Gcommaaccent amacron.sc -15
+KPX Gcommaaccent Wdieresis -15
+KPX Gcommaaccent Wacute -15
+KPX Gcommaaccent Wgrave -15
+KPX Gcommaaccent uni021A -15
+KPX Gcommaaccent AEacute -15
+KPX Gcommaaccent Ydieresis -15
+KPX Gcommaaccent Ycircumflex -15
+KPX Gcommaaccent Wcircumflex -15
+KPX Gcommaaccent Tcaron -15
+KPX Gcommaaccent Aogonek -15
+KPX Gcommaaccent Amacron -15
+KPX Gcommaaccent AE -15
+KPX Gcommaaccent Aring -15
+KPX Gcommaaccent Adieresis -15
+KPX Gcommaaccent Y -15
+KPX Gcommaaccent W -15
+KPX Gcommaaccent V -20
+KPX Gcommaaccent T -15
+KPX Gcommaaccent A -15
+KPX gcommaaccent rdotaccent 15
+KPX gcommaaccent rcaron 15
+KPX gcommaaccent rcommaaccent 15
+KPX gcommaaccent racute 15
+KPX gcommaaccent ecaron -15
+KPX gcommaaccent eogonek -15
+KPX gcommaaccent edotaccent -15
+KPX gcommaaccent ebreve -15
+KPX gcommaaccent emacron -15
+KPX gcommaaccent edieresis -15
+KPX gcommaaccent r 15
+KPX gcommaaccent e -15
+KPX hcircumflex ycircumflex -25
+KPX hcircumflex ydieresis -25
+KPX hcircumflex y -25
+KPX imacron T_h -15
+KPX imacron jacute -30
+KPX imacron uni021A -15
+KPX imacron Tcaron -15
+KPX imacron jcircumflex -30
+KPX imacron j -30
+KPX imacron T -15
+KPX ibreve T_h -15
+KPX ibreve jacute -30
+KPX ibreve uni021A -15
+KPX ibreve Tcaron -15
+KPX ibreve jcircumflex -30
+KPX ibreve j -30
+KPX ibreve T -15
+KPX iogonek T_h -15
+KPX iogonek uni021A -15
+KPX iogonek Tcaron -15
+KPX iogonek T -15
+KPX Jcircumflex ae.sc -20
+KPX Jcircumflex aring.sc -25
+KPX Jcircumflex adieresis.sc -25
+KPX Jcircumflex a.sc -25
+KPX Jcircumflex aeacute.sc -20
+KPX Jcircumflex aogonek.sc -25
+KPX Jcircumflex amacron.sc -25
+KPX Jcircumflex AEacute -25
+KPX Jcircumflex Aogonek -30
+KPX Jcircumflex Amacron -30
+KPX Jcircumflex AE -25
+KPX Jcircumflex Aring -30
+KPX Jcircumflex Adieresis -30
+KPX Jcircumflex A -30
+KPX Kcommaaccent T_h 20
+KPX Kcommaaccent oslash.sc -35
+KPX Kcommaaccent odieresis.sc -35
+KPX Kcommaaccent ccedilla.sc -40
+KPX Kcommaaccent t.sc 15
+KPX Kcommaaccent o.sc -35
+KPX Kcommaaccent g.sc -40
+KPX Kcommaaccent c.sc -40
+KPX Kcommaaccent uni021B.sc 15
+KPX Kcommaaccent tcaron.sc 15
+KPX Kcommaaccent omacron.sc -35
+KPX Kcommaaccent ohungarumlaut.sc -35
+KPX Kcommaaccent obreve.sc -35
+KPX Kcommaaccent gdotaccent.sc -40
+KPX Kcommaaccent gcommaaccent.sc -40
+KPX Kcommaaccent gcircumflex.sc -40
+KPX Kcommaaccent gbreve.sc -40
+KPX Kcommaaccent cdotaccent.sc -40
+KPX Kcommaaccent ccircumflex.sc -40
+KPX Kcommaaccent ccaron.sc -40
+KPX Kcommaaccent cacute.sc -40
+KPX Kcommaaccent oogonek.sc -35
+KPX Kcommaaccent oe.sc -35
+KPX Kcommaaccent gcaron.sc -40
+KPX Kcommaaccent gacute.sc -40
+KPX Kcommaaccent uni021A 20
+KPX Kcommaaccent Gacute -50
+KPX Kcommaaccent oogonek -10
+KPX Kcommaaccent Oogonek -40
+KPX Kcommaaccent Gcaron -50
+KPX Kcommaaccent ycircumflex -70
+KPX Kcommaaccent uogonek -25
+KPX Kcommaaccent uhungarumlaut -25
+KPX Kcommaaccent uring -25
+KPX Kcommaaccent ubreve -25
+KPX Kcommaaccent umacron -25
+KPX Kcommaaccent Tcaron 20
+KPX Kcommaaccent OE -40
+KPX Kcommaaccent ohungarumlaut -10
+KPX Kcommaaccent Ohungarumlaut -40
+KPX Kcommaaccent obreve -10
+KPX Kcommaaccent Obreve -40
+KPX Kcommaaccent omacron -10
+KPX Kcommaaccent Omacron -40
+KPX Kcommaaccent Gcommaaccent -50
+KPX Kcommaaccent Gdotaccent -50
+KPX Kcommaaccent Gbreve -50
+KPX Kcommaaccent Gcircumflex -50
+KPX Kcommaaccent ecaron -10
+KPX Kcommaaccent eogonek -10
+KPX Kcommaaccent edotaccent -10
+KPX Kcommaaccent ebreve -10
+KPX Kcommaaccent emacron -10
+KPX Kcommaaccent Ccaron -50
+KPX Kcommaaccent Cdotaccent -50
+KPX Kcommaaccent Ccircumflex -50
+KPX Kcommaaccent Cacute -50
+KPX Kcommaaccent ydieresis -70
+KPX Kcommaaccent udieresis -25
+KPX Kcommaaccent ucircumflex -25
+KPX Kcommaaccent oslash -10
+KPX Kcommaaccent odieresis -10
+KPX Kcommaaccent edieresis -10
+KPX Kcommaaccent Oslash -40
+KPX Kcommaaccent Odieresis -40
+KPX Kcommaaccent Ccedilla -50
+KPX Kcommaaccent y -70
+KPX Kcommaaccent u -25
+KPX Kcommaaccent o -10
+KPX Kcommaaccent e -10
+KPX Kcommaaccent T 20
+KPX Kcommaaccent O -40
+KPX Kcommaaccent G -50
+KPX Kcommaaccent C -50
+KPX Kcommaaccent hyphen -45
+KPX kcommaaccent uni0219 15
+KPX kcommaaccent oogonek -15
+KPX kcommaaccent scaron 15
+KPX kcommaaccent scedilla 15
+KPX kcommaaccent scircumflex 15
+KPX kcommaaccent sacute 15
+KPX kcommaaccent ohungarumlaut -15
+KPX kcommaaccent obreve -15
+KPX kcommaaccent omacron -15
+KPX kcommaaccent ecaron -15
+KPX kcommaaccent eogonek -15
+KPX kcommaaccent edotaccent -15
+KPX kcommaaccent ebreve -15
+KPX kcommaaccent emacron -15
+KPX kcommaaccent oslash -15
+KPX kcommaaccent odieresis -15
+KPX kcommaaccent edieresis -15
+KPX kcommaaccent s 15
+KPX kcommaaccent o -15
+KPX kcommaaccent e -15
+KPX kcommaaccent period 10
+KPX kcommaaccent hyphen -35
+KPX Lacute T_h -65
+KPX Lacute ydieresis.sc -65
+KPX Lacute udieresis.sc -20
+KPX Lacute ucircumflex.sc -20
+KPX Lacute ccedilla.sc -10
+KPX Lacute ae.sc 15
+KPX Lacute aring.sc 15
+KPX Lacute adieresis.sc 15
+KPX Lacute y.sc -65
+KPX Lacute w.sc -55
+KPX Lacute v.sc -80
+KPX Lacute u.sc -20
+KPX Lacute t.sc -55
+KPX Lacute g.sc -15
+KPX Lacute c.sc -10
+KPX Lacute a.sc 15
+KPX Lacute ycircumflex.sc -65
+KPX Lacute wgrave.sc -55
+KPX Lacute wdieresis.sc -55
+KPX Lacute wcircumflex.sc -55
+KPX Lacute wacute.sc -55
+KPX Lacute uring.sc -20
+KPX Lacute uogonek.sc -20
+KPX Lacute umacron.sc -20
+KPX Lacute uhungarumlaut.sc -20
+KPX Lacute ubreve.sc -20
+KPX Lacute uni021B.sc -55
+KPX Lacute tcaron.sc -55
+KPX Lacute gdotaccent.sc -15
+KPX Lacute gcommaaccent.sc -15
+KPX Lacute gcircumflex.sc -15
+KPX Lacute gbreve.sc -15
+KPX Lacute cdotaccent.sc -10
+KPX Lacute ccircumflex.sc -10
+KPX Lacute ccaron.sc -10
+KPX Lacute cacute.sc -10
+KPX Lacute aeacute.sc 15
+KPX Lacute aogonek.sc 15
+KPX Lacute amacron.sc 15
+KPX Lacute gcaron.sc -15
+KPX Lacute gacute.sc -15
+KPX Lacute quotedblright -80
+KPX Lacute quoteright -80
+KPX Lacute Wdieresis -65
+KPX Lacute Wacute -65
+KPX Lacute Wgrave -65
+KPX Lacute uni021A -65
+KPX Lacute AEacute 20
+KPX Lacute Gacute -15
+KPX Lacute Gcaron -15
+KPX Lacute Ydieresis -75
+KPX Lacute ycircumflex -55
+KPX Lacute Ycircumflex -75
+KPX Lacute Wcircumflex -65
+KPX Lacute uogonek -20
+KPX Lacute Uogonek -25
+KPX Lacute uhungarumlaut -20
+KPX Lacute Uhungarumlaut -25
+KPX Lacute uring -20
+KPX Lacute Uring -25
+KPX Lacute ubreve -20
+KPX Lacute Ubreve -25
+KPX Lacute umacron -20
+KPX Lacute Umacron -25
+KPX Lacute Tcaron -65
+KPX Lacute Gcommaaccent -15
+KPX Lacute Gdotaccent -15
+KPX Lacute Gbreve -15
+KPX Lacute Gcircumflex -15
+KPX Lacute Ccaron -10
+KPX Lacute Cdotaccent -10
+KPX Lacute Ccircumflex -10
+KPX Lacute Cacute -10
+KPX Lacute Aogonek 15
+KPX Lacute Amacron 15
+KPX Lacute ydieresis -55
+KPX Lacute udieresis -20
+KPX Lacute ucircumflex -20
+KPX Lacute Udieresis -25
+KPX Lacute Ucircumflex -25
+KPX Lacute Ccedilla -10
+KPX Lacute AE 20
+KPX Lacute Aring 15
+KPX Lacute Adieresis 15
+KPX Lacute y -55
+KPX Lacute u -20
+KPX Lacute Y -75
+KPX Lacute W -65
+KPX Lacute V -95
+KPX Lacute U -25
+KPX Lacute T -65
+KPX Lacute G -15
+KPX Lacute C -10
+KPX Lacute A 15
+KPX Lacute hyphen 20
+KPX lacute ycircumflex -20
+KPX lacute ydieresis -20
+KPX lacute y -20
+KPX lacute v -20
+KPX Lcommaaccent T_h -65
+KPX Lcommaaccent ydieresis.sc -65
+KPX Lcommaaccent udieresis.sc -20
+KPX Lcommaaccent ucircumflex.sc -20
+KPX Lcommaaccent ccedilla.sc -10
+KPX Lcommaaccent ae.sc 15
+KPX Lcommaaccent aring.sc 15
+KPX Lcommaaccent adieresis.sc 15
+KPX Lcommaaccent y.sc -65
+KPX Lcommaaccent w.sc -55
+KPX Lcommaaccent v.sc -80
+KPX Lcommaaccent u.sc -20
+KPX Lcommaaccent t.sc -55
+KPX Lcommaaccent g.sc -15
+KPX Lcommaaccent c.sc -10
+KPX Lcommaaccent a.sc 15
+KPX Lcommaaccent ycircumflex.sc -65
+KPX Lcommaaccent wgrave.sc -55
+KPX Lcommaaccent wdieresis.sc -55
+KPX Lcommaaccent wcircumflex.sc -55
+KPX Lcommaaccent wacute.sc -55
+KPX Lcommaaccent uring.sc -20
+KPX Lcommaaccent uogonek.sc -20
+KPX Lcommaaccent umacron.sc -20
+KPX Lcommaaccent uhungarumlaut.sc -20
+KPX Lcommaaccent ubreve.sc -20
+KPX Lcommaaccent uni021B.sc -55
+KPX Lcommaaccent tcaron.sc -55
+KPX Lcommaaccent gdotaccent.sc -15
+KPX Lcommaaccent gcommaaccent.sc -15
+KPX Lcommaaccent gcircumflex.sc -15
+KPX Lcommaaccent gbreve.sc -15
+KPX Lcommaaccent cdotaccent.sc -10
+KPX Lcommaaccent ccircumflex.sc -10
+KPX Lcommaaccent ccaron.sc -10
+KPX Lcommaaccent cacute.sc -10
+KPX Lcommaaccent aeacute.sc 15
+KPX Lcommaaccent aogonek.sc 15
+KPX Lcommaaccent amacron.sc 15
+KPX Lcommaaccent gcaron.sc -15
+KPX Lcommaaccent gacute.sc -15
+KPX Lcommaaccent quotedblright -80
+KPX Lcommaaccent quoteright -80
+KPX Lcommaaccent Wdieresis -65
+KPX Lcommaaccent Wacute -65
+KPX Lcommaaccent Wgrave -65
+KPX Lcommaaccent uni021A -65
+KPX Lcommaaccent AEacute 20
+KPX Lcommaaccent Gacute -15
+KPX Lcommaaccent Gcaron -15
+KPX Lcommaaccent Ydieresis -75
+KPX Lcommaaccent ycircumflex -55
+KPX Lcommaaccent Ycircumflex -75
+KPX Lcommaaccent Wcircumflex -65
+KPX Lcommaaccent uogonek -20
+KPX Lcommaaccent Uogonek -25
+KPX Lcommaaccent uhungarumlaut -20
+KPX Lcommaaccent Uhungarumlaut -25
+KPX Lcommaaccent uring -20
+KPX Lcommaaccent Uring -25
+KPX Lcommaaccent ubreve -20
+KPX Lcommaaccent Ubreve -25
+KPX Lcommaaccent umacron -20
+KPX Lcommaaccent Umacron -25
+KPX Lcommaaccent Tcaron -65
+KPX Lcommaaccent Gcommaaccent -15
+KPX Lcommaaccent Gdotaccent -15
+KPX Lcommaaccent Gbreve -15
+KPX Lcommaaccent Gcircumflex -15
+KPX Lcommaaccent Ccaron -10
+KPX Lcommaaccent Cdotaccent -10
+KPX Lcommaaccent Ccircumflex -10
+KPX Lcommaaccent Cacute -10
+KPX Lcommaaccent Aogonek 15
+KPX Lcommaaccent Amacron 15
+KPX Lcommaaccent ydieresis -55
+KPX Lcommaaccent udieresis -20
+KPX Lcommaaccent ucircumflex -20
+KPX Lcommaaccent Udieresis -25
+KPX Lcommaaccent Ucircumflex -25
+KPX Lcommaaccent Ccedilla -10
+KPX Lcommaaccent AE 20
+KPX Lcommaaccent Aring 15
+KPX Lcommaaccent Adieresis 15
+KPX Lcommaaccent y -55
+KPX Lcommaaccent u -20
+KPX Lcommaaccent Y -75
+KPX Lcommaaccent W -65
+KPX Lcommaaccent V -95
+KPX Lcommaaccent U -25
+KPX Lcommaaccent T -65
+KPX Lcommaaccent G -15
+KPX Lcommaaccent C -10
+KPX Lcommaaccent A 15
+KPX Lcommaaccent hyphen 20
+KPX lcommaaccent ycircumflex -20
+KPX lcommaaccent ydieresis -20
+KPX lcommaaccent y -20
+KPX lcommaaccent v -20
+KPX Lcaron T_h -35
+KPX Lcaron ydieresis.sc -30
+KPX Lcaron yacute.sc -30
+KPX Lcaron udieresis.sc -10
+KPX Lcaron ucircumflex.sc -10
+KPX Lcaron uacute.sc -10
+KPX Lcaron ugrave.sc -10
+KPX Lcaron ccedilla.sc -10
+KPX Lcaron ae.sc 15
+KPX Lcaron aring.sc 15
+KPX Lcaron adieresis.sc 15
+KPX Lcaron y.sc -30
+KPX Lcaron w.sc -25
+KPX Lcaron v.sc -40
+KPX Lcaron u.sc -10
+KPX Lcaron t.sc -25
+KPX Lcaron g.sc -15
+KPX Lcaron c.sc -10
+KPX Lcaron a.sc 15
+KPX Lcaron ygrave.sc -30
+KPX Lcaron ycircumflex.sc -30
+KPX Lcaron wgrave.sc -25
+KPX Lcaron wdieresis.sc -25
+KPX Lcaron wcircumflex.sc -25
+KPX Lcaron wacute.sc -25
+KPX Lcaron utilde.sc -10
+KPX Lcaron uring.sc -10
+KPX Lcaron uogonek.sc -10
+KPX Lcaron umacron.sc -10
+KPX Lcaron uhungarumlaut.sc -10
+KPX Lcaron ubreve.sc -10
+KPX Lcaron uni021B.sc -25
+KPX Lcaron tcaron.sc -25
+KPX Lcaron gdotaccent.sc -15
+KPX Lcaron gcommaaccent.sc -15
+KPX Lcaron gcircumflex.sc -15
+KPX Lcaron gbreve.sc -15
+KPX Lcaron cdotaccent.sc -10
+KPX Lcaron ccircumflex.sc -10
+KPX Lcaron ccaron.sc -10
+KPX Lcaron cacute.sc -10
+KPX Lcaron aeacute.sc 15
+KPX Lcaron aogonek.sc 15
+KPX Lcaron amacron.sc 15
+KPX Lcaron ytilde.sc -30
+KPX Lcaron yhookabove.sc -30
+KPX Lcaron ydotbelow.sc -30
+KPX Lcaron uhorntilde.sc -10
+KPX Lcaron uhornhookabove.sc -10
+KPX Lcaron uhorngrave.sc -10
+KPX Lcaron uhorndotbelow.sc -10
+KPX Lcaron uhornacute.sc -10
+KPX Lcaron uhookabove.sc -10
+KPX Lcaron udotbelow.sc -10
+KPX Lcaron gcaron.sc -15
+KPX Lcaron gacute.sc -15
+KPX Lcaron quotedblright -80
+KPX Lcaron quoteright -80
+KPX Lcaron Ytilde -40
+KPX Lcaron Yhookabove -40
+KPX Lcaron Ydotbelow -40
+KPX Lcaron Ygrave -40
+KPX Lcaron Uhorndotbelow -15
+KPX Lcaron Uhorntilde -15
+KPX Lcaron Uhornhookabove -15
+KPX Lcaron Uhorngrave -15
+KPX Lcaron Uhornacute -15
+KPX Lcaron Uhookabove -15
+KPX Lcaron Udotbelow -15
+KPX Lcaron Wdieresis -35
+KPX Lcaron Wacute -35
+KPX Lcaron Wgrave -35
+KPX Lcaron uni021A -35
+KPX Lcaron AEacute 20
+KPX Lcaron Gacute -15
+KPX Lcaron Gcaron -15
+KPX Lcaron Ydieresis -40
+KPX Lcaron ycircumflex -55
+KPX Lcaron Ycircumflex -40
+KPX Lcaron Wcircumflex -35
+KPX Lcaron uogonek -20
+KPX Lcaron Uogonek -15
+KPX Lcaron uhungarumlaut -20
+KPX Lcaron Uhungarumlaut -15
+KPX Lcaron uring -20
+KPX Lcaron Uring -15
+KPX Lcaron ubreve -20
+KPX Lcaron Ubreve -15
+KPX Lcaron umacron -20
+KPX Lcaron Umacron -15
+KPX Lcaron Utilde -15
+KPX Lcaron Tcaron -35
+KPX Lcaron Gcommaaccent -15
+KPX Lcaron Gdotaccent -15
+KPX Lcaron Gbreve -15
+KPX Lcaron Gcircumflex -15
+KPX Lcaron Ccaron -10
+KPX Lcaron Cdotaccent -10
+KPX Lcaron Ccircumflex -10
+KPX Lcaron Cacute -10
+KPX Lcaron Aogonek 15
+KPX Lcaron Amacron 15
+KPX Lcaron ydieresis -55
+KPX Lcaron udieresis -20
+KPX Lcaron ucircumflex -20
+KPX Lcaron Yacute -40
+KPX Lcaron Udieresis -15
+KPX Lcaron Ucircumflex -15
+KPX Lcaron Uacute -15
+KPX Lcaron Ugrave -15
+KPX Lcaron Ccedilla -10
+KPX Lcaron AE 20
+KPX Lcaron Aring 15
+KPX Lcaron Adieresis 15
+KPX Lcaron y -55
+KPX Lcaron u -20
+KPX Lcaron Y -40
+KPX Lcaron W -35
+KPX Lcaron V -50
+KPX Lcaron U -15
+KPX Lcaron T -35
+KPX Lcaron G -15
+KPX Lcaron C -10
+KPX Lcaron A 15
+KPX Lcaron hyphen 20
+KPX lcaron quotedblright 40
+KPX lcaron quotedblleft 40
+KPX lcaron quoteright 40
+KPX lcaron quoteleft 40
+KPX lcaron ycircumflex -20
+KPX lcaron lcaron 35
+KPX lcaron lcommaaccent 35
+KPX lcaron lacute 35
+KPX lcaron kcommaaccent 35
+KPX lcaron hcircumflex 35
+KPX lcaron ydieresis -20
+KPX lcaron thorn 35
+KPX lcaron y -20
+KPX lcaron v -20
+KPX lcaron l 35
+KPX lcaron k 35
+KPX lcaron h 35
+KPX lcaron b 35
+KPX lcaron backslash 40
+KPX Lslash T_h -50
+KPX Lslash ydieresis.sc -65
+KPX Lslash udieresis.sc -20
+KPX Lslash ucircumflex.sc -20
+KPX Lslash ccedilla.sc -10
+KPX Lslash ae.sc 15
+KPX Lslash aring.sc 15
+KPX Lslash adieresis.sc 15
+KPX Lslash y.sc -65
+KPX Lslash w.sc -55
+KPX Lslash v.sc -80
+KPX Lslash u.sc -20
+KPX Lslash t.sc -55
+KPX Lslash g.sc -15
+KPX Lslash c.sc -10
+KPX Lslash a.sc 15
+KPX Lslash ycircumflex.sc -65
+KPX Lslash wgrave.sc -55
+KPX Lslash wdieresis.sc -55
+KPX Lslash wcircumflex.sc -55
+KPX Lslash wacute.sc -55
+KPX Lslash uring.sc -20
+KPX Lslash uogonek.sc -20
+KPX Lslash umacron.sc -20
+KPX Lslash uhungarumlaut.sc -20
+KPX Lslash ubreve.sc -20
+KPX Lslash uni021B.sc -55
+KPX Lslash tcaron.sc -55
+KPX Lslash gdotaccent.sc -15
+KPX Lslash gcommaaccent.sc -15
+KPX Lslash gcircumflex.sc -15
+KPX Lslash gbreve.sc -15
+KPX Lslash cdotaccent.sc -10
+KPX Lslash ccircumflex.sc -10
+KPX Lslash ccaron.sc -10
+KPX Lslash cacute.sc -10
+KPX Lslash aeacute.sc 15
+KPX Lslash aogonek.sc 15
+KPX Lslash amacron.sc 15
+KPX Lslash gcaron.sc -15
+KPX Lslash gacute.sc -15
+KPX Lslash quotedblright -80
+KPX Lslash quoteright -80
+KPX Lslash Ytilde -60
+KPX Lslash Yhookabove -60
+KPX Lslash Ydotbelow -60
+KPX Lslash Ygrave -60
+KPX Lslash Uhorndotbelow -20
+KPX Lslash Uhorntilde -20
+KPX Lslash Uhornhookabove -20
+KPX Lslash Uhorngrave -20
+KPX Lslash Uhornacute -20
+KPX Lslash Uhookabove -20
+KPX Lslash Udotbelow -20
+KPX Lslash Wdieresis -50
+KPX Lslash Wacute -50
+KPX Lslash Wgrave -50
+KPX Lslash uni021A -50
+KPX Lslash AEacute 20
+KPX Lslash Gacute -15
+KPX Lslash Gcaron -15
+KPX Lslash Ydieresis -60
+KPX Lslash ycircumflex -55
+KPX Lslash Ycircumflex -60
+KPX Lslash Wcircumflex -50
+KPX Lslash uogonek -20
+KPX Lslash Uogonek -20
+KPX Lslash uhungarumlaut -20
+KPX Lslash Uhungarumlaut -20
+KPX Lslash uring -20
+KPX Lslash Uring -20
+KPX Lslash ubreve -20
+KPX Lslash Ubreve -20
+KPX Lslash umacron -20
+KPX Lslash Umacron -20
+KPX Lslash Utilde -20
+KPX Lslash Tcaron -50
+KPX Lslash Gcommaaccent -15
+KPX Lslash Gdotaccent -15
+KPX Lslash Gbreve -15
+KPX Lslash Gcircumflex -15
+KPX Lslash Ccaron -10
+KPX Lslash Cdotaccent -10
+KPX Lslash Ccircumflex -10
+KPX Lslash Cacute -10
+KPX Lslash Aogonek 15
+KPX Lslash Amacron 15
+KPX Lslash ydieresis -55
+KPX Lslash udieresis -20
+KPX Lslash ucircumflex -20
+KPX Lslash Yacute -60
+KPX Lslash Udieresis -20
+KPX Lslash Ucircumflex -20
+KPX Lslash Uacute -20
+KPX Lslash Ugrave -20
+KPX Lslash Ccedilla -10
+KPX Lslash AE 20
+KPX Lslash Aring 15
+KPX Lslash Adieresis 15
+KPX Lslash y -55
+KPX Lslash u -20
+KPX Lslash Y -60
+KPX Lslash W -50
+KPX Lslash V -75
+KPX Lslash U -20
+KPX Lslash T -50
+KPX Lslash G -15
+KPX Lslash C -10
+KPX Lslash A 15
+KPX Lslash hyphen 20
+KPX lslash ycircumflex -20
+KPX lslash ydieresis -20
+KPX lslash y -20
+KPX lslash v -20
+KPX Nacute oslash.sc -15
+KPX Nacute odieresis.sc -15
+KPX Nacute ccedilla.sc -15
+KPX Nacute ae.sc -15
+KPX Nacute aring.sc -20
+KPX Nacute adieresis.sc -20
+KPX Nacute o.sc -15
+KPX Nacute g.sc -20
+KPX Nacute c.sc -15
+KPX Nacute a.sc -20
+KPX Nacute omacron.sc -15
+KPX Nacute ohungarumlaut.sc -15
+KPX Nacute obreve.sc -15
+KPX Nacute gdotaccent.sc -20
+KPX Nacute gcommaaccent.sc -20
+KPX Nacute gcircumflex.sc -20
+KPX Nacute gbreve.sc -20
+KPX Nacute cdotaccent.sc -15
+KPX Nacute ccircumflex.sc -15
+KPX Nacute ccaron.sc -15
+KPX Nacute cacute.sc -15
+KPX Nacute aeacute.sc -15
+KPX Nacute aogonek.sc -20
+KPX Nacute amacron.sc -20
+KPX Nacute oogonek.sc -15
+KPX Nacute gcaron.sc -20
+KPX Nacute gacute.sc -20
+KPX Nacute aeacute -30
+KPX Nacute AEacute -20
+KPX Nacute Gacute -25
+KPX Nacute oogonek -20
+KPX Nacute Oogonek -20
+KPX Nacute Gcaron -25
+KPX Nacute uogonek -30
+KPX Nacute uhungarumlaut -30
+KPX Nacute uring -30
+KPX Nacute ubreve -30
+KPX Nacute umacron -30
+KPX Nacute ohungarumlaut -20
+KPX Nacute Ohungarumlaut -20
+KPX Nacute obreve -20
+KPX Nacute Obreve -20
+KPX Nacute omacron -20
+KPX Nacute Omacron -20
+KPX Nacute Gcommaaccent -25
+KPX Nacute Gdotaccent -25
+KPX Nacute Gbreve -25
+KPX Nacute Gcircumflex -25
+KPX Nacute ecaron -25
+KPX Nacute eogonek -25
+KPX Nacute edotaccent -25
+KPX Nacute ebreve -25
+KPX Nacute emacron -25
+KPX Nacute Ccaron -20
+KPX Nacute Cdotaccent -20
+KPX Nacute Ccircumflex -20
+KPX Nacute Cacute -20
+KPX Nacute aogonek -30
+KPX Nacute Aogonek -25
+KPX Nacute amacron -30
+KPX Nacute Amacron -25
+KPX Nacute udieresis -30
+KPX Nacute ucircumflex -30
+KPX Nacute oslash -20
+KPX Nacute odieresis -20
+KPX Nacute edieresis -25
+KPX Nacute ae -30
+KPX Nacute aring -30
+KPX Nacute adieresis -30
+KPX Nacute Oslash -20
+KPX Nacute Odieresis -20
+KPX Nacute Ccedilla -20
+KPX Nacute AE -20
+KPX Nacute Aring -25
+KPX Nacute Adieresis -25
+KPX Nacute u -30
+KPX Nacute o -20
+KPX Nacute e -25
+KPX Nacute a -30
+KPX Nacute O -20
+KPX Nacute G -25
+KPX Nacute C -20
+KPX Nacute A -25
+KPX Nacute comma -10
+KPX nacute T_h -60
+KPX nacute wdieresis -25
+KPX nacute wacute -25
+KPX nacute wgrave -25
+KPX nacute uni021A -60
+KPX nacute ycircumflex -25
+KPX nacute wcircumflex -25
+KPX nacute Tcaron -60
+KPX nacute ydieresis -25
+KPX nacute y -25
+KPX nacute w -25
+KPX nacute v -25
+KPX nacute p -20
+KPX nacute T -60
+KPX Ncommaaccent oslash.sc -15
+KPX Ncommaaccent odieresis.sc -15
+KPX Ncommaaccent ccedilla.sc -15
+KPX Ncommaaccent ae.sc -15
+KPX Ncommaaccent aring.sc -20
+KPX Ncommaaccent adieresis.sc -20
+KPX Ncommaaccent o.sc -15
+KPX Ncommaaccent g.sc -20
+KPX Ncommaaccent c.sc -15
+KPX Ncommaaccent a.sc -20
+KPX Ncommaaccent omacron.sc -15
+KPX Ncommaaccent ohungarumlaut.sc -15
+KPX Ncommaaccent obreve.sc -15
+KPX Ncommaaccent gdotaccent.sc -20
+KPX Ncommaaccent gcommaaccent.sc -20
+KPX Ncommaaccent gcircumflex.sc -20
+KPX Ncommaaccent gbreve.sc -20
+KPX Ncommaaccent cdotaccent.sc -15
+KPX Ncommaaccent ccircumflex.sc -15
+KPX Ncommaaccent ccaron.sc -15
+KPX Ncommaaccent cacute.sc -15
+KPX Ncommaaccent aeacute.sc -15
+KPX Ncommaaccent aogonek.sc -20
+KPX Ncommaaccent amacron.sc -20
+KPX Ncommaaccent oogonek.sc -15
+KPX Ncommaaccent gcaron.sc -20
+KPX Ncommaaccent gacute.sc -20
+KPX Ncommaaccent aeacute -30
+KPX Ncommaaccent AEacute -20
+KPX Ncommaaccent Gacute -25
+KPX Ncommaaccent oogonek -20
+KPX Ncommaaccent Oogonek -20
+KPX Ncommaaccent Gcaron -25
+KPX Ncommaaccent uogonek -30
+KPX Ncommaaccent uhungarumlaut -30
+KPX Ncommaaccent uring -30
+KPX Ncommaaccent ubreve -30
+KPX Ncommaaccent umacron -30
+KPX Ncommaaccent ohungarumlaut -20
+KPX Ncommaaccent Ohungarumlaut -20
+KPX Ncommaaccent obreve -20
+KPX Ncommaaccent Obreve -20
+KPX Ncommaaccent omacron -20
+KPX Ncommaaccent Omacron -20
+KPX Ncommaaccent Gcommaaccent -25
+KPX Ncommaaccent Gdotaccent -25
+KPX Ncommaaccent Gbreve -25
+KPX Ncommaaccent Gcircumflex -25
+KPX Ncommaaccent ecaron -25
+KPX Ncommaaccent eogonek -25
+KPX Ncommaaccent edotaccent -25
+KPX Ncommaaccent ebreve -25
+KPX Ncommaaccent emacron -25
+KPX Ncommaaccent Ccaron -20
+KPX Ncommaaccent Cdotaccent -20
+KPX Ncommaaccent Ccircumflex -20
+KPX Ncommaaccent Cacute -20
+KPX Ncommaaccent aogonek -30
+KPX Ncommaaccent Aogonek -25
+KPX Ncommaaccent amacron -30
+KPX Ncommaaccent Amacron -25
+KPX Ncommaaccent udieresis -30
+KPX Ncommaaccent ucircumflex -30
+KPX Ncommaaccent oslash -20
+KPX Ncommaaccent odieresis -20
+KPX Ncommaaccent edieresis -25
+KPX Ncommaaccent ae -30
+KPX Ncommaaccent aring -30
+KPX Ncommaaccent adieresis -30
+KPX Ncommaaccent Oslash -20
+KPX Ncommaaccent Odieresis -20
+KPX Ncommaaccent Ccedilla -20
+KPX Ncommaaccent AE -20
+KPX Ncommaaccent Aring -25
+KPX Ncommaaccent Adieresis -25
+KPX Ncommaaccent u -30
+KPX Ncommaaccent o -20
+KPX Ncommaaccent e -25
+KPX Ncommaaccent a -30
+KPX Ncommaaccent O -20
+KPX Ncommaaccent G -25
+KPX Ncommaaccent C -20
+KPX Ncommaaccent A -25
+KPX Ncommaaccent comma -10
+KPX ncommaaccent T_h -60
+KPX ncommaaccent wdieresis -25
+KPX ncommaaccent wacute -25
+KPX ncommaaccent wgrave -25
+KPX ncommaaccent uni021A -60
+KPX ncommaaccent ycircumflex -25
+KPX ncommaaccent wcircumflex -25
+KPX ncommaaccent Tcaron -60
+KPX ncommaaccent ydieresis -25
+KPX ncommaaccent y -25
+KPX ncommaaccent w -25
+KPX ncommaaccent v -25
+KPX ncommaaccent p -20
+KPX ncommaaccent T -60
+KPX Ncaron oslash.sc -15
+KPX Ncaron odieresis.sc -15
+KPX Ncaron ccedilla.sc -15
+KPX Ncaron ae.sc -15
+KPX Ncaron aring.sc -20
+KPX Ncaron adieresis.sc -20
+KPX Ncaron o.sc -15
+KPX Ncaron g.sc -20
+KPX Ncaron c.sc -15
+KPX Ncaron a.sc -20
+KPX Ncaron omacron.sc -15
+KPX Ncaron ohungarumlaut.sc -15
+KPX Ncaron obreve.sc -15
+KPX Ncaron gdotaccent.sc -20
+KPX Ncaron gcommaaccent.sc -20
+KPX Ncaron gcircumflex.sc -20
+KPX Ncaron gbreve.sc -20
+KPX Ncaron cdotaccent.sc -15
+KPX Ncaron ccircumflex.sc -15
+KPX Ncaron ccaron.sc -15
+KPX Ncaron cacute.sc -15
+KPX Ncaron aeacute.sc -15
+KPX Ncaron aogonek.sc -20
+KPX Ncaron amacron.sc -20
+KPX Ncaron oogonek.sc -15
+KPX Ncaron gcaron.sc -20
+KPX Ncaron gacute.sc -20
+KPX Ncaron aeacute -30
+KPX Ncaron AEacute -20
+KPX Ncaron Gacute -25
+KPX Ncaron oogonek -20
+KPX Ncaron Oogonek -20
+KPX Ncaron Gcaron -25
+KPX Ncaron uogonek -30
+KPX Ncaron uhungarumlaut -30
+KPX Ncaron uring -30
+KPX Ncaron ubreve -30
+KPX Ncaron umacron -30
+KPX Ncaron ohungarumlaut -20
+KPX Ncaron Ohungarumlaut -20
+KPX Ncaron obreve -20
+KPX Ncaron Obreve -20
+KPX Ncaron omacron -20
+KPX Ncaron Omacron -20
+KPX Ncaron Gcommaaccent -25
+KPX Ncaron Gdotaccent -25
+KPX Ncaron Gbreve -25
+KPX Ncaron Gcircumflex -25
+KPX Ncaron ecaron -25
+KPX Ncaron eogonek -25
+KPX Ncaron edotaccent -25
+KPX Ncaron ebreve -25
+KPX Ncaron emacron -25
+KPX Ncaron Ccaron -20
+KPX Ncaron Cdotaccent -20
+KPX Ncaron Ccircumflex -20
+KPX Ncaron Cacute -20
+KPX Ncaron aogonek -30
+KPX Ncaron Aogonek -25
+KPX Ncaron amacron -30
+KPX Ncaron Amacron -25
+KPX Ncaron udieresis -30
+KPX Ncaron ucircumflex -30
+KPX Ncaron oslash -20
+KPX Ncaron odieresis -20
+KPX Ncaron edieresis -25
+KPX Ncaron ae -30
+KPX Ncaron aring -30
+KPX Ncaron adieresis -30
+KPX Ncaron Oslash -20
+KPX Ncaron Odieresis -20
+KPX Ncaron Ccedilla -20
+KPX Ncaron AE -20
+KPX Ncaron Aring -25
+KPX Ncaron Adieresis -25
+KPX Ncaron u -30
+KPX Ncaron o -20
+KPX Ncaron e -25
+KPX Ncaron a -30
+KPX Ncaron O -20
+KPX Ncaron G -25
+KPX Ncaron C -20
+KPX Ncaron A -25
+KPX Ncaron comma -10
+KPX ncaron T_h -60
+KPX ncaron wdieresis -25
+KPX ncaron wacute -25
+KPX ncaron wgrave -25
+KPX ncaron uni021A -60
+KPX ncaron ycircumflex -25
+KPX ncaron wcircumflex -25
+KPX ncaron Tcaron -60
+KPX ncaron ydieresis -25
+KPX ncaron y -25
+KPX ncaron w -25
+KPX ncaron v -25
+KPX ncaron p -20
+KPX ncaron T -60
+KPX Omacron ydieresis.sc -30
+KPX Omacron ae.sc -45
+KPX Omacron aring.sc -40
+KPX Omacron adieresis.sc -40
+KPX Omacron y.sc -30
+KPX Omacron x.sc -35
+KPX Omacron w.sc -25
+KPX Omacron v.sc -40
+KPX Omacron a.sc -40
+KPX Omacron ycircumflex.sc -30
+KPX Omacron wgrave.sc -25
+KPX Omacron wdieresis.sc -25
+KPX Omacron wcircumflex.sc -25
+KPX Omacron wacute.sc -25
+KPX Omacron aeacute.sc -45
+KPX Omacron aogonek.sc -40
+KPX Omacron amacron.sc -40
+KPX Omacron Wdieresis -30
+KPX Omacron Wacute -30
+KPX Omacron Wgrave -30
+KPX Omacron AEacute -55
+KPX Omacron Ydieresis -35
+KPX Omacron Ycircumflex -35
+KPX Omacron Wcircumflex -30
+KPX Omacron Aogonek -50
+KPX Omacron Amacron -50
+KPX Omacron AE -55
+KPX Omacron Aring -50
+KPX Omacron Adieresis -50
+KPX Omacron Y -35
+KPX Omacron X -40
+KPX Omacron W -30
+KPX Omacron V -50
+KPX Omacron A -50
+KPX omacron T_h -90
+KPX omacron wdieresis -20
+KPX omacron wacute -20
+KPX omacron wgrave -20
+KPX omacron uni021A -90
+KPX omacron ycircumflex -20
+KPX omacron wcircumflex -20
+KPX omacron Tcaron -90
+KPX omacron ydieresis -20
+KPX omacron y -20
+KPX omacron x -15
+KPX omacron w -20
+KPX omacron v -15
+KPX omacron T -90
+KPX Obreve ydieresis.sc -30
+KPX Obreve ae.sc -45
+KPX Obreve aring.sc -40
+KPX Obreve adieresis.sc -40
+KPX Obreve y.sc -30
+KPX Obreve x.sc -35
+KPX Obreve w.sc -25
+KPX Obreve v.sc -40
+KPX Obreve a.sc -40
+KPX Obreve ycircumflex.sc -30
+KPX Obreve wgrave.sc -25
+KPX Obreve wdieresis.sc -25
+KPX Obreve wcircumflex.sc -25
+KPX Obreve wacute.sc -25
+KPX Obreve aeacute.sc -45
+KPX Obreve aogonek.sc -40
+KPX Obreve amacron.sc -40
+KPX Obreve Wdieresis -30
+KPX Obreve Wacute -30
+KPX Obreve Wgrave -30
+KPX Obreve AEacute -55
+KPX Obreve Ydieresis -35
+KPX Obreve Ycircumflex -35
+KPX Obreve Wcircumflex -30
+KPX Obreve Aogonek -50
+KPX Obreve Amacron -50
+KPX Obreve AE -55
+KPX Obreve Aring -50
+KPX Obreve Adieresis -50
+KPX Obreve Y -35
+KPX Obreve X -40
+KPX Obreve W -30
+KPX Obreve V -50
+KPX Obreve A -50
+KPX obreve T_h -90
+KPX obreve wdieresis -20
+KPX obreve wacute -20
+KPX obreve wgrave -20
+KPX obreve uni021A -90
+KPX obreve ycircumflex -20
+KPX obreve wcircumflex -20
+KPX obreve Tcaron -90
+KPX obreve ydieresis -20
+KPX obreve y -20
+KPX obreve x -15
+KPX obreve w -20
+KPX obreve v -15
+KPX obreve T -90
+KPX Ohungarumlaut ydieresis.sc -30
+KPX Ohungarumlaut ae.sc -45
+KPX Ohungarumlaut aring.sc -40
+KPX Ohungarumlaut adieresis.sc -40
+KPX Ohungarumlaut y.sc -30
+KPX Ohungarumlaut x.sc -35
+KPX Ohungarumlaut w.sc -25
+KPX Ohungarumlaut v.sc -40
+KPX Ohungarumlaut a.sc -40
+KPX Ohungarumlaut ycircumflex.sc -30
+KPX Ohungarumlaut wgrave.sc -25
+KPX Ohungarumlaut wdieresis.sc -25
+KPX Ohungarumlaut wcircumflex.sc -25
+KPX Ohungarumlaut wacute.sc -25
+KPX Ohungarumlaut aeacute.sc -45
+KPX Ohungarumlaut aogonek.sc -40
+KPX Ohungarumlaut amacron.sc -40
+KPX Ohungarumlaut Wdieresis -30
+KPX Ohungarumlaut Wacute -30
+KPX Ohungarumlaut Wgrave -30
+KPX Ohungarumlaut AEacute -55
+KPX Ohungarumlaut Ydieresis -35
+KPX Ohungarumlaut Ycircumflex -35
+KPX Ohungarumlaut Wcircumflex -30
+KPX Ohungarumlaut Aogonek -50
+KPX Ohungarumlaut Amacron -50
+KPX Ohungarumlaut AE -55
+KPX Ohungarumlaut Aring -50
+KPX Ohungarumlaut Adieresis -50
+KPX Ohungarumlaut Y -35
+KPX Ohungarumlaut X -40
+KPX Ohungarumlaut W -30
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut A -50
+KPX ohungarumlaut T_h -90
+KPX ohungarumlaut wdieresis -20
+KPX ohungarumlaut wacute -20
+KPX ohungarumlaut wgrave -20
+KPX ohungarumlaut uni021A -90
+KPX ohungarumlaut ycircumflex -20
+KPX ohungarumlaut wcircumflex -20
+KPX ohungarumlaut Tcaron -90
+KPX ohungarumlaut ydieresis -20
+KPX ohungarumlaut y -20
+KPX ohungarumlaut x -15
+KPX ohungarumlaut w -20
+KPX ohungarumlaut v -15
+KPX ohungarumlaut T -90
+KPX Racute T_h -25
+KPX Racute ydieresis.sc -25
+KPX Racute udieresis.sc -35
+KPX Racute ucircumflex.sc -35
+KPX Racute oslash.sc -30
+KPX Racute odieresis.sc -30
+KPX Racute ccedilla.sc -30
+KPX Racute y.sc -25
+KPX Racute w.sc -35
+KPX Racute v.sc -35
+KPX Racute u.sc -35
+KPX Racute t.sc -20
+KPX Racute o.sc -30
+KPX Racute g.sc -30
+KPX Racute c.sc -30
+KPX Racute ycircumflex.sc -25
+KPX Racute wgrave.sc -35
+KPX Racute wdieresis.sc -35
+KPX Racute wcircumflex.sc -35
+KPX Racute wacute.sc -35
+KPX Racute uring.sc -35
+KPX Racute uogonek.sc -35
+KPX Racute umacron.sc -35
+KPX Racute uhungarumlaut.sc -35
+KPX Racute ubreve.sc -35
+KPX Racute uni021B.sc -20
+KPX Racute tcaron.sc -20
+KPX Racute omacron.sc -30
+KPX Racute ohungarumlaut.sc -30
+KPX Racute obreve.sc -30
+KPX Racute gdotaccent.sc -30
+KPX Racute gcommaaccent.sc -30
+KPX Racute gcircumflex.sc -30
+KPX Racute gbreve.sc -30
+KPX Racute cdotaccent.sc -30
+KPX Racute ccircumflex.sc -30
+KPX Racute ccaron.sc -30
+KPX Racute cacute.sc -30
+KPX Racute oogonek.sc -30
+KPX Racute oe.sc -25
+KPX Racute gcaron.sc -30
+KPX Racute gacute.sc -30
+KPX Racute Wdieresis -40
+KPX Racute Wacute -40
+KPX Racute Wgrave -40
+KPX Racute uni021A -25
+KPX Racute Gacute -35
+KPX Racute oogonek -10
+KPX Racute Oogonek -35
+KPX Racute Gcaron -35
+KPX Racute Ydieresis -30
+KPX Racute ycircumflex -25
+KPX Racute Ycircumflex -30
+KPX Racute Wcircumflex -40
+KPX Racute uogonek -20
+KPX Racute Uogonek -40
+KPX Racute uhungarumlaut -20
+KPX Racute Uhungarumlaut -40
+KPX Racute uring -20
+KPX Racute Uring -40
+KPX Racute ubreve -20
+KPX Racute Ubreve -40
+KPX Racute umacron -20
+KPX Racute Umacron -40
+KPX Racute Tcaron -25
+KPX Racute oe -15
+KPX Racute OE -30
+KPX Racute ohungarumlaut -10
+KPX Racute Ohungarumlaut -35
+KPX Racute obreve -10
+KPX Racute Obreve -35
+KPX Racute omacron -10
+KPX Racute Omacron -35
+KPX Racute Gcommaaccent -35
+KPX Racute Gdotaccent -35
+KPX Racute Gbreve -35
+KPX Racute Gcircumflex -35
+KPX Racute ecaron -10
+KPX Racute eogonek -10
+KPX Racute edotaccent -10
+KPX Racute ebreve -10
+KPX Racute emacron -10
+KPX Racute Ccaron -35
+KPX Racute Cdotaccent -35
+KPX Racute Ccircumflex -35
+KPX Racute Cacute -35
+KPX Racute aogonek 10
+KPX Racute amacron 10
+KPX Racute ydieresis -25
+KPX Racute udieresis -20
+KPX Racute ucircumflex -20
+KPX Racute oslash -10
+KPX Racute odieresis -10
+KPX Racute edieresis -10
+KPX Racute aring 10
+KPX Racute adieresis 10
+KPX Racute Udieresis -40
+KPX Racute Ucircumflex -40
+KPX Racute Oslash -35
+KPX Racute Odieresis -35
+KPX Racute Ccedilla -35
+KPX Racute y -25
+KPX Racute u -20
+KPX Racute o -10
+KPX Racute e -10
+KPX Racute a 10
+KPX Racute Y -30
+KPX Racute W -40
+KPX Racute V -40
+KPX Racute U -40
+KPX Racute T -25
+KPX Racute O -35
+KPX Racute G -35
+KPX Racute C -35
+KPX Racute hyphen -20
+KPX racute ffl 20
+KPX racute ffi 20
+KPX racute fl 20
+KPX racute fi 20
+KPX racute ff 20
+KPX racute jacute 20
+KPX racute f_k 20
+KPX racute quoteright 45
+KPX racute wdieresis 30
+KPX racute wacute 30
+KPX racute wgrave 30
+KPX racute rdotaccent 25
+KPX racute uni021B 25
+KPX racute uni0219 15
+KPX racute gacute 10
+KPX racute gcaron 10
+KPX racute ycircumflex 35
+KPX racute wcircumflex 30
+KPX racute uogonek 25
+KPX racute uhungarumlaut 25
+KPX racute uring 25
+KPX racute ubreve 25
+KPX racute umacron 25
+KPX racute tcaron 25
+KPX racute scaron 15
+KPX racute scedilla 15
+KPX racute scircumflex 15
+KPX racute sacute 15
+KPX racute rcaron 25
+KPX racute rcommaaccent 25
+KPX racute racute 25
+KPX racute ncaron 25
+KPX racute ncommaaccent 25
+KPX racute nacute 25
+KPX racute lslash -10
+KPX racute lcaron -10
+KPX racute lcommaaccent -10
+KPX racute lacute -10
+KPX racute jcircumflex 20
+KPX racute iogonek 20
+KPX racute ibreve 20
+KPX racute imacron 20
+KPX racute gcommaaccent 10
+KPX racute gdotaccent 10
+KPX racute gbreve 10
+KPX racute gcircumflex 10
+KPX racute ydieresis 35
+KPX racute udieresis 25
+KPX racute ucircumflex 25
+KPX racute ntilde 25
+KPX racute idieresis 20
+KPX racute icircumflex 20
+KPX racute y 35
+KPX racute x 30
+KPX racute w 30
+KPX racute v 35
+KPX racute u 25
+KPX racute t 25
+KPX racute s 15
+KPX racute r 25
+KPX racute p 25
+KPX racute n 25
+KPX racute m 25
+KPX racute l -10
+KPX racute j 20
+KPX racute i 20
+KPX racute g 10
+KPX racute f 20
+KPX racute colon 15
+KPX racute period -20
+KPX racute hyphen 20
+KPX racute comma -25
+KPX Rcommaaccent T_h -25
+KPX Rcommaaccent ydieresis.sc -25
+KPX Rcommaaccent udieresis.sc -35
+KPX Rcommaaccent ucircumflex.sc -35
+KPX Rcommaaccent oslash.sc -30
+KPX Rcommaaccent odieresis.sc -30
+KPX Rcommaaccent ccedilla.sc -30
+KPX Rcommaaccent y.sc -25
+KPX Rcommaaccent w.sc -35
+KPX Rcommaaccent v.sc -35
+KPX Rcommaaccent u.sc -35
+KPX Rcommaaccent t.sc -20
+KPX Rcommaaccent o.sc -30
+KPX Rcommaaccent g.sc -30
+KPX Rcommaaccent c.sc -30
+KPX Rcommaaccent ycircumflex.sc -25
+KPX Rcommaaccent wgrave.sc -35
+KPX Rcommaaccent wdieresis.sc -35
+KPX Rcommaaccent wcircumflex.sc -35
+KPX Rcommaaccent wacute.sc -35
+KPX Rcommaaccent uring.sc -35
+KPX Rcommaaccent uogonek.sc -35
+KPX Rcommaaccent umacron.sc -35
+KPX Rcommaaccent uhungarumlaut.sc -35
+KPX Rcommaaccent ubreve.sc -35
+KPX Rcommaaccent uni021B.sc -20
+KPX Rcommaaccent tcaron.sc -20
+KPX Rcommaaccent omacron.sc -30
+KPX Rcommaaccent ohungarumlaut.sc -30
+KPX Rcommaaccent obreve.sc -30
+KPX Rcommaaccent gdotaccent.sc -30
+KPX Rcommaaccent gcommaaccent.sc -30
+KPX Rcommaaccent gcircumflex.sc -30
+KPX Rcommaaccent gbreve.sc -30
+KPX Rcommaaccent cdotaccent.sc -30
+KPX Rcommaaccent ccircumflex.sc -30
+KPX Rcommaaccent ccaron.sc -30
+KPX Rcommaaccent cacute.sc -30
+KPX Rcommaaccent oogonek.sc -30
+KPX Rcommaaccent oe.sc -25
+KPX Rcommaaccent gcaron.sc -30
+KPX Rcommaaccent gacute.sc -30
+KPX Rcommaaccent Wdieresis -40
+KPX Rcommaaccent Wacute -40
+KPX Rcommaaccent Wgrave -40
+KPX Rcommaaccent uni021A -25
+KPX Rcommaaccent Gacute -35
+KPX Rcommaaccent oogonek -10
+KPX Rcommaaccent Oogonek -35
+KPX Rcommaaccent Gcaron -35
+KPX Rcommaaccent Ydieresis -30
+KPX Rcommaaccent ycircumflex -25
+KPX Rcommaaccent Ycircumflex -30
+KPX Rcommaaccent Wcircumflex -40
+KPX Rcommaaccent uogonek -20
+KPX Rcommaaccent Uogonek -40
+KPX Rcommaaccent uhungarumlaut -20
+KPX Rcommaaccent Uhungarumlaut -40
+KPX Rcommaaccent uring -20
+KPX Rcommaaccent Uring -40
+KPX Rcommaaccent ubreve -20
+KPX Rcommaaccent Ubreve -40
+KPX Rcommaaccent umacron -20
+KPX Rcommaaccent Umacron -40
+KPX Rcommaaccent Tcaron -25
+KPX Rcommaaccent oe -15
+KPX Rcommaaccent OE -30
+KPX Rcommaaccent ohungarumlaut -10
+KPX Rcommaaccent Ohungarumlaut -35
+KPX Rcommaaccent obreve -10
+KPX Rcommaaccent Obreve -35
+KPX Rcommaaccent omacron -10
+KPX Rcommaaccent Omacron -35
+KPX Rcommaaccent Gcommaaccent -35
+KPX Rcommaaccent Gdotaccent -35
+KPX Rcommaaccent Gbreve -35
+KPX Rcommaaccent Gcircumflex -35
+KPX Rcommaaccent ecaron -10
+KPX Rcommaaccent eogonek -10
+KPX Rcommaaccent edotaccent -10
+KPX Rcommaaccent ebreve -10
+KPX Rcommaaccent emacron -10
+KPX Rcommaaccent Ccaron -35
+KPX Rcommaaccent Cdotaccent -35
+KPX Rcommaaccent Ccircumflex -35
+KPX Rcommaaccent Cacute -35
+KPX Rcommaaccent aogonek 10
+KPX Rcommaaccent amacron 10
+KPX Rcommaaccent ydieresis -25
+KPX Rcommaaccent udieresis -20
+KPX Rcommaaccent ucircumflex -20
+KPX Rcommaaccent oslash -10
+KPX Rcommaaccent odieresis -10
+KPX Rcommaaccent edieresis -10
+KPX Rcommaaccent aring 10
+KPX Rcommaaccent adieresis 10
+KPX Rcommaaccent Udieresis -40
+KPX Rcommaaccent Ucircumflex -40
+KPX Rcommaaccent Oslash -35
+KPX Rcommaaccent Odieresis -35
+KPX Rcommaaccent Ccedilla -35
+KPX Rcommaaccent y -25
+KPX Rcommaaccent u -20
+KPX Rcommaaccent o -10
+KPX Rcommaaccent e -10
+KPX Rcommaaccent a 10
+KPX Rcommaaccent Y -30
+KPX Rcommaaccent W -40
+KPX Rcommaaccent V -40
+KPX Rcommaaccent U -40
+KPX Rcommaaccent T -25
+KPX Rcommaaccent O -35
+KPX Rcommaaccent G -35
+KPX Rcommaaccent C -35
+KPX Rcommaaccent hyphen -20
+KPX rcommaaccent ffl 20
+KPX rcommaaccent ffi 20
+KPX rcommaaccent fl 20
+KPX rcommaaccent fi 20
+KPX rcommaaccent ff 20
+KPX rcommaaccent jacute 20
+KPX rcommaaccent f_k 20
+KPX rcommaaccent quoteright 45
+KPX rcommaaccent wdieresis 30
+KPX rcommaaccent wacute 30
+KPX rcommaaccent wgrave 30
+KPX rcommaaccent rdotaccent 25
+KPX rcommaaccent uni021B 25
+KPX rcommaaccent uni0219 15
+KPX rcommaaccent gacute 10
+KPX rcommaaccent gcaron 10
+KPX rcommaaccent ycircumflex 35
+KPX rcommaaccent wcircumflex 30
+KPX rcommaaccent uogonek 25
+KPX rcommaaccent uhungarumlaut 25
+KPX rcommaaccent uring 25
+KPX rcommaaccent ubreve 25
+KPX rcommaaccent umacron 25
+KPX rcommaaccent tcaron 25
+KPX rcommaaccent scaron 15
+KPX rcommaaccent scedilla 15
+KPX rcommaaccent scircumflex 15
+KPX rcommaaccent sacute 15
+KPX rcommaaccent rcaron 25
+KPX rcommaaccent rcommaaccent 25
+KPX rcommaaccent racute 25
+KPX rcommaaccent ncaron 25
+KPX rcommaaccent ncommaaccent 25
+KPX rcommaaccent nacute 25
+KPX rcommaaccent lslash -10
+KPX rcommaaccent lcaron -10
+KPX rcommaaccent lcommaaccent -10
+KPX rcommaaccent lacute -10
+KPX rcommaaccent jcircumflex 20
+KPX rcommaaccent iogonek 20
+KPX rcommaaccent ibreve 20
+KPX rcommaaccent imacron 20
+KPX rcommaaccent gcommaaccent 10
+KPX rcommaaccent gdotaccent 10
+KPX rcommaaccent gbreve 10
+KPX rcommaaccent gcircumflex 10
+KPX rcommaaccent ydieresis 35
+KPX rcommaaccent udieresis 25
+KPX rcommaaccent ucircumflex 25
+KPX rcommaaccent ntilde 25
+KPX rcommaaccent idieresis 20
+KPX rcommaaccent icircumflex 20
+KPX rcommaaccent y 35
+KPX rcommaaccent x 30
+KPX rcommaaccent w 30
+KPX rcommaaccent v 35
+KPX rcommaaccent u 25
+KPX rcommaaccent t 25
+KPX rcommaaccent s 15
+KPX rcommaaccent r 25
+KPX rcommaaccent p 25
+KPX rcommaaccent n 25
+KPX rcommaaccent m 25
+KPX rcommaaccent l -10
+KPX rcommaaccent j 20
+KPX rcommaaccent i 20
+KPX rcommaaccent g 10
+KPX rcommaaccent f 20
+KPX rcommaaccent colon 15
+KPX rcommaaccent period -20
+KPX rcommaaccent hyphen 20
+KPX rcommaaccent comma -25
+KPX Rcaron T_h -25
+KPX Rcaron ydieresis.sc -25
+KPX Rcaron udieresis.sc -35
+KPX Rcaron ucircumflex.sc -35
+KPX Rcaron oslash.sc -30
+KPX Rcaron odieresis.sc -30
+KPX Rcaron ccedilla.sc -30
+KPX Rcaron y.sc -25
+KPX Rcaron w.sc -35
+KPX Rcaron v.sc -35
+KPX Rcaron u.sc -35
+KPX Rcaron t.sc -20
+KPX Rcaron o.sc -30
+KPX Rcaron g.sc -30
+KPX Rcaron c.sc -30
+KPX Rcaron ycircumflex.sc -25
+KPX Rcaron wgrave.sc -35
+KPX Rcaron wdieresis.sc -35
+KPX Rcaron wcircumflex.sc -35
+KPX Rcaron wacute.sc -35
+KPX Rcaron uring.sc -35
+KPX Rcaron uogonek.sc -35
+KPX Rcaron umacron.sc -35
+KPX Rcaron uhungarumlaut.sc -35
+KPX Rcaron ubreve.sc -35
+KPX Rcaron uni021B.sc -20
+KPX Rcaron tcaron.sc -20
+KPX Rcaron omacron.sc -30
+KPX Rcaron ohungarumlaut.sc -30
+KPX Rcaron obreve.sc -30
+KPX Rcaron gdotaccent.sc -30
+KPX Rcaron gcommaaccent.sc -30
+KPX Rcaron gcircumflex.sc -30
+KPX Rcaron gbreve.sc -30
+KPX Rcaron cdotaccent.sc -30
+KPX Rcaron ccircumflex.sc -30
+KPX Rcaron ccaron.sc -30
+KPX Rcaron cacute.sc -30
+KPX Rcaron oogonek.sc -30
+KPX Rcaron oe.sc -25
+KPX Rcaron gcaron.sc -30
+KPX Rcaron gacute.sc -30
+KPX Rcaron Wdieresis -40
+KPX Rcaron Wacute -40
+KPX Rcaron Wgrave -40
+KPX Rcaron uni021A -25
+KPX Rcaron Gacute -35
+KPX Rcaron oogonek -10
+KPX Rcaron Oogonek -35
+KPX Rcaron Gcaron -35
+KPX Rcaron Ydieresis -30
+KPX Rcaron ycircumflex -25
+KPX Rcaron Ycircumflex -30
+KPX Rcaron Wcircumflex -40
+KPX Rcaron uogonek -20
+KPX Rcaron Uogonek -40
+KPX Rcaron uhungarumlaut -20
+KPX Rcaron Uhungarumlaut -40
+KPX Rcaron uring -20
+KPX Rcaron Uring -40
+KPX Rcaron ubreve -20
+KPX Rcaron Ubreve -40
+KPX Rcaron umacron -20
+KPX Rcaron Umacron -40
+KPX Rcaron Tcaron -25
+KPX Rcaron oe -15
+KPX Rcaron OE -30
+KPX Rcaron ohungarumlaut -10
+KPX Rcaron Ohungarumlaut -35
+KPX Rcaron obreve -10
+KPX Rcaron Obreve -35
+KPX Rcaron omacron -10
+KPX Rcaron Omacron -35
+KPX Rcaron Gcommaaccent -35
+KPX Rcaron Gdotaccent -35
+KPX Rcaron Gbreve -35
+KPX Rcaron Gcircumflex -35
+KPX Rcaron ecaron -10
+KPX Rcaron eogonek -10
+KPX Rcaron edotaccent -10
+KPX Rcaron ebreve -10
+KPX Rcaron emacron -10
+KPX Rcaron Ccaron -35
+KPX Rcaron Cdotaccent -35
+KPX Rcaron Ccircumflex -35
+KPX Rcaron Cacute -35
+KPX Rcaron aogonek 10
+KPX Rcaron amacron 10
+KPX Rcaron ydieresis -25
+KPX Rcaron udieresis -20
+KPX Rcaron ucircumflex -20
+KPX Rcaron oslash -10
+KPX Rcaron odieresis -10
+KPX Rcaron edieresis -10
+KPX Rcaron aring 10
+KPX Rcaron adieresis 10
+KPX Rcaron Udieresis -40
+KPX Rcaron Ucircumflex -40
+KPX Rcaron Oslash -35
+KPX Rcaron Odieresis -35
+KPX Rcaron Ccedilla -35
+KPX Rcaron y -25
+KPX Rcaron u -20
+KPX Rcaron o -10
+KPX Rcaron e -10
+KPX Rcaron a 10
+KPX Rcaron Y -30
+KPX Rcaron W -40
+KPX Rcaron V -40
+KPX Rcaron U -40
+KPX Rcaron T -25
+KPX Rcaron O -35
+KPX Rcaron G -35
+KPX Rcaron C -35
+KPX Rcaron hyphen -20
+KPX rcaron ffl 20
+KPX rcaron ffi 20
+KPX rcaron fl 20
+KPX rcaron fi 20
+KPX rcaron ff 20
+KPX rcaron jacute 20
+KPX rcaron f_k 20
+KPX rcaron quoteright 45
+KPX rcaron wdieresis 30
+KPX rcaron wacute 30
+KPX rcaron wgrave 30
+KPX rcaron rdotaccent 25
+KPX rcaron uni021B 25
+KPX rcaron uni0219 15
+KPX rcaron gacute 10
+KPX rcaron gcaron 10
+KPX rcaron ycircumflex 35
+KPX rcaron wcircumflex 30
+KPX rcaron uogonek 25
+KPX rcaron uhungarumlaut 25
+KPX rcaron uring 25
+KPX rcaron ubreve 25
+KPX rcaron umacron 25
+KPX rcaron tcaron 25
+KPX rcaron scaron 15
+KPX rcaron scedilla 15
+KPX rcaron scircumflex 15
+KPX rcaron sacute 15
+KPX rcaron rcaron 25
+KPX rcaron rcommaaccent 25
+KPX rcaron racute 25
+KPX rcaron ncaron 25
+KPX rcaron ncommaaccent 25
+KPX rcaron nacute 25
+KPX rcaron lslash -10
+KPX rcaron lcaron -10
+KPX rcaron lcommaaccent -10
+KPX rcaron lacute -10
+KPX rcaron jcircumflex 20
+KPX rcaron iogonek 20
+KPX rcaron ibreve 20
+KPX rcaron imacron 20
+KPX rcaron gcommaaccent 10
+KPX rcaron gdotaccent 10
+KPX rcaron gbreve 10
+KPX rcaron gcircumflex 10
+KPX rcaron ydieresis 35
+KPX rcaron udieresis 25
+KPX rcaron ucircumflex 25
+KPX rcaron ntilde 25
+KPX rcaron idieresis 20
+KPX rcaron icircumflex 20
+KPX rcaron y 35
+KPX rcaron x 30
+KPX rcaron w 30
+KPX rcaron v 35
+KPX rcaron u 25
+KPX rcaron t 25
+KPX rcaron s 15
+KPX rcaron r 25
+KPX rcaron p 25
+KPX rcaron n 25
+KPX rcaron m 25
+KPX rcaron l -10
+KPX rcaron j 20
+KPX rcaron i 20
+KPX rcaron g 10
+KPX rcaron f 20
+KPX rcaron colon 15
+KPX rcaron period -20
+KPX rcaron hyphen 20
+KPX rcaron comma -25
+KPX Sacute ae.sc -25
+KPX Sacute aring.sc -20
+KPX Sacute adieresis.sc -20
+KPX Sacute a.sc -20
+KPX Sacute aeacute.sc -25
+KPX Sacute aogonek.sc -20
+KPX Sacute amacron.sc -20
+KPX Sacute uni021B -15
+KPX Sacute AEacute -30
+KPX Sacute tcaron -15
+KPX Sacute Aogonek -25
+KPX Sacute Amacron -25
+KPX Sacute AE -30
+KPX Sacute Aring -25
+KPX Sacute Adieresis -25
+KPX Sacute t -15
+KPX Sacute A -25
+KPX Scircumflex ae.sc -25
+KPX Scircumflex aring.sc -20
+KPX Scircumflex adieresis.sc -20
+KPX Scircumflex a.sc -20
+KPX Scircumflex aeacute.sc -25
+KPX Scircumflex aogonek.sc -20
+KPX Scircumflex amacron.sc -20
+KPX Scircumflex uni021B -15
+KPX Scircumflex AEacute -30
+KPX Scircumflex tcaron -15
+KPX Scircumflex Aogonek -25
+KPX Scircumflex Amacron -25
+KPX Scircumflex AE -30
+KPX Scircumflex Aring -25
+KPX Scircumflex Adieresis -25
+KPX Scircumflex t -15
+KPX Scircumflex A -25
+KPX Scedilla ae.sc -25
+KPX Scedilla aring.sc -20
+KPX Scedilla adieresis.sc -20
+KPX Scedilla a.sc -20
+KPX Scedilla aeacute.sc -25
+KPX Scedilla aogonek.sc -20
+KPX Scedilla amacron.sc -20
+KPX Scedilla uni021B -15
+KPX Scedilla AEacute -30
+KPX Scedilla tcaron -15
+KPX Scedilla Aogonek -25
+KPX Scedilla Amacron -25
+KPX Scedilla AE -30
+KPX Scedilla Aring -25
+KPX Scedilla Adieresis -25
+KPX Scedilla t -15
+KPX Scedilla A -25
+KPX Scaron ae.sc -25
+KPX Scaron aring.sc -20
+KPX Scaron adieresis.sc -20
+KPX Scaron a.sc -20
+KPX Scaron aeacute.sc -25
+KPX Scaron aogonek.sc -20
+KPX Scaron amacron.sc -20
+KPX Scaron uni021B -15
+KPX Scaron AEacute -30
+KPX Scaron tcaron -15
+KPX Scaron Aogonek -25
+KPX Scaron Amacron -25
+KPX Scaron AE -30
+KPX Scaron Aring -25
+KPX Scaron Adieresis -25
+KPX Scaron t -15
+KPX Scaron A -25
+KPX Tcaron ydieresis.sc 15
+KPX Tcaron yacute.sc 20
+KPX Tcaron oslash.sc -10
+KPX Tcaron odieresis.sc -5
+KPX Tcaron otilde.sc -5
+KPX Tcaron ocircumflex.sc -5
+KPX Tcaron oacute.sc -5
+KPX Tcaron ograve.sc -5
+KPX Tcaron ccedilla.sc -10
+KPX Tcaron ae.sc -55
+KPX Tcaron aring.sc -25
+KPX Tcaron adieresis.sc -25
+KPX Tcaron atilde.sc -25
+KPX Tcaron acircumflex.sc -25
+KPX Tcaron aacute.sc -35
+KPX Tcaron agrave.sc -25
+KPX Tcaron y.sc 25
+KPX Tcaron w.sc 25
+KPX Tcaron v.sc 25
+KPX Tcaron o.sc -10
+KPX Tcaron j.sc 15
+KPX Tcaron g.sc -15
+KPX Tcaron c.sc -10
+KPX Tcaron a.sc -45
+KPX Tcaron ygrave.sc 15
+KPX Tcaron ycircumflex.sc 15
+KPX Tcaron wgrave.sc 15
+KPX Tcaron wdieresis.sc 15
+KPX Tcaron wcircumflex.sc 15
+KPX Tcaron wacute.sc 20
+KPX Tcaron omacron.sc -5
+KPX Tcaron ohungarumlaut.sc -5
+KPX Tcaron obreve.sc -5
+KPX Tcaron jcircumflex.sc 10
+KPX Tcaron gdotaccent.sc -5
+KPX Tcaron gcommaaccent.sc -15
+KPX Tcaron gcircumflex.sc -5
+KPX Tcaron gbreve.sc -5
+KPX Tcaron cdotaccent.sc -5
+KPX Tcaron ccircumflex.sc -5
+KPX Tcaron ccaron.sc -5
+KPX Tcaron cacute.sc -5
+KPX Tcaron aeacute.sc -55
+KPX Tcaron aogonek.sc -45
+KPX Tcaron amacron.sc -25
+KPX Tcaron abreve.sc -25
+KPX Tcaron jacute -10
+KPX Tcaron Jacute 20
+KPX Tcaron ytilde.sc 15
+KPX Tcaron yhookabove.sc 15
+KPX Tcaron oogonek.sc -10
+KPX Tcaron ohorntilde.sc -5
+KPX Tcaron ohornhookabove.sc -5
+KPX Tcaron ohorngrave.sc -5
+KPX Tcaron ohorndotbelow.sc -5
+KPX Tcaron ohornacute.sc -5
+KPX Tcaron ohookabove.sc -5
+KPX Tcaron oe.sc -25
+KPX Tcaron ocircumflexdotbelow.sc -5
+KPX Tcaron jacute.sc 15
+KPX Tcaron gcaron.sc -5
+KPX Tcaron gacute.sc -10
+KPX Tcaron ahookabove.sc -25
+KPX Tcaron acircumflexdotbelow.sc -25
+KPX Tcaron abrevedotbelow.sc -25
+KPX Tcaron guilsinglleft -125
+KPX Tcaron ytilde -50
+KPX Tcaron yhookabove -50
+KPX Tcaron ygrave -50
+KPX Tcaron uhorndotbelow -50
+KPX Tcaron uhorntilde -50
+KPX Tcaron uhornhookabove -50
+KPX Tcaron uhorngrave -50
+KPX Tcaron uhornacute -50
+KPX Tcaron uhookabove -50
+KPX Tcaron ohorndotbelow -45
+KPX Tcaron ohorntilde -45
+KPX Tcaron ohornhookabove -45
+KPX Tcaron ohorngrave -45
+KPX Tcaron ohornacute -45
+KPX Tcaron ocircumflexdotbelow -45
+KPX Tcaron ohookabove -45
+KPX Tcaron ihookabove -5
+KPX Tcaron ecircumflexdotbelow -45
+KPX Tcaron etilde -45
+KPX Tcaron ehookabove -45
+KPX Tcaron abrevedotbelow -35
+KPX Tcaron acircumflexdotbelow -35
+KPX Tcaron ahookabove -35
+KPX Tcaron wdieresis -50
+KPX Tcaron Wdieresis 30
+KPX Tcaron wacute -70
+KPX Tcaron Wacute 30
+KPX Tcaron wgrave -50
+KPX Tcaron Wgrave 30
+KPX Tcaron rdotaccent -30
+KPX Tcaron uni0219 -65
+KPX Tcaron aeacute -60
+KPX Tcaron AEacute -80
+KPX Tcaron gacute -60
+KPX Tcaron Gacute -15
+KPX Tcaron oogonek -90
+KPX Tcaron Oogonek -10
+KPX Tcaron gcaron -40
+KPX Tcaron Gcaron -15
+KPX Tcaron Ydieresis 30
+KPX Tcaron ycircumflex -50
+KPX Tcaron Ycircumflex 30
+KPX Tcaron wcircumflex -50
+KPX Tcaron Wcircumflex 30
+KPX Tcaron uogonek -100
+KPX Tcaron uhungarumlaut -50
+KPX Tcaron uring -50
+KPX Tcaron ubreve -50
+KPX Tcaron umacron -50
+KPX Tcaron utilde -50
+KPX Tcaron scaron -35
+KPX Tcaron scedilla -65
+KPX Tcaron scircumflex -35
+KPX Tcaron sacute -50
+KPX Tcaron rcaron -30
+KPX Tcaron rcommaaccent -60
+KPX Tcaron racute -45
+KPX Tcaron oe -50
+KPX Tcaron OE -35
+KPX Tcaron ohungarumlaut -45
+KPX Tcaron Ohungarumlaut -10
+KPX Tcaron obreve -45
+KPX Tcaron Obreve -10
+KPX Tcaron omacron -45
+KPX Tcaron Omacron -10
+KPX Tcaron jcircumflex -5
+KPX Tcaron Jcircumflex 20
+KPX Tcaron iogonek -10
+KPX Tcaron ibreve -5
+KPX Tcaron imacron -5
+KPX Tcaron itilde -5
+KPX Tcaron gcommaaccent -80
+KPX Tcaron Gcommaaccent -15
+KPX Tcaron gdotaccent -40
+KPX Tcaron Gdotaccent -15
+KPX Tcaron gbreve -40
+KPX Tcaron Gbreve -15
+KPX Tcaron gcircumflex -40
+KPX Tcaron Gcircumflex -15
+KPX Tcaron ecaron -45
+KPX Tcaron eogonek -90
+KPX Tcaron edotaccent -45
+KPX Tcaron ebreve -45
+KPX Tcaron emacron -45
+KPX Tcaron ccaron -45
+KPX Tcaron Ccaron -10
+KPX Tcaron cdotaccent -45
+KPX Tcaron Cdotaccent -10
+KPX Tcaron ccircumflex -45
+KPX Tcaron Ccircumflex -10
+KPX Tcaron cacute -70
+KPX Tcaron Cacute -10
+KPX Tcaron aogonek -70
+KPX Tcaron Aogonek -55
+KPX Tcaron abreve -35
+KPX Tcaron amacron -35
+KPX Tcaron Amacron -55
+KPX Tcaron ydieresis -50
+KPX Tcaron yacute -70
+KPX Tcaron udieresis -50
+KPX Tcaron ucircumflex -50
+KPX Tcaron uacute -75
+KPX Tcaron ugrave -50
+KPX Tcaron oslash -90
+KPX Tcaron odieresis -45
+KPX Tcaron otilde -45
+KPX Tcaron ocircumflex -45
+KPX Tcaron oacute -70
+KPX Tcaron ograve -45
+KPX Tcaron idieresis -5
+KPX Tcaron icircumflex -5
+KPX Tcaron iacute -10
+KPX Tcaron igrave -5
+KPX Tcaron edieresis -45
+KPX Tcaron ecircumflex -45
+KPX Tcaron eacute -70
+KPX Tcaron egrave -45
+KPX Tcaron ccedilla -90
+KPX Tcaron ae -60
+KPX Tcaron aring -35
+KPX Tcaron adieresis -35
+KPX Tcaron atilde -35
+KPX Tcaron acircumflex -35
+KPX Tcaron aacute -55
+KPX Tcaron agrave -35
+KPX Tcaron Oslash -10
+KPX Tcaron Odieresis -10
+KPX Tcaron Ccedilla -10
+KPX Tcaron AE -80
+KPX Tcaron Aring -55
+KPX Tcaron Adieresis -55
+KPX Tcaron guillemotleft -100
+KPX Tcaron y -95
+KPX Tcaron w -95
+KPX Tcaron v -95
+KPX Tcaron u -100
+KPX Tcaron s -65
+KPX Tcaron r -60
+KPX Tcaron o -90
+KPX Tcaron j -10
+KPX Tcaron i -10
+KPX Tcaron g -80
+KPX Tcaron e -90
+KPX Tcaron c -90
+KPX Tcaron a -70
+KPX Tcaron Y 30
+KPX Tcaron W 30
+KPX Tcaron V 30
+KPX Tcaron O -10
+KPX Tcaron J 20
+KPX Tcaron G -15
+KPX Tcaron C -10
+KPX Tcaron A -55
+KPX Tcaron semicolon -70
+KPX Tcaron colon -65
+KPX Tcaron period -65
+KPX Tcaron hyphen -60
+KPX Tcaron comma -70
+KPX tcaron quotedblright 35
+KPX tcaron quotedblleft 35
+KPX tcaron quoteright 20
+KPX tcaron quoteleft 35
+KPX tcaron lcaron 30
+KPX tcaron lcommaaccent 30
+KPX tcaron lacute 30
+KPX tcaron kcommaaccent 30
+KPX tcaron hcircumflex 20
+KPX tcaron aogonek 10
+KPX tcaron amacron 10
+KPX tcaron thorn 30
+KPX tcaron aring 10
+KPX tcaron adieresis 10
+KPX tcaron l 30
+KPX tcaron k 30
+KPX tcaron h 20
+KPX tcaron b 30
+KPX tcaron a 10
+KPX tcaron backslash 35
+KPX tcaron colon 15
+KPX Utilde aring.sc -20
+KPX Utilde adieresis.sc -20
+KPX Utilde atilde.sc -20
+KPX Utilde acircumflex.sc -20
+KPX Utilde aacute.sc -30
+KPX Utilde agrave.sc -20
+KPX Utilde a.sc -40
+KPX Utilde amacron.sc -20
+KPX Utilde abreve.sc -20
+KPX Utilde ahookabove.sc -20
+KPX Utilde acircumflexdotbelow.sc -20
+KPX Utilde abrevedotbelow.sc -20
+KPX Utilde rdotaccent -15
+KPX Utilde rcaron -15
+KPX Utilde racute -20
+KPX Utilde ncaron -10
+KPX Utilde nacute -15
+KPX Utilde ntilde -10
+KPX Utilde n -20
+KPX Utilde m -20
+KPX Utilde A -50
+KPX Umacron ae.sc -45
+KPX Umacron aring.sc -20
+KPX Umacron adieresis.sc -20
+KPX Umacron atilde.sc -20
+KPX Umacron acircumflex.sc -20
+KPX Umacron aacute.sc -30
+KPX Umacron agrave.sc -20
+KPX Umacron a.sc -40
+KPX Umacron aeacute.sc -45
+KPX Umacron aogonek.sc -40
+KPX Umacron amacron.sc -20
+KPX Umacron abreve.sc -20
+KPX Umacron ahookabove.sc -20
+KPX Umacron acircumflexdotbelow.sc -20
+KPX Umacron abrevedotbelow.sc -20
+KPX Umacron rdotaccent -15
+KPX Umacron AEacute -55
+KPX Umacron rcaron -15
+KPX Umacron rcommaaccent -25
+KPX Umacron racute -20
+KPX Umacron ncaron -10
+KPX Umacron ncommaaccent -20
+KPX Umacron nacute -15
+KPX Umacron Aogonek -50
+KPX Umacron Amacron -50
+KPX Umacron ntilde -10
+KPX Umacron AE -55
+KPX Umacron Aring -50
+KPX Umacron Adieresis -50
+KPX Umacron r -25
+KPX Umacron p -25
+KPX Umacron n -20
+KPX Umacron m -20
+KPX Umacron A -50
+KPX Umacron period -15
+KPX Umacron comma -25
+KPX Ubreve ae.sc -45
+KPX Ubreve aring.sc -20
+KPX Ubreve adieresis.sc -20
+KPX Ubreve atilde.sc -20
+KPX Ubreve acircumflex.sc -20
+KPX Ubreve aacute.sc -30
+KPX Ubreve agrave.sc -20
+KPX Ubreve a.sc -40
+KPX Ubreve aeacute.sc -45
+KPX Ubreve aogonek.sc -40
+KPX Ubreve amacron.sc -20
+KPX Ubreve abreve.sc -20
+KPX Ubreve ahookabove.sc -20
+KPX Ubreve acircumflexdotbelow.sc -20
+KPX Ubreve abrevedotbelow.sc -20
+KPX Ubreve rdotaccent -15
+KPX Ubreve AEacute -55
+KPX Ubreve rcaron -15
+KPX Ubreve rcommaaccent -25
+KPX Ubreve racute -20
+KPX Ubreve ncaron -10
+KPX Ubreve ncommaaccent -20
+KPX Ubreve nacute -15
+KPX Ubreve Aogonek -50
+KPX Ubreve Amacron -50
+KPX Ubreve ntilde -10
+KPX Ubreve AE -55
+KPX Ubreve Aring -50
+KPX Ubreve Adieresis -50
+KPX Ubreve r -25
+KPX Ubreve p -25
+KPX Ubreve n -20
+KPX Ubreve m -20
+KPX Ubreve A -50
+KPX Ubreve period -15
+KPX Ubreve comma -25
+KPX Uring ae.sc -45
+KPX Uring aring.sc -20
+KPX Uring adieresis.sc -20
+KPX Uring atilde.sc -20
+KPX Uring acircumflex.sc -20
+KPX Uring aacute.sc -30
+KPX Uring agrave.sc -20
+KPX Uring a.sc -40
+KPX Uring aeacute.sc -45
+KPX Uring aogonek.sc -40
+KPX Uring amacron.sc -20
+KPX Uring abreve.sc -20
+KPX Uring ahookabove.sc -20
+KPX Uring acircumflexdotbelow.sc -20
+KPX Uring abrevedotbelow.sc -20
+KPX Uring rdotaccent -15
+KPX Uring AEacute -55
+KPX Uring rcaron -15
+KPX Uring rcommaaccent -25
+KPX Uring racute -20
+KPX Uring ncaron -10
+KPX Uring ncommaaccent -20
+KPX Uring nacute -15
+KPX Uring Aogonek -50
+KPX Uring Amacron -50
+KPX Uring ntilde -10
+KPX Uring AE -55
+KPX Uring Aring -50
+KPX Uring Adieresis -50
+KPX Uring r -25
+KPX Uring p -25
+KPX Uring n -20
+KPX Uring m -20
+KPX Uring A -50
+KPX Uring period -15
+KPX Uring comma -25
+KPX Uhungarumlaut ae.sc -45
+KPX Uhungarumlaut aring.sc -20
+KPX Uhungarumlaut adieresis.sc -20
+KPX Uhungarumlaut atilde.sc -20
+KPX Uhungarumlaut acircumflex.sc -20
+KPX Uhungarumlaut aacute.sc -30
+KPX Uhungarumlaut agrave.sc -20
+KPX Uhungarumlaut a.sc -40
+KPX Uhungarumlaut aeacute.sc -45
+KPX Uhungarumlaut aogonek.sc -40
+KPX Uhungarumlaut amacron.sc -20
+KPX Uhungarumlaut abreve.sc -20
+KPX Uhungarumlaut ahookabove.sc -20
+KPX Uhungarumlaut acircumflexdotbelow.sc -20
+KPX Uhungarumlaut abrevedotbelow.sc -20
+KPX Uhungarumlaut rdotaccent -15
+KPX Uhungarumlaut AEacute -55
+KPX Uhungarumlaut rcaron -15
+KPX Uhungarumlaut rcommaaccent -25
+KPX Uhungarumlaut racute -20
+KPX Uhungarumlaut ncaron -10
+KPX Uhungarumlaut ncommaaccent -20
+KPX Uhungarumlaut nacute -15
+KPX Uhungarumlaut Aogonek -50
+KPX Uhungarumlaut Amacron -50
+KPX Uhungarumlaut ntilde -10
+KPX Uhungarumlaut AE -55
+KPX Uhungarumlaut Aring -50
+KPX Uhungarumlaut Adieresis -50
+KPX Uhungarumlaut r -25
+KPX Uhungarumlaut p -25
+KPX Uhungarumlaut n -20
+KPX Uhungarumlaut m -20
+KPX Uhungarumlaut A -50
+KPX Uhungarumlaut period -15
+KPX Uhungarumlaut comma -25
+KPX Uogonek ae.sc -45
+KPX Uogonek aring.sc -20
+KPX Uogonek adieresis.sc -20
+KPX Uogonek atilde.sc -20
+KPX Uogonek acircumflex.sc -20
+KPX Uogonek aacute.sc -30
+KPX Uogonek agrave.sc -20
+KPX Uogonek a.sc -40
+KPX Uogonek aeacute.sc -45
+KPX Uogonek aogonek.sc -40
+KPX Uogonek amacron.sc -20
+KPX Uogonek abreve.sc -20
+KPX Uogonek ahookabove.sc -20
+KPX Uogonek acircumflexdotbelow.sc -20
+KPX Uogonek abrevedotbelow.sc -20
+KPX Uogonek rdotaccent -15
+KPX Uogonek AEacute -55
+KPX Uogonek rcaron -15
+KPX Uogonek rcommaaccent -25
+KPX Uogonek racute -20
+KPX Uogonek ncaron -10
+KPX Uogonek ncommaaccent -20
+KPX Uogonek nacute -15
+KPX Uogonek Aogonek -50
+KPX Uogonek Amacron -50
+KPX Uogonek ntilde -10
+KPX Uogonek AE -55
+KPX Uogonek Aring -50
+KPX Uogonek Adieresis -50
+KPX Uogonek r -25
+KPX Uogonek p -25
+KPX Uogonek n -20
+KPX Uogonek m -20
+KPX Uogonek A -50
+KPX Uogonek period -15
+KPX Uogonek comma -25
+KPX Wcircumflex T_h 30
+KPX Wcircumflex oslash.sc -30
+KPX Wcircumflex odieresis.sc -15
+KPX Wcircumflex otilde.sc -15
+KPX Wcircumflex ocircumflex.sc -15
+KPX Wcircumflex oacute.sc -20
+KPX Wcircumflex ograve.sc -15
+KPX Wcircumflex ccedilla.sc -30
+KPX Wcircumflex ae.sc -55
+KPX Wcircumflex aring.sc -35
+KPX Wcircumflex adieresis.sc -35
+KPX Wcircumflex atilde.sc -35
+KPX Wcircumflex acircumflex.sc -35
+KPX Wcircumflex aacute.sc -50
+KPX Wcircumflex agrave.sc -35
+KPX Wcircumflex t.sc 25
+KPX Wcircumflex s.sc -20
+KPX Wcircumflex o.sc -30
+KPX Wcircumflex g.sc -35
+KPX Wcircumflex c.sc -30
+KPX Wcircumflex a.sc -65
+KPX Wcircumflex uni021B.sc 25
+KPX Wcircumflex tcaron.sc 15
+KPX Wcircumflex uni0219.sc -20
+KPX Wcircumflex scircumflex.sc -10
+KPX Wcircumflex scedilla.sc -20
+KPX Wcircumflex sacute.sc -15
+KPX Wcircumflex omacron.sc -15
+KPX Wcircumflex ohungarumlaut.sc -15
+KPX Wcircumflex obreve.sc -15
+KPX Wcircumflex gdotaccent.sc -15
+KPX Wcircumflex gcommaaccent.sc -35
+KPX Wcircumflex gcircumflex.sc -15
+KPX Wcircumflex gbreve.sc -15
+KPX Wcircumflex cdotaccent.sc -15
+KPX Wcircumflex ccircumflex.sc -15
+KPX Wcircumflex ccaron.sc -15
+KPX Wcircumflex cacute.sc -20
+KPX Wcircumflex aeacute.sc -55
+KPX Wcircumflex aogonek.sc -65
+KPX Wcircumflex amacron.sc -35
+KPX Wcircumflex abreve.sc -35
+KPX Wcircumflex scaron.sc -10
+KPX Wcircumflex oogonek.sc -30
+KPX Wcircumflex ohorntilde.sc -15
+KPX Wcircumflex ohornhookabove.sc -15
+KPX Wcircumflex ohorngrave.sc -15
+KPX Wcircumflex ohorndotbelow.sc -15
+KPX Wcircumflex ohornacute.sc -15
+KPX Wcircumflex ohookabove.sc -15
+KPX Wcircumflex oe.sc -25
+KPX Wcircumflex ocircumflexdotbelow.sc -15
+KPX Wcircumflex gcaron.sc -15
+KPX Wcircumflex gacute.sc -25
+KPX Wcircumflex ahookabove.sc -35
+KPX Wcircumflex acircumflexdotbelow.sc -35
+KPX Wcircumflex abrevedotbelow.sc -35
+KPX Wcircumflex guilsinglleft -85
+KPX Wcircumflex ytilde -10
+KPX Wcircumflex yhookabove -10
+KPX Wcircumflex ygrave -10
+KPX Wcircumflex uhorndotbelow -20
+KPX Wcircumflex uhorntilde -20
+KPX Wcircumflex uhornhookabove -20
+KPX Wcircumflex uhorngrave -20
+KPX Wcircumflex uhornacute -20
+KPX Wcircumflex uhookabove -20
+KPX Wcircumflex ohorndotbelow -25
+KPX Wcircumflex ohorntilde -25
+KPX Wcircumflex ohornhookabove -25
+KPX Wcircumflex ohorngrave -25
+KPX Wcircumflex ohornacute -25
+KPX Wcircumflex ocircumflexdotbelow -25
+KPX Wcircumflex ohookabove -25
+KPX Wcircumflex ecircumflexdotbelow -30
+KPX Wcircumflex etilde -30
+KPX Wcircumflex ehookabove -30
+KPX Wcircumflex abrevedotbelow -30
+KPX Wcircumflex acircumflexdotbelow -30
+KPX Wcircumflex ahookabove -30
+KPX Wcircumflex rdotaccent -20
+KPX Wcircumflex uni021A 30
+KPX Wcircumflex uni0218 -25
+KPX Wcircumflex aeacute -60
+KPX Wcircumflex AEacute -80
+KPX Wcircumflex gacute -40
+KPX Wcircumflex Gacute -40
+KPX Wcircumflex oogonek -50
+KPX Wcircumflex Oogonek -35
+KPX Wcircumflex gcaron -30
+KPX Wcircumflex Gcaron -40
+KPX Wcircumflex ycircumflex -10
+KPX Wcircumflex uogonek -35
+KPX Wcircumflex uhungarumlaut -20
+KPX Wcircumflex uring -20
+KPX Wcircumflex ubreve -20
+KPX Wcircumflex umacron -20
+KPX Wcircumflex utilde -20
+KPX Wcircumflex Tcaron 30
+KPX Wcircumflex Scaron -25
+KPX Wcircumflex Scedilla -25
+KPX Wcircumflex Scircumflex -25
+KPX Wcircumflex Sacute -25
+KPX Wcircumflex rcaron -20
+KPX Wcircumflex rcommaaccent -35
+KPX Wcircumflex racute -25
+KPX Wcircumflex oe -50
+KPX Wcircumflex OE -35
+KPX Wcircumflex ohungarumlaut -25
+KPX Wcircumflex Ohungarumlaut -35
+KPX Wcircumflex obreve -25
+KPX Wcircumflex Obreve -35
+KPX Wcircumflex omacron -25
+KPX Wcircumflex Omacron -35
+KPX Wcircumflex gcommaaccent -55
+KPX Wcircumflex Gcommaaccent -40
+KPX Wcircumflex gdotaccent -30
+KPX Wcircumflex Gdotaccent -40
+KPX Wcircumflex gbreve -30
+KPX Wcircumflex Gbreve -40
+KPX Wcircumflex gcircumflex -30
+KPX Wcircumflex Gcircumflex -40
+KPX Wcircumflex ecaron -30
+KPX Wcircumflex eogonek -55
+KPX Wcircumflex edotaccent -30
+KPX Wcircumflex ebreve -30
+KPX Wcircumflex emacron -30
+KPX Wcircumflex Ccaron -35
+KPX Wcircumflex Cdotaccent -35
+KPX Wcircumflex Ccircumflex -35
+KPX Wcircumflex Cacute -35
+KPX Wcircumflex aogonek -60
+KPX Wcircumflex Aogonek -80
+KPX Wcircumflex abreve -30
+KPX Wcircumflex amacron -30
+KPX Wcircumflex Amacron -80
+KPX Wcircumflex ydieresis -10
+KPX Wcircumflex yacute -15
+KPX Wcircumflex udieresis -20
+KPX Wcircumflex ucircumflex -20
+KPX Wcircumflex uacute -25
+KPX Wcircumflex ugrave -20
+KPX Wcircumflex oslash -50
+KPX Wcircumflex odieresis -25
+KPX Wcircumflex otilde -25
+KPX Wcircumflex ocircumflex -25
+KPX Wcircumflex oacute -40
+KPX Wcircumflex ograve -25
+KPX Wcircumflex edieresis -30
+KPX Wcircumflex ecircumflex -30
+KPX Wcircumflex eacute -40
+KPX Wcircumflex egrave -30
+KPX Wcircumflex ae -60
+KPX Wcircumflex aring -30
+KPX Wcircumflex adieresis -30
+KPX Wcircumflex atilde -30
+KPX Wcircumflex acircumflex -30
+KPX Wcircumflex aacute -45
+KPX Wcircumflex agrave -30
+KPX Wcircumflex Oslash -35
+KPX Wcircumflex Odieresis -35
+KPX Wcircumflex Ccedilla -35
+KPX Wcircumflex AE -80
+KPX Wcircumflex Aring -80
+KPX Wcircumflex Adieresis -80
+KPX Wcircumflex guillemotleft -60
+KPX Wcircumflex y -20
+KPX Wcircumflex u -35
+KPX Wcircumflex r -35
+KPX Wcircumflex o -50
+KPX Wcircumflex g -55
+KPX Wcircumflex e -55
+KPX Wcircumflex a -60
+KPX Wcircumflex T 30
+KPX Wcircumflex S -25
+KPX Wcircumflex O -35
+KPX Wcircumflex G -40
+KPX Wcircumflex C -35
+KPX Wcircumflex A -80
+KPX Wcircumflex semicolon -55
+KPX Wcircumflex colon -40
+KPX Wcircumflex period -50
+KPX Wcircumflex hyphen -20
+KPX Wcircumflex comma -60
+KPX wcircumflex aeacute -20
+KPX wcircumflex gacute -10
+KPX wcircumflex oogonek -25
+KPX wcircumflex gcaron -10
+KPX wcircumflex oe -25
+KPX wcircumflex ohungarumlaut -25
+KPX wcircumflex obreve -25
+KPX wcircumflex omacron -25
+KPX wcircumflex lslash -20
+KPX wcircumflex lcaron -20
+KPX wcircumflex lcommaaccent -20
+KPX wcircumflex lacute -20
+KPX wcircumflex gcommaaccent -10
+KPX wcircumflex gdotaccent -10
+KPX wcircumflex gbreve -10
+KPX wcircumflex gcircumflex -10
+KPX wcircumflex ecaron -30
+KPX wcircumflex eogonek -30
+KPX wcircumflex edotaccent -30
+KPX wcircumflex ebreve -30
+KPX wcircumflex emacron -30
+KPX wcircumflex ccaron -35
+KPX wcircumflex cdotaccent -35
+KPX wcircumflex ccircumflex -35
+KPX wcircumflex cacute -35
+KPX wcircumflex aogonek -20
+KPX wcircumflex amacron -20
+KPX wcircumflex oslash -25
+KPX wcircumflex odieresis -25
+KPX wcircumflex edieresis -30
+KPX wcircumflex ccedilla -35
+KPX wcircumflex ae -20
+KPX wcircumflex aring -20
+KPX wcircumflex adieresis -20
+KPX wcircumflex o -25
+KPX wcircumflex l -20
+KPX wcircumflex g -10
+KPX wcircumflex e -30
+KPX wcircumflex c -35
+KPX wcircumflex a -20
+KPX wcircumflex period -45
+KPX wcircumflex comma -55
+KPX Ycircumflex zcaron -50
+KPX Ycircumflex zdotaccent -50
+KPX Ycircumflex zacute -50
+KPX Ycircumflex z -50
+KPX Ycircumflex ccaron -75
+KPX Ycircumflex cdotaccent -75
+KPX Ycircumflex ccircumflex -75
+KPX Ycircumflex cacute -75
+KPX Ycircumflex ccedilla -75
+KPX Ycircumflex c -75
+KPX Ycircumflex scaron -50
+KPX Ycircumflex scedilla -50
+KPX Ycircumflex scircumflex -50
+KPX Ycircumflex sacute -50
+KPX Ycircumflex s -50
+KPX Ycircumflex T_h 35
+KPX Ycircumflex oslash.sc -40
+KPX Ycircumflex odieresis.sc -20
+KPX Ycircumflex otilde.sc -20
+KPX Ycircumflex ocircumflex.sc -20
+KPX Ycircumflex oacute.sc -30
+KPX Ycircumflex ograve.sc -20
+KPX Ycircumflex ccedilla.sc -40
+KPX Ycircumflex ae.sc -55
+KPX Ycircumflex aring.sc -15
+KPX Ycircumflex adieresis.sc -15
+KPX Ycircumflex atilde.sc -15
+KPX Ycircumflex acircumflex.sc -15
+KPX Ycircumflex aacute.sc -25
+KPX Ycircumflex agrave.sc -15
+KPX Ycircumflex t.sc 30
+KPX Ycircumflex s.sc -20
+KPX Ycircumflex o.sc -40
+KPX Ycircumflex g.sc -40
+KPX Ycircumflex c.sc -40
+KPX Ycircumflex a.sc -35
+KPX Ycircumflex uni021B.sc 30
+KPX Ycircumflex tcaron.sc 15
+KPX Ycircumflex uni0219.sc -20
+KPX Ycircumflex scircumflex.sc -10
+KPX Ycircumflex scedilla.sc -20
+KPX Ycircumflex sacute.sc -15
+KPX Ycircumflex omacron.sc -20
+KPX Ycircumflex ohungarumlaut.sc -20
+KPX Ycircumflex obreve.sc -20
+KPX Ycircumflex gdotaccent.sc -20
+KPX Ycircumflex gcommaaccent.sc -40
+KPX Ycircumflex gcircumflex.sc -20
+KPX Ycircumflex gbreve.sc -20
+KPX Ycircumflex cdotaccent.sc -20
+KPX Ycircumflex ccircumflex.sc -20
+KPX Ycircumflex ccaron.sc -20
+KPX Ycircumflex cacute.sc -30
+KPX Ycircumflex aeacute.sc -55
+KPX Ycircumflex aogonek.sc -35
+KPX Ycircumflex amacron.sc -15
+KPX Ycircumflex abreve.sc -15
+KPX Ycircumflex scaron.sc -10
+KPX Ycircumflex oogonek.sc -40
+KPX Ycircumflex ohorntilde.sc -20
+KPX Ycircumflex ohornhookabove.sc -20
+KPX Ycircumflex ohorngrave.sc -20
+KPX Ycircumflex ohorndotbelow.sc -20
+KPX Ycircumflex ohornacute.sc -20
+KPX Ycircumflex ohookabove.sc -20
+KPX Ycircumflex oe.sc -25
+KPX Ycircumflex ocircumflexdotbelow.sc -20
+KPX Ycircumflex gcaron.sc -20
+KPX Ycircumflex gacute.sc -30
+KPX Ycircumflex ahookabove.sc -15
+KPX Ycircumflex acircumflexdotbelow.sc -15
+KPX Ycircumflex abrevedotbelow.sc -15
+KPX Ycircumflex guilsinglleft -105
+KPX Ycircumflex uhorndotbelow -25
+KPX Ycircumflex uhorntilde -25
+KPX Ycircumflex uhornhookabove -25
+KPX Ycircumflex uhorngrave -25
+KPX Ycircumflex uhornacute -25
+KPX Ycircumflex uhookabove -25
+KPX Ycircumflex ohorndotbelow -35
+KPX Ycircumflex ohorntilde -35
+KPX Ycircumflex ohornhookabove -35
+KPX Ycircumflex ohorngrave -35
+KPX Ycircumflex ohornacute -35
+KPX Ycircumflex ocircumflexdotbelow -35
+KPX Ycircumflex ohookabove -35
+KPX Ycircumflex ecircumflexdotbelow -35
+KPX Ycircumflex etilde -35
+KPX Ycircumflex ehookabove -35
+KPX Ycircumflex abrevedotbelow -30
+KPX Ycircumflex acircumflexdotbelow -30
+KPX Ycircumflex ahookabove -30
+KPX Ycircumflex uni021A 35
+KPX Ycircumflex uni0218 -25
+KPX Ycircumflex aeacute -60
+KPX Ycircumflex AEacute -80
+KPX Ycircumflex gacute -50
+KPX Ycircumflex Gacute -45
+KPX Ycircumflex oogonek -70
+KPX Ycircumflex Oogonek -45
+KPX Ycircumflex gcaron -35
+KPX Ycircumflex Gcaron -45
+KPX Ycircumflex uogonek -50
+KPX Ycircumflex uhungarumlaut -25
+KPX Ycircumflex uring -25
+KPX Ycircumflex ubreve -25
+KPX Ycircumflex umacron -25
+KPX Ycircumflex utilde -25
+KPX Ycircumflex Tcaron 35
+KPX Ycircumflex Scaron -25
+KPX Ycircumflex Scedilla -25
+KPX Ycircumflex Scircumflex -25
+KPX Ycircumflex Sacute -25
+KPX Ycircumflex oe -50
+KPX Ycircumflex OE -35
+KPX Ycircumflex ohungarumlaut -35
+KPX Ycircumflex Ohungarumlaut -45
+KPX Ycircumflex obreve -35
+KPX Ycircumflex Obreve -45
+KPX Ycircumflex omacron -35
+KPX Ycircumflex Omacron -45
+KPX Ycircumflex gcommaaccent -65
+KPX Ycircumflex Gcommaaccent -45
+KPX Ycircumflex gdotaccent -35
+KPX Ycircumflex Gdotaccent -45
+KPX Ycircumflex gbreve -35
+KPX Ycircumflex Gbreve -45
+KPX Ycircumflex gcircumflex -35
+KPX Ycircumflex Gcircumflex -45
+KPX Ycircumflex ecaron -35
+KPX Ycircumflex eogonek -70
+KPX Ycircumflex edotaccent -35
+KPX Ycircumflex ebreve -35
+KPX Ycircumflex emacron -35
+KPX Ycircumflex Ccaron -45
+KPX Ycircumflex Cdotaccent -45
+KPX Ycircumflex Ccircumflex -45
+KPX Ycircumflex Cacute -45
+KPX Ycircumflex aogonek -55
+KPX Ycircumflex Aogonek -40
+KPX Ycircumflex abreve -30
+KPX Ycircumflex amacron -30
+KPX Ycircumflex Amacron -40
+KPX Ycircumflex udieresis -25
+KPX Ycircumflex ucircumflex -25
+KPX Ycircumflex uacute -40
+KPX Ycircumflex ugrave -25
+KPX Ycircumflex oslash -70
+KPX Ycircumflex odieresis -35
+KPX Ycircumflex otilde -35
+KPX Ycircumflex ocircumflex -35
+KPX Ycircumflex oacute -55
+KPX Ycircumflex ograve -35
+KPX Ycircumflex edieresis -35
+KPX Ycircumflex ecircumflex -35
+KPX Ycircumflex eacute -55
+KPX Ycircumflex egrave -35
+KPX Ycircumflex ae -60
+KPX Ycircumflex aring -30
+KPX Ycircumflex adieresis -30
+KPX Ycircumflex atilde -30
+KPX Ycircumflex acircumflex -30
+KPX Ycircumflex aacute -40
+KPX Ycircumflex agrave -30
+KPX Ycircumflex Oslash -45
+KPX Ycircumflex Odieresis -45
+KPX Ycircumflex Ccedilla -45
+KPX Ycircumflex AE -80
+KPX Ycircumflex Aring -40
+KPX Ycircumflex Adieresis -40
+KPX Ycircumflex guillemotleft -80
+KPX Ycircumflex v -35
+KPX Ycircumflex u -50
+KPX Ycircumflex p -50
+KPX Ycircumflex o -70
+KPX Ycircumflex g -65
+KPX Ycircumflex e -70
+KPX Ycircumflex a -55
+KPX Ycircumflex T 35
+KPX Ycircumflex S -25
+KPX Ycircumflex O -45
+KPX Ycircumflex G -45
+KPX Ycircumflex C -45
+KPX Ycircumflex A -40
+KPX Ycircumflex semicolon -60
+KPX Ycircumflex colon -55
+KPX Ycircumflex period -50
+KPX Ycircumflex hyphen -45
+KPX Ycircumflex comma -55
+KPX ycircumflex aeacute -20
+KPX ycircumflex gacute -15
+KPX ycircumflex oogonek -30
+KPX ycircumflex gcaron -15
+KPX ycircumflex oe -25
+KPX ycircumflex ohungarumlaut -30
+KPX ycircumflex obreve -30
+KPX ycircumflex omacron -30
+KPX ycircumflex lslash -15
+KPX ycircumflex lcaron -15
+KPX ycircumflex lcommaaccent -15
+KPX ycircumflex lacute -15
+KPX ycircumflex gcommaaccent -15
+KPX ycircumflex gdotaccent -15
+KPX ycircumflex gbreve -15
+KPX ycircumflex gcircumflex -15
+KPX ycircumflex ecaron -35
+KPX ycircumflex eogonek -35
+KPX ycircumflex edotaccent -35
+KPX ycircumflex ebreve -35
+KPX ycircumflex emacron -35
+KPX ycircumflex ccaron -35
+KPX ycircumflex cdotaccent -35
+KPX ycircumflex ccircumflex -35
+KPX ycircumflex cacute -35
+KPX ycircumflex aogonek -25
+KPX ycircumflex amacron -25
+KPX ycircumflex oslash -30
+KPX ycircumflex odieresis -30
+KPX ycircumflex edieresis -35
+KPX ycircumflex ccedilla -35
+KPX ycircumflex ae -20
+KPX ycircumflex aring -25
+KPX ycircumflex adieresis -25
+KPX ycircumflex o -30
+KPX ycircumflex l -15
+KPX ycircumflex g -15
+KPX ycircumflex e -35
+KPX ycircumflex c -35
+KPX ycircumflex a -25
+KPX ycircumflex period -60
+KPX ycircumflex hyphen -10
+KPX ycircumflex comma -65
+KPX Ydieresis zcaron -50
+KPX Ydieresis zdotaccent -50
+KPX Ydieresis zacute -50
+KPX Ydieresis z -50
+KPX Ydieresis ccaron -75
+KPX Ydieresis cdotaccent -75
+KPX Ydieresis ccircumflex -75
+KPX Ydieresis cacute -75
+KPX Ydieresis ccedilla -75
+KPX Ydieresis c -75
+KPX Ydieresis scaron -50
+KPX Ydieresis scedilla -50
+KPX Ydieresis scircumflex -50
+KPX Ydieresis sacute -50
+KPX Ydieresis s -50
+KPX Ydieresis T_h 35
+KPX Ydieresis oslash.sc -40
+KPX Ydieresis odieresis.sc -20
+KPX Ydieresis otilde.sc -20
+KPX Ydieresis ocircumflex.sc -20
+KPX Ydieresis oacute.sc -30
+KPX Ydieresis ograve.sc -20
+KPX Ydieresis ccedilla.sc -40
+KPX Ydieresis ae.sc -55
+KPX Ydieresis aring.sc -15
+KPX Ydieresis adieresis.sc -15
+KPX Ydieresis atilde.sc -15
+KPX Ydieresis acircumflex.sc -15
+KPX Ydieresis aacute.sc -25
+KPX Ydieresis agrave.sc -15
+KPX Ydieresis t.sc 30
+KPX Ydieresis s.sc -20
+KPX Ydieresis o.sc -40
+KPX Ydieresis g.sc -40
+KPX Ydieresis c.sc -40
+KPX Ydieresis a.sc -35
+KPX Ydieresis uni021B.sc 30
+KPX Ydieresis tcaron.sc 15
+KPX Ydieresis uni0219.sc -20
+KPX Ydieresis scircumflex.sc -10
+KPX Ydieresis scedilla.sc -20
+KPX Ydieresis sacute.sc -15
+KPX Ydieresis omacron.sc -20
+KPX Ydieresis ohungarumlaut.sc -20
+KPX Ydieresis obreve.sc -20
+KPX Ydieresis gdotaccent.sc -20
+KPX Ydieresis gcommaaccent.sc -40
+KPX Ydieresis gcircumflex.sc -20
+KPX Ydieresis gbreve.sc -20
+KPX Ydieresis cdotaccent.sc -20
+KPX Ydieresis ccircumflex.sc -20
+KPX Ydieresis ccaron.sc -20
+KPX Ydieresis cacute.sc -30
+KPX Ydieresis aeacute.sc -55
+KPX Ydieresis aogonek.sc -35
+KPX Ydieresis amacron.sc -15
+KPX Ydieresis abreve.sc -15
+KPX Ydieresis scaron.sc -10
+KPX Ydieresis oogonek.sc -40
+KPX Ydieresis ohorntilde.sc -20
+KPX Ydieresis ohornhookabove.sc -20
+KPX Ydieresis ohorngrave.sc -20
+KPX Ydieresis ohorndotbelow.sc -20
+KPX Ydieresis ohornacute.sc -20
+KPX Ydieresis ohookabove.sc -20
+KPX Ydieresis oe.sc -25
+KPX Ydieresis ocircumflexdotbelow.sc -20
+KPX Ydieresis gcaron.sc -20
+KPX Ydieresis gacute.sc -30
+KPX Ydieresis ahookabove.sc -15
+KPX Ydieresis acircumflexdotbelow.sc -15
+KPX Ydieresis abrevedotbelow.sc -15
+KPX Ydieresis guilsinglleft -105
+KPX Ydieresis uhorndotbelow -25
+KPX Ydieresis uhorntilde -25
+KPX Ydieresis uhornhookabove -25
+KPX Ydieresis uhorngrave -25
+KPX Ydieresis uhornacute -25
+KPX Ydieresis uhookabove -25
+KPX Ydieresis ohorndotbelow -35
+KPX Ydieresis ohorntilde -35
+KPX Ydieresis ohornhookabove -35
+KPX Ydieresis ohorngrave -35
+KPX Ydieresis ohornacute -35
+KPX Ydieresis ocircumflexdotbelow -35
+KPX Ydieresis ohookabove -35
+KPX Ydieresis ecircumflexdotbelow -35
+KPX Ydieresis etilde -35
+KPX Ydieresis ehookabove -35
+KPX Ydieresis abrevedotbelow -30
+KPX Ydieresis acircumflexdotbelow -30
+KPX Ydieresis ahookabove -30
+KPX Ydieresis uni021A 35
+KPX Ydieresis uni0218 -25
+KPX Ydieresis aeacute -60
+KPX Ydieresis AEacute -80
+KPX Ydieresis gacute -50
+KPX Ydieresis Gacute -45
+KPX Ydieresis oogonek -70
+KPX Ydieresis Oogonek -45
+KPX Ydieresis gcaron -35
+KPX Ydieresis Gcaron -45
+KPX Ydieresis uogonek -50
+KPX Ydieresis uhungarumlaut -25
+KPX Ydieresis uring -25
+KPX Ydieresis ubreve -25
+KPX Ydieresis umacron -25
+KPX Ydieresis utilde -25
+KPX Ydieresis Tcaron 35
+KPX Ydieresis Scaron -25
+KPX Ydieresis Scedilla -25
+KPX Ydieresis Scircumflex -25
+KPX Ydieresis Sacute -25
+KPX Ydieresis oe -50
+KPX Ydieresis OE -35
+KPX Ydieresis ohungarumlaut -35
+KPX Ydieresis Ohungarumlaut -45
+KPX Ydieresis obreve -35
+KPX Ydieresis Obreve -45
+KPX Ydieresis omacron -35
+KPX Ydieresis Omacron -45
+KPX Ydieresis gcommaaccent -65
+KPX Ydieresis Gcommaaccent -45
+KPX Ydieresis gdotaccent -35
+KPX Ydieresis Gdotaccent -45
+KPX Ydieresis gbreve -35
+KPX Ydieresis Gbreve -45
+KPX Ydieresis gcircumflex -35
+KPX Ydieresis Gcircumflex -45
+KPX Ydieresis ecaron -35
+KPX Ydieresis eogonek -70
+KPX Ydieresis edotaccent -35
+KPX Ydieresis ebreve -35
+KPX Ydieresis emacron -35
+KPX Ydieresis Ccaron -45
+KPX Ydieresis Cdotaccent -45
+KPX Ydieresis Ccircumflex -45
+KPX Ydieresis Cacute -45
+KPX Ydieresis aogonek -55
+KPX Ydieresis Aogonek -40
+KPX Ydieresis abreve -30
+KPX Ydieresis amacron -30
+KPX Ydieresis Amacron -40
+KPX Ydieresis udieresis -25
+KPX Ydieresis ucircumflex -25
+KPX Ydieresis uacute -40
+KPX Ydieresis ugrave -25
+KPX Ydieresis oslash -70
+KPX Ydieresis odieresis -35
+KPX Ydieresis otilde -35
+KPX Ydieresis ocircumflex -35
+KPX Ydieresis oacute -55
+KPX Ydieresis ograve -35
+KPX Ydieresis edieresis -35
+KPX Ydieresis ecircumflex -35
+KPX Ydieresis eacute -55
+KPX Ydieresis egrave -35
+KPX Ydieresis ae -60
+KPX Ydieresis aring -30
+KPX Ydieresis adieresis -30
+KPX Ydieresis atilde -30
+KPX Ydieresis acircumflex -30
+KPX Ydieresis aacute -40
+KPX Ydieresis agrave -30
+KPX Ydieresis Oslash -45
+KPX Ydieresis Odieresis -45
+KPX Ydieresis Ccedilla -45
+KPX Ydieresis AE -80
+KPX Ydieresis Aring -40
+KPX Ydieresis Adieresis -40
+KPX Ydieresis guillemotleft -80
+KPX Ydieresis v -35
+KPX Ydieresis u -50
+KPX Ydieresis p -50
+KPX Ydieresis o -70
+KPX Ydieresis g -65
+KPX Ydieresis e -70
+KPX Ydieresis a -55
+KPX Ydieresis T 35
+KPX Ydieresis S -25
+KPX Ydieresis O -45
+KPX Ydieresis G -45
+KPX Ydieresis C -45
+KPX Ydieresis A -40
+KPX Ydieresis semicolon -60
+KPX Ydieresis colon -55
+KPX Ydieresis period -50
+KPX Ydieresis hyphen -45
+KPX Ydieresis comma -55
+KPX Zacute ycircumflex -50
+KPX Zacute ydieresis -50
+KPX Zacute y -50
+KPX Zacute v -45
+KPX Zdotaccent ycircumflex -50
+KPX Zdotaccent ydieresis -50
+KPX Zdotaccent y -50
+KPX Zdotaccent v -45
+KPX Zcaron ycircumflex -50
+KPX Zcaron ydieresis -50
+KPX Zcaron y -50
+KPX Zcaron v -45
+KPX Gcaron T_h -15
+KPX Gcaron ydieresis.sc -15
+KPX Gcaron ae.sc -15
+KPX Gcaron aring.sc -15
+KPX Gcaron adieresis.sc -15
+KPX Gcaron y.sc -15
+KPX Gcaron w.sc -15
+KPX Gcaron v.sc -15
+KPX Gcaron t.sc -15
+KPX Gcaron a.sc -15
+KPX Gcaron ycircumflex.sc -15
+KPX Gcaron wgrave.sc -15
+KPX Gcaron wdieresis.sc -15
+KPX Gcaron wcircumflex.sc -15
+KPX Gcaron wacute.sc -15
+KPX Gcaron uni021B.sc -15
+KPX Gcaron tcaron.sc -15
+KPX Gcaron aeacute.sc -15
+KPX Gcaron aogonek.sc -15
+KPX Gcaron amacron.sc -15
+KPX Gcaron Wdieresis -15
+KPX Gcaron Wacute -15
+KPX Gcaron Wgrave -15
+KPX Gcaron uni021A -15
+KPX Gcaron AEacute -15
+KPX Gcaron Ydieresis -15
+KPX Gcaron Ycircumflex -15
+KPX Gcaron Wcircumflex -15
+KPX Gcaron Tcaron -15
+KPX Gcaron Aogonek -15
+KPX Gcaron Amacron -15
+KPX Gcaron AE -15
+KPX Gcaron Aring -15
+KPX Gcaron Adieresis -15
+KPX Gcaron Y -15
+KPX Gcaron W -15
+KPX Gcaron V -20
+KPX Gcaron T -15
+KPX Gcaron A -15
+KPX gcaron rdotaccent 15
+KPX gcaron rcaron 15
+KPX gcaron rcommaaccent 15
+KPX gcaron racute 15
+KPX gcaron ecaron -15
+KPX gcaron eogonek -15
+KPX gcaron edotaccent -15
+KPX gcaron ebreve -15
+KPX gcaron emacron -15
+KPX gcaron edieresis -15
+KPX gcaron r 15
+KPX gcaron e -15
+KPX Oogonek ydieresis.sc -30
+KPX Oogonek ae.sc -45
+KPX Oogonek aring.sc -40
+KPX Oogonek adieresis.sc -40
+KPX Oogonek y.sc -30
+KPX Oogonek x.sc -35
+KPX Oogonek w.sc -25
+KPX Oogonek v.sc -40
+KPX Oogonek a.sc -40
+KPX Oogonek ycircumflex.sc -30
+KPX Oogonek wgrave.sc -25
+KPX Oogonek wdieresis.sc -25
+KPX Oogonek wcircumflex.sc -25
+KPX Oogonek wacute.sc -25
+KPX Oogonek aeacute.sc -45
+KPX Oogonek aogonek.sc -40
+KPX Oogonek amacron.sc -40
+KPX Oogonek Wdieresis -30
+KPX Oogonek Wacute -30
+KPX Oogonek Wgrave -30
+KPX Oogonek AEacute -55
+KPX Oogonek Ydieresis -35
+KPX Oogonek Ycircumflex -35
+KPX Oogonek Wcircumflex -30
+KPX Oogonek Aogonek -50
+KPX Oogonek Amacron -50
+KPX Oogonek AE -55
+KPX Oogonek Aring -50
+KPX Oogonek Adieresis -50
+KPX Oogonek Y -35
+KPX Oogonek X -40
+KPX Oogonek W -30
+KPX Oogonek V -50
+KPX Oogonek A -50
+KPX oogonek T_h -90
+KPX oogonek wdieresis -20
+KPX oogonek wacute -20
+KPX oogonek wgrave -20
+KPX oogonek uni021A -90
+KPX oogonek wcircumflex -20
+KPX oogonek Tcaron -90
+KPX oogonek x -15
+KPX oogonek w -20
+KPX oogonek v -15
+KPX oogonek T -90
+KPX Gacute T_h -15
+KPX Gacute ydieresis.sc -15
+KPX Gacute ae.sc -15
+KPX Gacute aring.sc -15
+KPX Gacute adieresis.sc -15
+KPX Gacute y.sc -15
+KPX Gacute w.sc -15
+KPX Gacute v.sc -15
+KPX Gacute t.sc -15
+KPX Gacute a.sc -15
+KPX Gacute ycircumflex.sc -15
+KPX Gacute wgrave.sc -15
+KPX Gacute wdieresis.sc -15
+KPX Gacute wcircumflex.sc -15
+KPX Gacute wacute.sc -15
+KPX Gacute uni021B.sc -15
+KPX Gacute tcaron.sc -15
+KPX Gacute aeacute.sc -15
+KPX Gacute aogonek.sc -15
+KPX Gacute amacron.sc -15
+KPX Gacute Wdieresis -15
+KPX Gacute Wacute -15
+KPX Gacute Wgrave -15
+KPX Gacute uni021A -15
+KPX Gacute AEacute -15
+KPX Gacute Ydieresis -15
+KPX Gacute Ycircumflex -15
+KPX Gacute Wcircumflex -15
+KPX Gacute Tcaron -15
+KPX Gacute Aogonek -15
+KPX Gacute Amacron -15
+KPX Gacute AE -15
+KPX Gacute Aring -15
+KPX Gacute Adieresis -15
+KPX Gacute Y -15
+KPX Gacute W -15
+KPX Gacute V -20
+KPX Gacute T -15
+KPX Gacute A -15
+KPX gacute rdotaccent 15
+KPX gacute rcaron 15
+KPX gacute rcommaaccent 15
+KPX gacute racute 15
+KPX gacute ecaron -15
+KPX gacute eogonek -15
+KPX gacute edotaccent -15
+KPX gacute ebreve -15
+KPX gacute emacron -15
+KPX gacute edieresis -15
+KPX gacute r 15
+KPX gacute e -15
+KPX aeacute ycircumflex -10
+KPX aeacute ydieresis -10
+KPX aeacute y -10
+KPX uni0218 ae.sc -25
+KPX uni0218 aring.sc -20
+KPX uni0218 adieresis.sc -20
+KPX uni0218 a.sc -20
+KPX uni0218 aeacute.sc -25
+KPX uni0218 aogonek.sc -20
+KPX uni0218 amacron.sc -20
+KPX uni0218 uni021B -15
+KPX uni0218 AEacute -30
+KPX uni0218 tcaron -15
+KPX uni0218 Aogonek -25
+KPX uni0218 Amacron -25
+KPX uni0218 AE -30
+KPX uni0218 Aring -25
+KPX uni0218 Adieresis -25
+KPX uni0218 t -15
+KPX uni0218 A -25
+KPX uni021A ydieresis.sc 15
+KPX uni021A yacute.sc 20
+KPX uni021A oslash.sc -10
+KPX uni021A odieresis.sc -5
+KPX uni021A otilde.sc -5
+KPX uni021A ocircumflex.sc -5
+KPX uni021A oacute.sc -5
+KPX uni021A ograve.sc -5
+KPX uni021A ccedilla.sc -10
+KPX uni021A ae.sc -55
+KPX uni021A aring.sc -25
+KPX uni021A adieresis.sc -25
+KPX uni021A atilde.sc -25
+KPX uni021A acircumflex.sc -25
+KPX uni021A aacute.sc -35
+KPX uni021A agrave.sc -25
+KPX uni021A y.sc 25
+KPX uni021A w.sc 25
+KPX uni021A v.sc 25
+KPX uni021A o.sc -10
+KPX uni021A j.sc 15
+KPX uni021A g.sc -15
+KPX uni021A c.sc -10
+KPX uni021A a.sc -45
+KPX uni021A ygrave.sc 15
+KPX uni021A ycircumflex.sc 15
+KPX uni021A wgrave.sc 15
+KPX uni021A wdieresis.sc 15
+KPX uni021A wcircumflex.sc 15
+KPX uni021A wacute.sc 20
+KPX uni021A omacron.sc -5
+KPX uni021A ohungarumlaut.sc -5
+KPX uni021A obreve.sc -5
+KPX uni021A jcircumflex.sc 10
+KPX uni021A gdotaccent.sc -5
+KPX uni021A gcommaaccent.sc -15
+KPX uni021A gcircumflex.sc -5
+KPX uni021A gbreve.sc -5
+KPX uni021A cdotaccent.sc -5
+KPX uni021A ccircumflex.sc -5
+KPX uni021A ccaron.sc -5
+KPX uni021A cacute.sc -5
+KPX uni021A aeacute.sc -55
+KPX uni021A aogonek.sc -45
+KPX uni021A amacron.sc -25
+KPX uni021A abreve.sc -25
+KPX uni021A jacute -10
+KPX uni021A Jacute 20
+KPX uni021A ytilde.sc 15
+KPX uni021A yhookabove.sc 15
+KPX uni021A oogonek.sc -10
+KPX uni021A ohorntilde.sc -5
+KPX uni021A ohornhookabove.sc -5
+KPX uni021A ohorngrave.sc -5
+KPX uni021A ohorndotbelow.sc -5
+KPX uni021A ohornacute.sc -5
+KPX uni021A ohookabove.sc -5
+KPX uni021A oe.sc -25
+KPX uni021A ocircumflexdotbelow.sc -5
+KPX uni021A jacute.sc 15
+KPX uni021A gcaron.sc -5
+KPX uni021A gacute.sc -10
+KPX uni021A ahookabove.sc -25
+KPX uni021A acircumflexdotbelow.sc -25
+KPX uni021A abrevedotbelow.sc -25
+KPX uni021A guilsinglleft -125
+KPX uni021A ytilde -50
+KPX uni021A yhookabove -50
+KPX uni021A ygrave -50
+KPX uni021A uhorndotbelow -50
+KPX uni021A uhorntilde -50
+KPX uni021A uhornhookabove -50
+KPX uni021A uhorngrave -50
+KPX uni021A uhornacute -50
+KPX uni021A uhookabove -50
+KPX uni021A ohorndotbelow -45
+KPX uni021A ohorntilde -45
+KPX uni021A ohornhookabove -45
+KPX uni021A ohorngrave -45
+KPX uni021A ohornacute -45
+KPX uni021A ocircumflexdotbelow -45
+KPX uni021A ohookabove -45
+KPX uni021A ihookabove -5
+KPX uni021A ecircumflexdotbelow -45
+KPX uni021A etilde -45
+KPX uni021A ehookabove -45
+KPX uni021A abrevedotbelow -35
+KPX uni021A acircumflexdotbelow -35
+KPX uni021A ahookabove -35
+KPX uni021A wdieresis -50
+KPX uni021A Wdieresis 30
+KPX uni021A wacute -70
+KPX uni021A Wacute 30
+KPX uni021A wgrave -50
+KPX uni021A Wgrave 30
+KPX uni021A rdotaccent -30
+KPX uni021A uni0219 -65
+KPX uni021A aeacute -60
+KPX uni021A AEacute -80
+KPX uni021A gacute -60
+KPX uni021A Gacute -15
+KPX uni021A oogonek -90
+KPX uni021A Oogonek -10
+KPX uni021A gcaron -40
+KPX uni021A Gcaron -15
+KPX uni021A Ydieresis 30
+KPX uni021A ycircumflex -50
+KPX uni021A Ycircumflex 30
+KPX uni021A wcircumflex -50
+KPX uni021A Wcircumflex 30
+KPX uni021A uogonek -100
+KPX uni021A uhungarumlaut -50
+KPX uni021A uring -50
+KPX uni021A ubreve -50
+KPX uni021A umacron -50
+KPX uni021A utilde -50
+KPX uni021A scaron -35
+KPX uni021A scedilla -65
+KPX uni021A scircumflex -35
+KPX uni021A sacute -50
+KPX uni021A rcaron -30
+KPX uni021A rcommaaccent -60
+KPX uni021A racute -45
+KPX uni021A oe -50
+KPX uni021A OE -35
+KPX uni021A ohungarumlaut -45
+KPX uni021A Ohungarumlaut -10
+KPX uni021A obreve -45
+KPX uni021A Obreve -10
+KPX uni021A omacron -45
+KPX uni021A Omacron -10
+KPX uni021A jcircumflex -5
+KPX uni021A Jcircumflex 20
+KPX uni021A iogonek -10
+KPX uni021A ibreve -5
+KPX uni021A imacron -5
+KPX uni021A itilde -5
+KPX uni021A gcommaaccent -80
+KPX uni021A Gcommaaccent -15
+KPX uni021A gdotaccent -40
+KPX uni021A Gdotaccent -15
+KPX uni021A gbreve -40
+KPX uni021A Gbreve -15
+KPX uni021A gcircumflex -40
+KPX uni021A Gcircumflex -15
+KPX uni021A ecaron -45
+KPX uni021A eogonek -90
+KPX uni021A edotaccent -45
+KPX uni021A ebreve -45
+KPX uni021A emacron -45
+KPX uni021A ccaron -45
+KPX uni021A Ccaron -10
+KPX uni021A cdotaccent -45
+KPX uni021A Cdotaccent -10
+KPX uni021A ccircumflex -45
+KPX uni021A Ccircumflex -10
+KPX uni021A cacute -70
+KPX uni021A Cacute -10
+KPX uni021A aogonek -70
+KPX uni021A Aogonek -55
+KPX uni021A abreve -35
+KPX uni021A amacron -35
+KPX uni021A Amacron -55
+KPX uni021A ydieresis -50
+KPX uni021A yacute -70
+KPX uni021A udieresis -50
+KPX uni021A ucircumflex -50
+KPX uni021A uacute -75
+KPX uni021A ugrave -50
+KPX uni021A oslash -90
+KPX uni021A odieresis -45
+KPX uni021A otilde -45
+KPX uni021A ocircumflex -45
+KPX uni021A oacute -70
+KPX uni021A ograve -45
+KPX uni021A idieresis -5
+KPX uni021A icircumflex -5
+KPX uni021A iacute -10
+KPX uni021A igrave -5
+KPX uni021A edieresis -45
+KPX uni021A ecircumflex -45
+KPX uni021A eacute -70
+KPX uni021A egrave -45
+KPX uni021A ccedilla -90
+KPX uni021A ae -60
+KPX uni021A aring -35
+KPX uni021A adieresis -35
+KPX uni021A atilde -35
+KPX uni021A acircumflex -35
+KPX uni021A aacute -55
+KPX uni021A agrave -35
+KPX uni021A Oslash -10
+KPX uni021A Odieresis -10
+KPX uni021A Ccedilla -10
+KPX uni021A AE -80
+KPX uni021A Aring -55
+KPX uni021A Adieresis -55
+KPX uni021A guillemotleft -100
+KPX uni021A y -95
+KPX uni021A w -95
+KPX uni021A v -95
+KPX uni021A u -100
+KPX uni021A s -65
+KPX uni021A r -60
+KPX uni021A o -90
+KPX uni021A j -10
+KPX uni021A i -10
+KPX uni021A g -80
+KPX uni021A e -90
+KPX uni021A c -90
+KPX uni021A a -70
+KPX uni021A Y 30
+KPX uni021A W 30
+KPX uni021A V 30
+KPX uni021A O -10
+KPX uni021A J 20
+KPX uni021A G -15
+KPX uni021A C -10
+KPX uni021A A -55
+KPX uni021A semicolon -70
+KPX uni021A colon -65
+KPX uni021A period -65
+KPX uni021A hyphen -60
+KPX uni021A comma -70
+KPX uni021B quoteright 20
+KPX uni021B hcircumflex 20
+KPX uni021B aogonek 10
+KPX uni021B amacron 10
+KPX uni021B aring 10
+KPX uni021B adieresis 10
+KPX uni021B h 20
+KPX uni021B a 10
+KPX uni021B colon 15
+KPX ringhalfright a.sc -95
+KPX ringhalfright A -85
+KPX ringhalfleft a.sc -95
+KPX ringhalfleft A -85
+KPX Rdotaccent T_h -25
+KPX Rdotaccent ydieresis.sc -25
+KPX Rdotaccent udieresis.sc -35
+KPX Rdotaccent ucircumflex.sc -35
+KPX Rdotaccent oslash.sc -30
+KPX Rdotaccent odieresis.sc -30
+KPX Rdotaccent ccedilla.sc -30
+KPX Rdotaccent y.sc -25
+KPX Rdotaccent w.sc -35
+KPX Rdotaccent v.sc -35
+KPX Rdotaccent u.sc -35
+KPX Rdotaccent t.sc -20
+KPX Rdotaccent o.sc -30
+KPX Rdotaccent g.sc -30
+KPX Rdotaccent c.sc -30
+KPX Rdotaccent ycircumflex.sc -25
+KPX Rdotaccent wgrave.sc -35
+KPX Rdotaccent wdieresis.sc -35
+KPX Rdotaccent wcircumflex.sc -35
+KPX Rdotaccent wacute.sc -35
+KPX Rdotaccent uring.sc -35
+KPX Rdotaccent uogonek.sc -35
+KPX Rdotaccent umacron.sc -35
+KPX Rdotaccent uhungarumlaut.sc -35
+KPX Rdotaccent ubreve.sc -35
+KPX Rdotaccent uni021B.sc -20
+KPX Rdotaccent tcaron.sc -20
+KPX Rdotaccent omacron.sc -30
+KPX Rdotaccent ohungarumlaut.sc -30
+KPX Rdotaccent obreve.sc -30
+KPX Rdotaccent gdotaccent.sc -30
+KPX Rdotaccent gcommaaccent.sc -30
+KPX Rdotaccent gcircumflex.sc -30
+KPX Rdotaccent gbreve.sc -30
+KPX Rdotaccent cdotaccent.sc -30
+KPX Rdotaccent ccircumflex.sc -30
+KPX Rdotaccent ccaron.sc -30
+KPX Rdotaccent cacute.sc -30
+KPX Rdotaccent oogonek.sc -30
+KPX Rdotaccent oe.sc -25
+KPX Rdotaccent gcaron.sc -30
+KPX Rdotaccent gacute.sc -30
+KPX Rdotaccent Wdieresis -40
+KPX Rdotaccent Wacute -40
+KPX Rdotaccent Wgrave -40
+KPX Rdotaccent uni021A -25
+KPX Rdotaccent Gacute -35
+KPX Rdotaccent oogonek -10
+KPX Rdotaccent Oogonek -35
+KPX Rdotaccent Gcaron -35
+KPX Rdotaccent Ydieresis -30
+KPX Rdotaccent ycircumflex -25
+KPX Rdotaccent Ycircumflex -30
+KPX Rdotaccent Wcircumflex -40
+KPX Rdotaccent uogonek -20
+KPX Rdotaccent Uogonek -40
+KPX Rdotaccent uhungarumlaut -20
+KPX Rdotaccent Uhungarumlaut -40
+KPX Rdotaccent uring -20
+KPX Rdotaccent Uring -40
+KPX Rdotaccent ubreve -20
+KPX Rdotaccent Ubreve -40
+KPX Rdotaccent umacron -20
+KPX Rdotaccent Umacron -40
+KPX Rdotaccent Tcaron -25
+KPX Rdotaccent oe -15
+KPX Rdotaccent OE -30
+KPX Rdotaccent ohungarumlaut -10
+KPX Rdotaccent Ohungarumlaut -35
+KPX Rdotaccent obreve -10
+KPX Rdotaccent Obreve -35
+KPX Rdotaccent omacron -10
+KPX Rdotaccent Omacron -35
+KPX Rdotaccent Gcommaaccent -35
+KPX Rdotaccent Gdotaccent -35
+KPX Rdotaccent Gbreve -35
+KPX Rdotaccent Gcircumflex -35
+KPX Rdotaccent ecaron -10
+KPX Rdotaccent eogonek -10
+KPX Rdotaccent edotaccent -10
+KPX Rdotaccent ebreve -10
+KPX Rdotaccent emacron -10
+KPX Rdotaccent Ccaron -35
+KPX Rdotaccent Cdotaccent -35
+KPX Rdotaccent Ccircumflex -35
+KPX Rdotaccent Cacute -35
+KPX Rdotaccent aogonek 10
+KPX Rdotaccent amacron 10
+KPX Rdotaccent ydieresis -25
+KPX Rdotaccent udieresis -20
+KPX Rdotaccent ucircumflex -20
+KPX Rdotaccent oslash -10
+KPX Rdotaccent odieresis -10
+KPX Rdotaccent edieresis -10
+KPX Rdotaccent aring 10
+KPX Rdotaccent adieresis 10
+KPX Rdotaccent Udieresis -40
+KPX Rdotaccent Ucircumflex -40
+KPX Rdotaccent Oslash -35
+KPX Rdotaccent Odieresis -35
+KPX Rdotaccent Ccedilla -35
+KPX Rdotaccent y -25
+KPX Rdotaccent u -20
+KPX Rdotaccent o -10
+KPX Rdotaccent e -10
+KPX Rdotaccent a 10
+KPX Rdotaccent Y -30
+KPX Rdotaccent W -40
+KPX Rdotaccent V -40
+KPX Rdotaccent U -40
+KPX Rdotaccent T -25
+KPX Rdotaccent O -35
+KPX Rdotaccent G -35
+KPX Rdotaccent C -35
+KPX Rdotaccent hyphen -20
+KPX rdotaccent ffl 20
+KPX rdotaccent ffi 20
+KPX rdotaccent fl 20
+KPX rdotaccent fi 20
+KPX rdotaccent ff 20
+KPX rdotaccent jacute 20
+KPX rdotaccent f_k 20
+KPX rdotaccent quoteright 45
+KPX rdotaccent wdieresis 30
+KPX rdotaccent wacute 30
+KPX rdotaccent wgrave 30
+KPX rdotaccent rdotaccent 25
+KPX rdotaccent uni021B 25
+KPX rdotaccent uni0219 15
+KPX rdotaccent gacute 10
+KPX rdotaccent gcaron 10
+KPX rdotaccent ycircumflex 35
+KPX rdotaccent wcircumflex 30
+KPX rdotaccent uogonek 25
+KPX rdotaccent uhungarumlaut 25
+KPX rdotaccent uring 25
+KPX rdotaccent ubreve 25
+KPX rdotaccent umacron 25
+KPX rdotaccent tcaron 25
+KPX rdotaccent scaron 15
+KPX rdotaccent scedilla 15
+KPX rdotaccent scircumflex 15
+KPX rdotaccent sacute 15
+KPX rdotaccent rcaron 25
+KPX rdotaccent rcommaaccent 25
+KPX rdotaccent racute 25
+KPX rdotaccent ncaron 25
+KPX rdotaccent ncommaaccent 25
+KPX rdotaccent nacute 25
+KPX rdotaccent lslash -10
+KPX rdotaccent lcaron -10
+KPX rdotaccent lcommaaccent -10
+KPX rdotaccent lacute -10
+KPX rdotaccent jcircumflex 20
+KPX rdotaccent iogonek 20
+KPX rdotaccent ibreve 20
+KPX rdotaccent imacron 20
+KPX rdotaccent gcommaaccent 10
+KPX rdotaccent gdotaccent 10
+KPX rdotaccent gbreve 10
+KPX rdotaccent gcircumflex 10
+KPX rdotaccent ydieresis 35
+KPX rdotaccent udieresis 25
+KPX rdotaccent ucircumflex 25
+KPX rdotaccent ntilde 25
+KPX rdotaccent idieresis 20
+KPX rdotaccent icircumflex 20
+KPX rdotaccent y 35
+KPX rdotaccent x 30
+KPX rdotaccent w 30
+KPX rdotaccent v 35
+KPX rdotaccent u 25
+KPX rdotaccent t 25
+KPX rdotaccent s 15
+KPX rdotaccent r 25
+KPX rdotaccent p 25
+KPX rdotaccent n 25
+KPX rdotaccent m 25
+KPX rdotaccent l -10
+KPX rdotaccent j 20
+KPX rdotaccent i 20
+KPX rdotaccent g 10
+KPX rdotaccent f 20
+KPX rdotaccent colon 15
+KPX rdotaccent period -20
+KPX rdotaccent hyphen 20
+KPX rdotaccent comma -25
+KPX Wgrave zcaron -53
+KPX Wgrave zdotaccent -53
+KPX Wgrave zacute -53
+KPX Wgrave z -53
+KPX Wgrave ccaron -66
+KPX Wgrave cdotaccent -66
+KPX Wgrave ccircumflex -66
+KPX Wgrave cacute -66
+KPX Wgrave ccedilla -66
+KPX Wgrave c -66
+KPX Wgrave scaron -70
+KPX Wgrave scedilla -70
+KPX Wgrave scircumflex -70
+KPX Wgrave sacute -70
+KPX Wgrave s -70
+KPX Wgrave T_h 30
+KPX Wgrave oslash.sc -30
+KPX Wgrave odieresis.sc -15
+KPX Wgrave otilde.sc -15
+KPX Wgrave ocircumflex.sc -15
+KPX Wgrave oacute.sc -20
+KPX Wgrave ograve.sc -15
+KPX Wgrave ccedilla.sc -30
+KPX Wgrave ae.sc -55
+KPX Wgrave aring.sc -35
+KPX Wgrave adieresis.sc -35
+KPX Wgrave atilde.sc -35
+KPX Wgrave acircumflex.sc -35
+KPX Wgrave aacute.sc -50
+KPX Wgrave agrave.sc -35
+KPX Wgrave t.sc 25
+KPX Wgrave s.sc -20
+KPX Wgrave o.sc -30
+KPX Wgrave g.sc -35
+KPX Wgrave c.sc -30
+KPX Wgrave a.sc -65
+KPX Wgrave uni021B.sc 25
+KPX Wgrave tcaron.sc 15
+KPX Wgrave uni0219.sc -20
+KPX Wgrave scircumflex.sc -10
+KPX Wgrave scedilla.sc -20
+KPX Wgrave sacute.sc -15
+KPX Wgrave omacron.sc -15
+KPX Wgrave ohungarumlaut.sc -15
+KPX Wgrave obreve.sc -15
+KPX Wgrave gdotaccent.sc -15
+KPX Wgrave gcommaaccent.sc -35
+KPX Wgrave gcircumflex.sc -15
+KPX Wgrave gbreve.sc -15
+KPX Wgrave cdotaccent.sc -15
+KPX Wgrave ccircumflex.sc -15
+KPX Wgrave ccaron.sc -15
+KPX Wgrave cacute.sc -20
+KPX Wgrave aeacute.sc -55
+KPX Wgrave aogonek.sc -65
+KPX Wgrave amacron.sc -35
+KPX Wgrave abreve.sc -35
+KPX Wgrave scaron.sc -10
+KPX Wgrave oogonek.sc -30
+KPX Wgrave ohorntilde.sc -15
+KPX Wgrave ohornhookabove.sc -15
+KPX Wgrave ohorngrave.sc -15
+KPX Wgrave ohorndotbelow.sc -15
+KPX Wgrave ohornacute.sc -15
+KPX Wgrave ohookabove.sc -15
+KPX Wgrave oe.sc -25
+KPX Wgrave ocircumflexdotbelow.sc -15
+KPX Wgrave gcaron.sc -15
+KPX Wgrave gacute.sc -25
+KPX Wgrave ahookabove.sc -35
+KPX Wgrave acircumflexdotbelow.sc -35
+KPX Wgrave abrevedotbelow.sc -35
+KPX Wgrave guilsinglleft -85
+KPX Wgrave ytilde -10
+KPX Wgrave yhookabove -10
+KPX Wgrave ygrave -10
+KPX Wgrave uhorndotbelow -20
+KPX Wgrave uhorntilde -20
+KPX Wgrave uhornhookabove -20
+KPX Wgrave uhorngrave -20
+KPX Wgrave uhornacute -20
+KPX Wgrave uhookabove -20
+KPX Wgrave ohorndotbelow -25
+KPX Wgrave ohorntilde -25
+KPX Wgrave ohornhookabove -25
+KPX Wgrave ohorngrave -25
+KPX Wgrave ohornacute -25
+KPX Wgrave ocircumflexdotbelow -25
+KPX Wgrave ohookabove -25
+KPX Wgrave ecircumflexdotbelow -30
+KPX Wgrave etilde -30
+KPX Wgrave ehookabove -30
+KPX Wgrave abrevedotbelow -30
+KPX Wgrave acircumflexdotbelow -30
+KPX Wgrave ahookabove -30
+KPX Wgrave rdotaccent -20
+KPX Wgrave uni021A 30
+KPX Wgrave uni0218 -25
+KPX Wgrave aeacute -60
+KPX Wgrave AEacute -80
+KPX Wgrave gacute -40
+KPX Wgrave Gacute -40
+KPX Wgrave oogonek -50
+KPX Wgrave Oogonek -35
+KPX Wgrave gcaron -30
+KPX Wgrave Gcaron -40
+KPX Wgrave ycircumflex -10
+KPX Wgrave uogonek -35
+KPX Wgrave uhungarumlaut -20
+KPX Wgrave uring -20
+KPX Wgrave ubreve -20
+KPX Wgrave umacron -20
+KPX Wgrave utilde -20
+KPX Wgrave Tcaron 30
+KPX Wgrave Scaron -25
+KPX Wgrave Scedilla -25
+KPX Wgrave Scircumflex -25
+KPX Wgrave Sacute -25
+KPX Wgrave rcaron -20
+KPX Wgrave rcommaaccent -35
+KPX Wgrave racute -25
+KPX Wgrave oe -50
+KPX Wgrave OE -35
+KPX Wgrave ohungarumlaut -25
+KPX Wgrave Ohungarumlaut -35
+KPX Wgrave obreve -25
+KPX Wgrave Obreve -35
+KPX Wgrave omacron -25
+KPX Wgrave Omacron -35
+KPX Wgrave gcommaaccent -55
+KPX Wgrave Gcommaaccent -40
+KPX Wgrave gdotaccent -30
+KPX Wgrave Gdotaccent -40
+KPX Wgrave gbreve -30
+KPX Wgrave Gbreve -40
+KPX Wgrave gcircumflex -30
+KPX Wgrave Gcircumflex -40
+KPX Wgrave ecaron -30
+KPX Wgrave eogonek -55
+KPX Wgrave edotaccent -30
+KPX Wgrave ebreve -30
+KPX Wgrave emacron -30
+KPX Wgrave Ccaron -35
+KPX Wgrave Cdotaccent -35
+KPX Wgrave Ccircumflex -35
+KPX Wgrave Cacute -35
+KPX Wgrave aogonek -60
+KPX Wgrave Aogonek -80
+KPX Wgrave abreve -30
+KPX Wgrave amacron -30
+KPX Wgrave Amacron -80
+KPX Wgrave ydieresis -10
+KPX Wgrave yacute -15
+KPX Wgrave udieresis -20
+KPX Wgrave ucircumflex -20
+KPX Wgrave uacute -25
+KPX Wgrave ugrave -20
+KPX Wgrave oslash -50
+KPX Wgrave odieresis -25
+KPX Wgrave otilde -25
+KPX Wgrave ocircumflex -25
+KPX Wgrave oacute -40
+KPX Wgrave ograve -25
+KPX Wgrave edieresis -30
+KPX Wgrave ecircumflex -30
+KPX Wgrave eacute -40
+KPX Wgrave egrave -30
+KPX Wgrave ae -60
+KPX Wgrave aring -30
+KPX Wgrave adieresis -30
+KPX Wgrave atilde -30
+KPX Wgrave acircumflex -30
+KPX Wgrave aacute -45
+KPX Wgrave agrave -30
+KPX Wgrave Oslash -35
+KPX Wgrave Odieresis -35
+KPX Wgrave Ccedilla -35
+KPX Wgrave AE -80
+KPX Wgrave Aring -80
+KPX Wgrave Adieresis -80
+KPX Wgrave guillemotleft -60
+KPX Wgrave y -20
+KPX Wgrave u -35
+KPX Wgrave r -35
+KPX Wgrave o -50
+KPX Wgrave g -55
+KPX Wgrave e -55
+KPX Wgrave a -60
+KPX Wgrave T 30
+KPX Wgrave S -25
+KPX Wgrave O -35
+KPX Wgrave G -40
+KPX Wgrave C -35
+KPX Wgrave A -80
+KPX Wgrave semicolon -55
+KPX Wgrave colon -40
+KPX Wgrave period -50
+KPX Wgrave hyphen -20
+KPX Wgrave comma -60
+KPX wgrave aeacute -20
+KPX wgrave gacute -10
+KPX wgrave oogonek -25
+KPX wgrave gcaron -10
+KPX wgrave oe -25
+KPX wgrave ohungarumlaut -25
+KPX wgrave obreve -25
+KPX wgrave omacron -25
+KPX wgrave lslash -20
+KPX wgrave lcaron -20
+KPX wgrave lcommaaccent -20
+KPX wgrave lacute -20
+KPX wgrave gcommaaccent -10
+KPX wgrave gdotaccent -10
+KPX wgrave gbreve -10
+KPX wgrave gcircumflex -10
+KPX wgrave ecaron -30
+KPX wgrave eogonek -30
+KPX wgrave edotaccent -30
+KPX wgrave ebreve -30
+KPX wgrave emacron -30
+KPX wgrave ccaron -35
+KPX wgrave cdotaccent -35
+KPX wgrave ccircumflex -35
+KPX wgrave cacute -35
+KPX wgrave aogonek -20
+KPX wgrave amacron -20
+KPX wgrave oslash -25
+KPX wgrave odieresis -25
+KPX wgrave edieresis -30
+KPX wgrave ccedilla -35
+KPX wgrave ae -20
+KPX wgrave aring -20
+KPX wgrave adieresis -20
+KPX wgrave o -25
+KPX wgrave l -20
+KPX wgrave g -10
+KPX wgrave e -30
+KPX wgrave c -35
+KPX wgrave a -20
+KPX wgrave period -45
+KPX wgrave comma -55
+KPX Wacute zcaron -53
+KPX Wacute zdotaccent -53
+KPX Wacute zacute -53
+KPX Wacute z -53
+KPX Wacute ccaron -66
+KPX Wacute cdotaccent -66
+KPX Wacute ccircumflex -66
+KPX Wacute cacute -66
+KPX Wacute ccedilla -66
+KPX Wacute c -66
+KPX Wacute scaron -70
+KPX Wacute scedilla -70
+KPX Wacute scircumflex -70
+KPX Wacute sacute -70
+KPX Wacute s -70
+KPX Wacute T_h 30
+KPX Wacute oslash.sc -30
+KPX Wacute odieresis.sc -15
+KPX Wacute otilde.sc -15
+KPX Wacute ocircumflex.sc -15
+KPX Wacute oacute.sc -20
+KPX Wacute ograve.sc -15
+KPX Wacute ccedilla.sc -30
+KPX Wacute ae.sc -55
+KPX Wacute aring.sc -35
+KPX Wacute adieresis.sc -35
+KPX Wacute atilde.sc -35
+KPX Wacute acircumflex.sc -35
+KPX Wacute aacute.sc -50
+KPX Wacute agrave.sc -35
+KPX Wacute t.sc 25
+KPX Wacute s.sc -20
+KPX Wacute o.sc -30
+KPX Wacute g.sc -35
+KPX Wacute c.sc -30
+KPX Wacute a.sc -65
+KPX Wacute uni021B.sc 25
+KPX Wacute tcaron.sc 15
+KPX Wacute uni0219.sc -20
+KPX Wacute scircumflex.sc -10
+KPX Wacute scedilla.sc -20
+KPX Wacute sacute.sc -15
+KPX Wacute omacron.sc -15
+KPX Wacute ohungarumlaut.sc -15
+KPX Wacute obreve.sc -15
+KPX Wacute gdotaccent.sc -15
+KPX Wacute gcommaaccent.sc -35
+KPX Wacute gcircumflex.sc -15
+KPX Wacute gbreve.sc -15
+KPX Wacute cdotaccent.sc -15
+KPX Wacute ccircumflex.sc -15
+KPX Wacute ccaron.sc -15
+KPX Wacute cacute.sc -20
+KPX Wacute aeacute.sc -55
+KPX Wacute aogonek.sc -65
+KPX Wacute amacron.sc -35
+KPX Wacute abreve.sc -35
+KPX Wacute scaron.sc -10
+KPX Wacute oogonek.sc -30
+KPX Wacute ohorntilde.sc -15
+KPX Wacute ohornhookabove.sc -15
+KPX Wacute ohorngrave.sc -15
+KPX Wacute ohorndotbelow.sc -15
+KPX Wacute ohornacute.sc -15
+KPX Wacute ohookabove.sc -15
+KPX Wacute oe.sc -25
+KPX Wacute ocircumflexdotbelow.sc -15
+KPX Wacute gcaron.sc -15
+KPX Wacute gacute.sc -25
+KPX Wacute ahookabove.sc -35
+KPX Wacute acircumflexdotbelow.sc -35
+KPX Wacute abrevedotbelow.sc -35
+KPX Wacute guilsinglleft -85
+KPX Wacute ytilde -10
+KPX Wacute yhookabove -10
+KPX Wacute ygrave -10
+KPX Wacute uhorndotbelow -20
+KPX Wacute uhorntilde -20
+KPX Wacute uhornhookabove -20
+KPX Wacute uhorngrave -20
+KPX Wacute uhornacute -20
+KPX Wacute uhookabove -20
+KPX Wacute ohorndotbelow -25
+KPX Wacute ohorntilde -25
+KPX Wacute ohornhookabove -25
+KPX Wacute ohorngrave -25
+KPX Wacute ohornacute -25
+KPX Wacute ocircumflexdotbelow -25
+KPX Wacute ohookabove -25
+KPX Wacute ecircumflexdotbelow -30
+KPX Wacute etilde -30
+KPX Wacute ehookabove -30
+KPX Wacute abrevedotbelow -30
+KPX Wacute acircumflexdotbelow -30
+KPX Wacute ahookabove -30
+KPX Wacute rdotaccent -20
+KPX Wacute uni021A 30
+KPX Wacute uni0218 -25
+KPX Wacute aeacute -60
+KPX Wacute AEacute -80
+KPX Wacute gacute -40
+KPX Wacute Gacute -40
+KPX Wacute oogonek -50
+KPX Wacute Oogonek -35
+KPX Wacute gcaron -30
+KPX Wacute Gcaron -40
+KPX Wacute ycircumflex -10
+KPX Wacute uogonek -35
+KPX Wacute uhungarumlaut -20
+KPX Wacute uring -20
+KPX Wacute ubreve -20
+KPX Wacute umacron -20
+KPX Wacute utilde -20
+KPX Wacute Tcaron 30
+KPX Wacute Scaron -25
+KPX Wacute Scedilla -25
+KPX Wacute Scircumflex -25
+KPX Wacute Sacute -25
+KPX Wacute rcaron -20
+KPX Wacute rcommaaccent -35
+KPX Wacute racute -25
+KPX Wacute oe -50
+KPX Wacute OE -35
+KPX Wacute ohungarumlaut -25
+KPX Wacute Ohungarumlaut -35
+KPX Wacute obreve -25
+KPX Wacute Obreve -35
+KPX Wacute omacron -25
+KPX Wacute Omacron -35
+KPX Wacute gcommaaccent -55
+KPX Wacute Gcommaaccent -40
+KPX Wacute gdotaccent -30
+KPX Wacute Gdotaccent -40
+KPX Wacute gbreve -30
+KPX Wacute Gbreve -40
+KPX Wacute gcircumflex -30
+KPX Wacute Gcircumflex -40
+KPX Wacute ecaron -30
+KPX Wacute eogonek -55
+KPX Wacute edotaccent -30
+KPX Wacute ebreve -30
+KPX Wacute emacron -30
+KPX Wacute Ccaron -35
+KPX Wacute Cdotaccent -35
+KPX Wacute Ccircumflex -35
+KPX Wacute Cacute -35
+KPX Wacute aogonek -60
+KPX Wacute Aogonek -80
+KPX Wacute abreve -30
+KPX Wacute amacron -30
+KPX Wacute Amacron -80
+KPX Wacute ydieresis -10
+KPX Wacute yacute -15
+KPX Wacute udieresis -20
+KPX Wacute ucircumflex -20
+KPX Wacute uacute -25
+KPX Wacute ugrave -20
+KPX Wacute oslash -50
+KPX Wacute odieresis -25
+KPX Wacute otilde -25
+KPX Wacute ocircumflex -25
+KPX Wacute oacute -40
+KPX Wacute ograve -25
+KPX Wacute edieresis -30
+KPX Wacute ecircumflex -30
+KPX Wacute eacute -40
+KPX Wacute egrave -30
+KPX Wacute ae -60
+KPX Wacute aring -30
+KPX Wacute adieresis -30
+KPX Wacute atilde -30
+KPX Wacute acircumflex -30
+KPX Wacute aacute -45
+KPX Wacute agrave -30
+KPX Wacute Oslash -35
+KPX Wacute Odieresis -35
+KPX Wacute Ccedilla -35
+KPX Wacute AE -80
+KPX Wacute Aring -80
+KPX Wacute Adieresis -80
+KPX Wacute guillemotleft -60
+KPX Wacute y -20
+KPX Wacute u -35
+KPX Wacute r -35
+KPX Wacute o -50
+KPX Wacute g -55
+KPX Wacute e -55
+KPX Wacute a -60
+KPX Wacute T 30
+KPX Wacute S -25
+KPX Wacute O -35
+KPX Wacute G -40
+KPX Wacute C -35
+KPX Wacute A -80
+KPX Wacute semicolon -55
+KPX Wacute colon -40
+KPX Wacute period -50
+KPX Wacute hyphen -20
+KPX Wacute comma -60
+KPX wacute aeacute -20
+KPX wacute gacute -10
+KPX wacute oogonek -25
+KPX wacute gcaron -10
+KPX wacute oe -25
+KPX wacute ohungarumlaut -25
+KPX wacute obreve -25
+KPX wacute omacron -25
+KPX wacute lslash -20
+KPX wacute lcaron -20
+KPX wacute lcommaaccent -20
+KPX wacute lacute -20
+KPX wacute gcommaaccent -10
+KPX wacute gdotaccent -10
+KPX wacute gbreve -10
+KPX wacute gcircumflex -10
+KPX wacute ecaron -30
+KPX wacute eogonek -30
+KPX wacute edotaccent -30
+KPX wacute ebreve -30
+KPX wacute emacron -30
+KPX wacute ccaron -35
+KPX wacute cdotaccent -35
+KPX wacute ccircumflex -35
+KPX wacute cacute -35
+KPX wacute aogonek -20
+KPX wacute amacron -20
+KPX wacute oslash -25
+KPX wacute odieresis -25
+KPX wacute edieresis -30
+KPX wacute ccedilla -35
+KPX wacute ae -20
+KPX wacute aring -20
+KPX wacute adieresis -20
+KPX wacute o -25
+KPX wacute l -20
+KPX wacute g -10
+KPX wacute e -30
+KPX wacute c -35
+KPX wacute a -20
+KPX wacute period -45
+KPX wacute comma -55
+KPX Wdieresis zcaron -53
+KPX Wdieresis zdotaccent -53
+KPX Wdieresis zacute -53
+KPX Wdieresis z -53
+KPX Wdieresis ccaron -66
+KPX Wdieresis cdotaccent -66
+KPX Wdieresis ccircumflex -66
+KPX Wdieresis cacute -66
+KPX Wdieresis ccedilla -66
+KPX Wdieresis c -66
+KPX Wdieresis scaron -70
+KPX Wdieresis scedilla -70
+KPX Wdieresis scircumflex -70
+KPX Wdieresis sacute -70
+KPX Wdieresis s -70
+KPX Wdieresis T_h 30
+KPX Wdieresis oslash.sc -30
+KPX Wdieresis odieresis.sc -15
+KPX Wdieresis otilde.sc -15
+KPX Wdieresis ocircumflex.sc -15
+KPX Wdieresis oacute.sc -20
+KPX Wdieresis ograve.sc -15
+KPX Wdieresis ccedilla.sc -30
+KPX Wdieresis ae.sc -55
+KPX Wdieresis aring.sc -35
+KPX Wdieresis adieresis.sc -35
+KPX Wdieresis atilde.sc -35
+KPX Wdieresis acircumflex.sc -35
+KPX Wdieresis aacute.sc -50
+KPX Wdieresis agrave.sc -35
+KPX Wdieresis t.sc 25
+KPX Wdieresis s.sc -20
+KPX Wdieresis o.sc -30
+KPX Wdieresis g.sc -35
+KPX Wdieresis c.sc -30
+KPX Wdieresis a.sc -65
+KPX Wdieresis uni021B.sc 25
+KPX Wdieresis tcaron.sc 15
+KPX Wdieresis uni0219.sc -20
+KPX Wdieresis scircumflex.sc -10
+KPX Wdieresis scedilla.sc -20
+KPX Wdieresis sacute.sc -15
+KPX Wdieresis omacron.sc -15
+KPX Wdieresis ohungarumlaut.sc -15
+KPX Wdieresis obreve.sc -15
+KPX Wdieresis gdotaccent.sc -15
+KPX Wdieresis gcommaaccent.sc -35
+KPX Wdieresis gcircumflex.sc -15
+KPX Wdieresis gbreve.sc -15
+KPX Wdieresis cdotaccent.sc -15
+KPX Wdieresis ccircumflex.sc -15
+KPX Wdieresis ccaron.sc -15
+KPX Wdieresis cacute.sc -20
+KPX Wdieresis aeacute.sc -55
+KPX Wdieresis aogonek.sc -65
+KPX Wdieresis amacron.sc -35
+KPX Wdieresis abreve.sc -35
+KPX Wdieresis scaron.sc -10
+KPX Wdieresis oogonek.sc -30
+KPX Wdieresis ohorntilde.sc -15
+KPX Wdieresis ohornhookabove.sc -15
+KPX Wdieresis ohorngrave.sc -15
+KPX Wdieresis ohorndotbelow.sc -15
+KPX Wdieresis ohornacute.sc -15
+KPX Wdieresis ohookabove.sc -15
+KPX Wdieresis oe.sc -25
+KPX Wdieresis ocircumflexdotbelow.sc -15
+KPX Wdieresis gcaron.sc -15
+KPX Wdieresis gacute.sc -25
+KPX Wdieresis ahookabove.sc -35
+KPX Wdieresis acircumflexdotbelow.sc -35
+KPX Wdieresis abrevedotbelow.sc -35
+KPX Wdieresis guilsinglleft -85
+KPX Wdieresis ytilde -10
+KPX Wdieresis yhookabove -10
+KPX Wdieresis ygrave -10
+KPX Wdieresis uhorndotbelow -20
+KPX Wdieresis uhorntilde -20
+KPX Wdieresis uhornhookabove -20
+KPX Wdieresis uhorngrave -20
+KPX Wdieresis uhornacute -20
+KPX Wdieresis uhookabove -20
+KPX Wdieresis ohorndotbelow -25
+KPX Wdieresis ohorntilde -25
+KPX Wdieresis ohornhookabove -25
+KPX Wdieresis ohorngrave -25
+KPX Wdieresis ohornacute -25
+KPX Wdieresis ocircumflexdotbelow -25
+KPX Wdieresis ohookabove -25
+KPX Wdieresis ecircumflexdotbelow -30
+KPX Wdieresis etilde -30
+KPX Wdieresis ehookabove -30
+KPX Wdieresis abrevedotbelow -30
+KPX Wdieresis acircumflexdotbelow -30
+KPX Wdieresis ahookabove -30
+KPX Wdieresis rdotaccent -20
+KPX Wdieresis uni021A 30
+KPX Wdieresis uni0218 -25
+KPX Wdieresis aeacute -60
+KPX Wdieresis AEacute -80
+KPX Wdieresis gacute -40
+KPX Wdieresis Gacute -40
+KPX Wdieresis oogonek -50
+KPX Wdieresis Oogonek -35
+KPX Wdieresis gcaron -30
+KPX Wdieresis Gcaron -40
+KPX Wdieresis ycircumflex -10
+KPX Wdieresis uogonek -35
+KPX Wdieresis uhungarumlaut -20
+KPX Wdieresis uring -20
+KPX Wdieresis ubreve -20
+KPX Wdieresis umacron -20
+KPX Wdieresis utilde -20
+KPX Wdieresis Tcaron 30
+KPX Wdieresis Scaron -25
+KPX Wdieresis Scedilla -25
+KPX Wdieresis Scircumflex -25
+KPX Wdieresis Sacute -25
+KPX Wdieresis rcaron -20
+KPX Wdieresis rcommaaccent -35
+KPX Wdieresis racute -25
+KPX Wdieresis oe -50
+KPX Wdieresis OE -35
+KPX Wdieresis ohungarumlaut -25
+KPX Wdieresis Ohungarumlaut -35
+KPX Wdieresis obreve -25
+KPX Wdieresis Obreve -35
+KPX Wdieresis omacron -25
+KPX Wdieresis Omacron -35
+KPX Wdieresis gcommaaccent -55
+KPX Wdieresis Gcommaaccent -40
+KPX Wdieresis gdotaccent -30
+KPX Wdieresis Gdotaccent -40
+KPX Wdieresis gbreve -30
+KPX Wdieresis Gbreve -40
+KPX Wdieresis gcircumflex -30
+KPX Wdieresis Gcircumflex -40
+KPX Wdieresis ecaron -30
+KPX Wdieresis eogonek -55
+KPX Wdieresis edotaccent -30
+KPX Wdieresis ebreve -30
+KPX Wdieresis emacron -30
+KPX Wdieresis Ccaron -35
+KPX Wdieresis Cdotaccent -35
+KPX Wdieresis Ccircumflex -35
+KPX Wdieresis Cacute -35
+KPX Wdieresis aogonek -60
+KPX Wdieresis Aogonek -80
+KPX Wdieresis abreve -30
+KPX Wdieresis amacron -30
+KPX Wdieresis Amacron -80
+KPX Wdieresis ydieresis -10
+KPX Wdieresis yacute -15
+KPX Wdieresis udieresis -20
+KPX Wdieresis ucircumflex -20
+KPX Wdieresis uacute -25
+KPX Wdieresis ugrave -20
+KPX Wdieresis oslash -50
+KPX Wdieresis odieresis -25
+KPX Wdieresis otilde -25
+KPX Wdieresis ocircumflex -25
+KPX Wdieresis oacute -40
+KPX Wdieresis ograve -25
+KPX Wdieresis edieresis -30
+KPX Wdieresis ecircumflex -30
+KPX Wdieresis eacute -40
+KPX Wdieresis egrave -30
+KPX Wdieresis ae -60
+KPX Wdieresis aring -30
+KPX Wdieresis adieresis -30
+KPX Wdieresis atilde -30
+KPX Wdieresis acircumflex -30
+KPX Wdieresis aacute -45
+KPX Wdieresis agrave -30
+KPX Wdieresis Oslash -35
+KPX Wdieresis Odieresis -35
+KPX Wdieresis Ccedilla -35
+KPX Wdieresis AE -80
+KPX Wdieresis Aring -80
+KPX Wdieresis Adieresis -80
+KPX Wdieresis guillemotleft -60
+KPX Wdieresis y -20
+KPX Wdieresis u -35
+KPX Wdieresis r -35
+KPX Wdieresis o -50
+KPX Wdieresis g -55
+KPX Wdieresis e -55
+KPX Wdieresis a -60
+KPX Wdieresis T 30
+KPX Wdieresis S -25
+KPX Wdieresis O -35
+KPX Wdieresis G -40
+KPX Wdieresis C -35
+KPX Wdieresis A -80
+KPX Wdieresis semicolon -55
+KPX Wdieresis colon -40
+KPX Wdieresis period -50
+KPX Wdieresis hyphen -20
+KPX Wdieresis comma -60
+KPX wdieresis aeacute -20
+KPX wdieresis gacute -10
+KPX wdieresis oogonek -25
+KPX wdieresis gcaron -10
+KPX wdieresis oe -25
+KPX wdieresis ohungarumlaut -25
+KPX wdieresis obreve -25
+KPX wdieresis omacron -25
+KPX wdieresis lslash -20
+KPX wdieresis lcaron -20
+KPX wdieresis lcommaaccent -20
+KPX wdieresis lacute -20
+KPX wdieresis gcommaaccent -10
+KPX wdieresis gdotaccent -10
+KPX wdieresis gbreve -10
+KPX wdieresis gcircumflex -10
+KPX wdieresis ecaron -30
+KPX wdieresis eogonek -30
+KPX wdieresis edotaccent -30
+KPX wdieresis ebreve -30
+KPX wdieresis emacron -30
+KPX wdieresis ccaron -35
+KPX wdieresis cdotaccent -35
+KPX wdieresis ccircumflex -35
+KPX wdieresis cacute -35
+KPX wdieresis aogonek -20
+KPX wdieresis amacron -20
+KPX wdieresis oslash -25
+KPX wdieresis odieresis -25
+KPX wdieresis edieresis -30
+KPX wdieresis ccedilla -35
+KPX wdieresis ae -20
+KPX wdieresis aring -20
+KPX wdieresis adieresis -20
+KPX wdieresis o -25
+KPX wdieresis l -20
+KPX wdieresis g -10
+KPX wdieresis e -30
+KPX wdieresis c -35
+KPX wdieresis a -20
+KPX wdieresis period -45
+KPX wdieresis comma -55
+KPX Adotbelow T_h -55
+KPX Adotbelow y.sc -55
+KPX Adotbelow u.sc -40
+KPX Adotbelow t.sc -45
+KPX Adotbelow o.sc -40
+KPX Adotbelow c.sc -40
+KPX Adotbelow y -70
+KPX Adotbelow u -25
+KPX Adotbelow t -15
+KPX Adotbelow o -15
+KPX Adotbelow c -15
+KPX Adotbelow Y -65
+KPX Adotbelow U -45
+KPX Adotbelow T -55
+KPX Adotbelow O -45
+KPX Adotbelow C -50
+KPX adotbelow y -20
+KPX Ahookabove y.sc -55
+KPX Ahookabove u.sc -40
+KPX Ahookabove o.sc -40
+KPX Ahookabove y -70
+KPX Ahookabove u -25
+KPX Ahookabove o -15
+KPX Ahookabove Y -65
+KPX Ahookabove U -45
+KPX Ahookabove O -45
+KPX ahookabove y -20
+KPX Acircumflexacute T_h -55
+KPX Acircumflexacute y.sc -55
+KPX Acircumflexacute u.sc -40
+KPX Acircumflexacute t.sc -45
+KPX Acircumflexacute c.sc -40
+KPX Acircumflexacute y -70
+KPX Acircumflexacute u -25
+KPX Acircumflexacute t -15
+KPX Acircumflexacute c -15
+KPX Acircumflexacute Y -65
+KPX Acircumflexacute U -45
+KPX Acircumflexacute T -55
+KPX Acircumflexacute C -50
+KPX acircumflexacute y -20
+KPX Acircumflexgrave y.sc -55
+KPX Acircumflexgrave u.sc -40
+KPX Acircumflexgrave y -70
+KPX Acircumflexgrave u -25
+KPX Acircumflexgrave Y -65
+KPX Acircumflexgrave U -45
+KPX acircumflexgrave y -20
+KPX Acircumflexhookabove y.sc -55
+KPX Acircumflexhookabove u.sc -40
+KPX Acircumflexhookabove y -70
+KPX Acircumflexhookabove u -25
+KPX Acircumflexhookabove Y -65
+KPX Acircumflexhookabove U -45
+KPX acircumflexhookabove y -20
+KPX Acircumflextilde y.sc -55
+KPX Acircumflextilde u.sc -40
+KPX Acircumflextilde y -70
+KPX Acircumflextilde u -25
+KPX Acircumflextilde Y -65
+KPX Acircumflextilde U -45
+KPX acircumflextilde y -20
+KPX Acircumflexdotbelow T_h -55
+KPX Acircumflexdotbelow y.sc -55
+KPX Acircumflexdotbelow u.sc -40
+KPX Acircumflexdotbelow t.sc -45
+KPX Acircumflexdotbelow c.sc -40
+KPX Acircumflexdotbelow y -70
+KPX Acircumflexdotbelow u -25
+KPX Acircumflexdotbelow t -15
+KPX Acircumflexdotbelow c -15
+KPX Acircumflexdotbelow Y -65
+KPX Acircumflexdotbelow U -45
+KPX Acircumflexdotbelow T -55
+KPX Acircumflexdotbelow C -50
+KPX acircumflexdotbelow y -20
+KPX Abreveacute T_h -55
+KPX Abreveacute t.sc -45
+KPX Abreveacute c.sc -40
+KPX Abreveacute t -15
+KPX Abreveacute c -15
+KPX Abreveacute T -55
+KPX Abreveacute C -50
+KPX Abrevedotbelow T_h -55
+KPX Abrevedotbelow t.sc -45
+KPX Abrevedotbelow c.sc -40
+KPX Abrevedotbelow t -15
+KPX Abrevedotbelow c -15
+KPX Abrevedotbelow T -55
+KPX Abrevedotbelow C -50
+KPX idotbelow T_h -15
+KPX idotbelow T -15
+KPX Odotbelow a.sc -40
+KPX Odotbelow A -50
+KPX odotbelow T_h -90
+KPX odotbelow T -90
+KPX Ohookabove a.sc -40
+KPX Ohookabove A -50
+KPX ocircumflexacute T_h -90
+KPX ocircumflexacute T -90
+KPX ocircumflexdotbelow T_h -90
+KPX ocircumflexdotbelow T -90
+KPX ohornacute T_h -90
+KPX ohornacute T -90
+KPX ohorndotbelow T_h -90
+KPX ohorndotbelow T -90
+KPX Udotbelow aring.sc -20
+KPX Udotbelow adieresis.sc -20
+KPX Udotbelow atilde.sc -20
+KPX Udotbelow acircumflex.sc -20
+KPX Udotbelow aacute.sc -30
+KPX Udotbelow agrave.sc -20
+KPX Udotbelow a.sc -40
+KPX Udotbelow amacron.sc -20
+KPX Udotbelow abreve.sc -20
+KPX Udotbelow ahookabove.sc -20
+KPX Udotbelow acircumflexdotbelow.sc -20
+KPX Udotbelow abrevedotbelow.sc -20
+KPX Udotbelow rdotaccent -15
+KPX Udotbelow rcaron -15
+KPX Udotbelow racute -20
+KPX Udotbelow ncaron -10
+KPX Udotbelow nacute -15
+KPX Udotbelow ntilde -10
+KPX Udotbelow p -25
+KPX Udotbelow n -20
+KPX Udotbelow m -20
+KPX Udotbelow A -50
+KPX Uhookabove aring.sc -20
+KPX Uhookabove adieresis.sc -20
+KPX Uhookabove atilde.sc -20
+KPX Uhookabove acircumflex.sc -20
+KPX Uhookabove aacute.sc -30
+KPX Uhookabove agrave.sc -20
+KPX Uhookabove a.sc -40
+KPX Uhookabove amacron.sc -20
+KPX Uhookabove abreve.sc -20
+KPX Uhookabove ahookabove.sc -20
+KPX Uhookabove acircumflexdotbelow.sc -20
+KPX Uhookabove abrevedotbelow.sc -20
+KPX Uhookabove rdotaccent -15
+KPX Uhookabove rcaron -15
+KPX Uhookabove racute -20
+KPX Uhookabove ncaron -10
+KPX Uhookabove nacute -15
+KPX Uhookabove ntilde -10
+KPX Uhookabove n -20
+KPX Uhookabove m -20
+KPX Uhookabove A -50
+KPX Uhornacute aring.sc -20
+KPX Uhornacute adieresis.sc -20
+KPX Uhornacute atilde.sc -20
+KPX Uhornacute acircumflex.sc -20
+KPX Uhornacute aacute.sc -30
+KPX Uhornacute agrave.sc -20
+KPX Uhornacute a.sc -40
+KPX Uhornacute amacron.sc -20
+KPX Uhornacute abreve.sc -20
+KPX Uhornacute ahookabove.sc -20
+KPX Uhornacute acircumflexdotbelow.sc -20
+KPX Uhornacute abrevedotbelow.sc -20
+KPX Uhornacute rdotaccent -15
+KPX Uhornacute rcaron -15
+KPX Uhornacute racute -20
+KPX Uhornacute ncaron -10
+KPX Uhornacute nacute -15
+KPX Uhornacute ntilde -10
+KPX Uhornacute n -20
+KPX Uhornacute A -50
+KPX Uhorngrave aring.sc -20
+KPX Uhorngrave adieresis.sc -20
+KPX Uhorngrave atilde.sc -20
+KPX Uhorngrave acircumflex.sc -20
+KPX Uhorngrave aacute.sc -30
+KPX Uhorngrave agrave.sc -20
+KPX Uhorngrave a.sc -40
+KPX Uhorngrave amacron.sc -20
+KPX Uhorngrave abreve.sc -20
+KPX Uhorngrave ahookabove.sc -20
+KPX Uhorngrave acircumflexdotbelow.sc -20
+KPX Uhorngrave abrevedotbelow.sc -20
+KPX Uhorngrave rdotaccent -15
+KPX Uhorngrave rcaron -15
+KPX Uhorngrave racute -20
+KPX Uhorngrave ncaron -10
+KPX Uhorngrave nacute -15
+KPX Uhorngrave ntilde -10
+KPX Uhorngrave n -20
+KPX Uhorngrave m -20
+KPX Uhorngrave A -50
+KPX Uhornhookabove aring.sc -20
+KPX Uhornhookabove adieresis.sc -20
+KPX Uhornhookabove atilde.sc -20
+KPX Uhornhookabove acircumflex.sc -20
+KPX Uhornhookabove aacute.sc -30
+KPX Uhornhookabove agrave.sc -20
+KPX Uhornhookabove a.sc -40
+KPX Uhornhookabove amacron.sc -20
+KPX Uhornhookabove abreve.sc -20
+KPX Uhornhookabove ahookabove.sc -20
+KPX Uhornhookabove acircumflexdotbelow.sc -20
+KPX Uhornhookabove abrevedotbelow.sc -20
+KPX Uhornhookabove rdotaccent -15
+KPX Uhornhookabove rcaron -15
+KPX Uhornhookabove racute -20
+KPX Uhornhookabove ncaron -10
+KPX Uhornhookabove nacute -15
+KPX Uhornhookabove ntilde -10
+KPX Uhornhookabove n -20
+KPX Uhornhookabove A -50
+KPX Uhorntilde aring.sc -20
+KPX Uhorntilde adieresis.sc -20
+KPX Uhorntilde atilde.sc -20
+KPX Uhorntilde acircumflex.sc -20
+KPX Uhorntilde aacute.sc -30
+KPX Uhorntilde agrave.sc -20
+KPX Uhorntilde a.sc -40
+KPX Uhorntilde amacron.sc -20
+KPX Uhorntilde abreve.sc -20
+KPX Uhorntilde ahookabove.sc -20
+KPX Uhorntilde acircumflexdotbelow.sc -20
+KPX Uhorntilde abrevedotbelow.sc -20
+KPX Uhorntilde rdotaccent -15
+KPX Uhorntilde rcaron -15
+KPX Uhorntilde racute -20
+KPX Uhorntilde ncaron -10
+KPX Uhorntilde nacute -15
+KPX Uhorntilde ntilde -10
+KPX Uhorntilde n -20
+KPX Uhorntilde A -50
+KPX Uhorndotbelow aring.sc -20
+KPX Uhorndotbelow adieresis.sc -20
+KPX Uhorndotbelow atilde.sc -20
+KPX Uhorndotbelow acircumflex.sc -20
+KPX Uhorndotbelow aacute.sc -30
+KPX Uhorndotbelow agrave.sc -20
+KPX Uhorndotbelow a.sc -40
+KPX Uhorndotbelow amacron.sc -20
+KPX Uhorndotbelow abreve.sc -20
+KPX Uhorndotbelow ahookabove.sc -20
+KPX Uhorndotbelow acircumflexdotbelow.sc -20
+KPX Uhorndotbelow abrevedotbelow.sc -20
+KPX Uhorndotbelow rdotaccent -15
+KPX Uhorndotbelow rcaron -15
+KPX Uhorndotbelow racute -20
+KPX Uhorndotbelow ncaron -10
+KPX Uhorndotbelow nacute -15
+KPX Uhorndotbelow ntilde -10
+KPX Uhorndotbelow n -20
+KPX Uhorndotbelow A -50
+KPX Ygrave zcaron -50
+KPX Ygrave zdotaccent -50
+KPX Ygrave zacute -50
+KPX Ygrave z -50
+KPX Ygrave ccaron -75
+KPX Ygrave cdotaccent -75
+KPX Ygrave ccircumflex -75
+KPX Ygrave cacute -75
+KPX Ygrave ccedilla -75
+KPX Ygrave c -75
+KPX Ygrave scaron -50
+KPX Ygrave scedilla -50
+KPX Ygrave scircumflex -50
+KPX Ygrave sacute -50
+KPX Ygrave s -50
+KPX Ygrave odieresis.sc -20
+KPX Ygrave otilde.sc -20
+KPX Ygrave ocircumflex.sc -20
+KPX Ygrave oacute.sc -30
+KPX Ygrave ograve.sc -20
+KPX Ygrave ae.sc -55
+KPX Ygrave aring.sc -15
+KPX Ygrave adieresis.sc -15
+KPX Ygrave atilde.sc -15
+KPX Ygrave acircumflex.sc -15
+KPX Ygrave aacute.sc -25
+KPX Ygrave agrave.sc -15
+KPX Ygrave tcaron.sc 15
+KPX Ygrave scircumflex.sc -10
+KPX Ygrave sacute.sc -15
+KPX Ygrave omacron.sc -20
+KPX Ygrave ohungarumlaut.sc -20
+KPX Ygrave obreve.sc -20
+KPX Ygrave gdotaccent.sc -20
+KPX Ygrave gcircumflex.sc -20
+KPX Ygrave gbreve.sc -20
+KPX Ygrave cdotaccent.sc -20
+KPX Ygrave ccircumflex.sc -20
+KPX Ygrave ccaron.sc -20
+KPX Ygrave cacute.sc -30
+KPX Ygrave aeacute.sc -55
+KPX Ygrave amacron.sc -15
+KPX Ygrave abreve.sc -15
+KPX Ygrave scaron.sc -10
+KPX Ygrave ohorntilde.sc -20
+KPX Ygrave ohornhookabove.sc -20
+KPX Ygrave ohorngrave.sc -20
+KPX Ygrave ohorndotbelow.sc -20
+KPX Ygrave ohornacute.sc -20
+KPX Ygrave ohookabove.sc -20
+KPX Ygrave oe.sc -25
+KPX Ygrave ocircumflexdotbelow.sc -20
+KPX Ygrave gcaron.sc -20
+KPX Ygrave gacute.sc -30
+KPX Ygrave ahookabove.sc -15
+KPX Ygrave acircumflexdotbelow.sc -15
+KPX Ygrave abrevedotbelow.sc -15
+KPX Ygrave uhorndotbelow -25
+KPX Ygrave uhorntilde -25
+KPX Ygrave uhornhookabove -25
+KPX Ygrave uhorngrave -25
+KPX Ygrave uhornacute -25
+KPX Ygrave uhookabove -25
+KPX Ygrave ohorndotbelow -35
+KPX Ygrave ohorntilde -35
+KPX Ygrave ohornhookabove -35
+KPX Ygrave ohorngrave -35
+KPX Ygrave ohornacute -35
+KPX Ygrave ocircumflexdotbelow -35
+KPX Ygrave ohookabove -35
+KPX Ygrave ecircumflexdotbelow -35
+KPX Ygrave etilde -35
+KPX Ygrave ehookabove -35
+KPX Ygrave abrevedotbelow -30
+KPX Ygrave acircumflexdotbelow -30
+KPX Ygrave ahookabove -30
+KPX Ygrave aeacute -60
+KPX Ygrave AEacute -80
+KPX Ygrave gacute -50
+KPX Ygrave gcaron -35
+KPX Ygrave uhungarumlaut -25
+KPX Ygrave uring -25
+KPX Ygrave ubreve -25
+KPX Ygrave umacron -25
+KPX Ygrave utilde -25
+KPX Ygrave oe -50
+KPX Ygrave OE -35
+KPX Ygrave ohungarumlaut -35
+KPX Ygrave obreve -35
+KPX Ygrave omacron -35
+KPX Ygrave gdotaccent -35
+KPX Ygrave gbreve -35
+KPX Ygrave gcircumflex -35
+KPX Ygrave ecaron -35
+KPX Ygrave edotaccent -35
+KPX Ygrave ebreve -35
+KPX Ygrave emacron -35
+KPX Ygrave abreve -30
+KPX Ygrave amacron -30
+KPX Ygrave udieresis -25
+KPX Ygrave ucircumflex -25
+KPX Ygrave uacute -40
+KPX Ygrave ugrave -25
+KPX Ygrave odieresis -35
+KPX Ygrave otilde -35
+KPX Ygrave ocircumflex -35
+KPX Ygrave oacute -55
+KPX Ygrave ograve -35
+KPX Ygrave edieresis -35
+KPX Ygrave ecircumflex -35
+KPX Ygrave eacute -55
+KPX Ygrave egrave -35
+KPX Ygrave ae -60
+KPX Ygrave aring -30
+KPX Ygrave adieresis -30
+KPX Ygrave atilde -30
+KPX Ygrave acircumflex -30
+KPX Ygrave aacute -40
+KPX Ygrave agrave -30
+KPX Ygrave AE -80
+KPX ygrave aeacute -20
+KPX ygrave oe -25
+KPX ygrave ae -20
+KPX Ydotbelow zcaron -50
+KPX Ydotbelow zdotaccent -50
+KPX Ydotbelow zacute -50
+KPX Ydotbelow z -50
+KPX Ydotbelow ccaron -75
+KPX Ydotbelow cdotaccent -75
+KPX Ydotbelow ccircumflex -75
+KPX Ydotbelow cacute -75
+KPX Ydotbelow ccedilla -75
+KPX Ydotbelow c -75
+KPX Ydotbelow scaron -50
+KPX Ydotbelow scedilla -50
+KPX Ydotbelow scircumflex -50
+KPX Ydotbelow sacute -50
+KPX Ydotbelow s -50
+KPX Ydotbelow T_h 35
+KPX Ydotbelow odieresis.sc -20
+KPX Ydotbelow otilde.sc -20
+KPX Ydotbelow ocircumflex.sc -20
+KPX Ydotbelow oacute.sc -30
+KPX Ydotbelow ograve.sc -20
+KPX Ydotbelow ae.sc -55
+KPX Ydotbelow aring.sc -15
+KPX Ydotbelow adieresis.sc -15
+KPX Ydotbelow atilde.sc -15
+KPX Ydotbelow acircumflex.sc -15
+KPX Ydotbelow aacute.sc -25
+KPX Ydotbelow agrave.sc -15
+KPX Ydotbelow t.sc 30
+KPX Ydotbelow c.sc -40
+KPX Ydotbelow tcaron.sc 15
+KPX Ydotbelow scircumflex.sc -10
+KPX Ydotbelow sacute.sc -15
+KPX Ydotbelow omacron.sc -20
+KPX Ydotbelow ohungarumlaut.sc -20
+KPX Ydotbelow obreve.sc -20
+KPX Ydotbelow gdotaccent.sc -20
+KPX Ydotbelow gcircumflex.sc -20
+KPX Ydotbelow gbreve.sc -20
+KPX Ydotbelow cdotaccent.sc -20
+KPX Ydotbelow ccircumflex.sc -20
+KPX Ydotbelow ccaron.sc -20
+KPX Ydotbelow cacute.sc -30
+KPX Ydotbelow aeacute.sc -55
+KPX Ydotbelow amacron.sc -15
+KPX Ydotbelow abreve.sc -15
+KPX Ydotbelow scaron.sc -10
+KPX Ydotbelow ohorntilde.sc -20
+KPX Ydotbelow ohornhookabove.sc -20
+KPX Ydotbelow ohorngrave.sc -20
+KPX Ydotbelow ohorndotbelow.sc -20
+KPX Ydotbelow ohornacute.sc -20
+KPX Ydotbelow ohookabove.sc -20
+KPX Ydotbelow oe.sc -25
+KPX Ydotbelow ocircumflexdotbelow.sc -20
+KPX Ydotbelow gcaron.sc -20
+KPX Ydotbelow gacute.sc -30
+KPX Ydotbelow ahookabove.sc -15
+KPX Ydotbelow acircumflexdotbelow.sc -15
+KPX Ydotbelow abrevedotbelow.sc -15
+KPX Ydotbelow uhorndotbelow -25
+KPX Ydotbelow uhorntilde -25
+KPX Ydotbelow uhornhookabove -25
+KPX Ydotbelow uhorngrave -25
+KPX Ydotbelow uhornacute -25
+KPX Ydotbelow uhookabove -25
+KPX Ydotbelow ohorndotbelow -35
+KPX Ydotbelow ohorntilde -35
+KPX Ydotbelow ohornhookabove -35
+KPX Ydotbelow ohorngrave -35
+KPX Ydotbelow ohornacute -35
+KPX Ydotbelow ocircumflexdotbelow -35
+KPX Ydotbelow ohookabove -35
+KPX Ydotbelow ecircumflexdotbelow -35
+KPX Ydotbelow etilde -35
+KPX Ydotbelow ehookabove -35
+KPX Ydotbelow abrevedotbelow -30
+KPX Ydotbelow acircumflexdotbelow -30
+KPX Ydotbelow ahookabove -30
+KPX Ydotbelow aeacute -60
+KPX Ydotbelow AEacute -80
+KPX Ydotbelow gacute -50
+KPX Ydotbelow gcaron -35
+KPX Ydotbelow uhungarumlaut -25
+KPX Ydotbelow uring -25
+KPX Ydotbelow ubreve -25
+KPX Ydotbelow umacron -25
+KPX Ydotbelow utilde -25
+KPX Ydotbelow oe -50
+KPX Ydotbelow OE -35
+KPX Ydotbelow ohungarumlaut -35
+KPX Ydotbelow obreve -35
+KPX Ydotbelow omacron -35
+KPX Ydotbelow gdotaccent -35
+KPX Ydotbelow gbreve -35
+KPX Ydotbelow gcircumflex -35
+KPX Ydotbelow ecaron -35
+KPX Ydotbelow edotaccent -35
+KPX Ydotbelow ebreve -35
+KPX Ydotbelow emacron -35
+KPX Ydotbelow abreve -30
+KPX Ydotbelow amacron -30
+KPX Ydotbelow udieresis -25
+KPX Ydotbelow ucircumflex -25
+KPX Ydotbelow uacute -40
+KPX Ydotbelow ugrave -25
+KPX Ydotbelow odieresis -35
+KPX Ydotbelow otilde -35
+KPX Ydotbelow ocircumflex -35
+KPX Ydotbelow oacute -55
+KPX Ydotbelow ograve -35
+KPX Ydotbelow edieresis -35
+KPX Ydotbelow ecircumflex -35
+KPX Ydotbelow eacute -55
+KPX Ydotbelow egrave -35
+KPX Ydotbelow ae -60
+KPX Ydotbelow aring -30
+KPX Ydotbelow adieresis -30
+KPX Ydotbelow atilde -30
+KPX Ydotbelow acircumflex -30
+KPX Ydotbelow aacute -40
+KPX Ydotbelow agrave -30
+KPX Ydotbelow AE -80
+KPX Ydotbelow u -50
+KPX Ydotbelow T 35
+KPX Ydotbelow C -45
+KPX ydotbelow aeacute -20
+KPX ydotbelow oe -25
+KPX ydotbelow ae -20
+KPX ydotbelow c -35
+KPX Yhookabove zcaron -50
+KPX Yhookabove zdotaccent -50
+KPX Yhookabove zacute -50
+KPX Yhookabove z -50
+KPX Yhookabove ccaron -75
+KPX Yhookabove cdotaccent -75
+KPX Yhookabove ccircumflex -75
+KPX Yhookabove cacute -75
+KPX Yhookabove ccedilla -75
+KPX Yhookabove c -75
+KPX Yhookabove scaron -50
+KPX Yhookabove scedilla -50
+KPX Yhookabove scircumflex -50
+KPX Yhookabove sacute -50
+KPX Yhookabove s -50
+KPX Yhookabove odieresis.sc -20
+KPX Yhookabove otilde.sc -20
+KPX Yhookabove ocircumflex.sc -20
+KPX Yhookabove oacute.sc -30
+KPX Yhookabove ograve.sc -20
+KPX Yhookabove ae.sc -55
+KPX Yhookabove aring.sc -15
+KPX Yhookabove adieresis.sc -15
+KPX Yhookabove atilde.sc -15
+KPX Yhookabove acircumflex.sc -15
+KPX Yhookabove aacute.sc -25
+KPX Yhookabove agrave.sc -15
+KPX Yhookabove tcaron.sc 15
+KPX Yhookabove scircumflex.sc -10
+KPX Yhookabove sacute.sc -15
+KPX Yhookabove omacron.sc -20
+KPX Yhookabove ohungarumlaut.sc -20
+KPX Yhookabove obreve.sc -20
+KPX Yhookabove gdotaccent.sc -20
+KPX Yhookabove gcircumflex.sc -20
+KPX Yhookabove gbreve.sc -20
+KPX Yhookabove cdotaccent.sc -20
+KPX Yhookabove ccircumflex.sc -20
+KPX Yhookabove ccaron.sc -20
+KPX Yhookabove cacute.sc -30
+KPX Yhookabove aeacute.sc -55
+KPX Yhookabove amacron.sc -15
+KPX Yhookabove abreve.sc -15
+KPX Yhookabove scaron.sc -10
+KPX Yhookabove ohorntilde.sc -20
+KPX Yhookabove ohornhookabove.sc -20
+KPX Yhookabove ohorngrave.sc -20
+KPX Yhookabove ohorndotbelow.sc -20
+KPX Yhookabove ohornacute.sc -20
+KPX Yhookabove ohookabove.sc -20
+KPX Yhookabove oe.sc -25
+KPX Yhookabove ocircumflexdotbelow.sc -20
+KPX Yhookabove gcaron.sc -20
+KPX Yhookabove gacute.sc -30
+KPX Yhookabove ahookabove.sc -15
+KPX Yhookabove acircumflexdotbelow.sc -15
+KPX Yhookabove abrevedotbelow.sc -15
+KPX Yhookabove uhorndotbelow -25
+KPX Yhookabove uhorntilde -25
+KPX Yhookabove uhornhookabove -25
+KPX Yhookabove uhorngrave -25
+KPX Yhookabove uhornacute -25
+KPX Yhookabove uhookabove -25
+KPX Yhookabove ohorndotbelow -35
+KPX Yhookabove ohorntilde -35
+KPX Yhookabove ohornhookabove -35
+KPX Yhookabove ohorngrave -35
+KPX Yhookabove ohornacute -35
+KPX Yhookabove ocircumflexdotbelow -35
+KPX Yhookabove ohookabove -35
+KPX Yhookabove ecircumflexdotbelow -35
+KPX Yhookabove etilde -35
+KPX Yhookabove ehookabove -35
+KPX Yhookabove abrevedotbelow -30
+KPX Yhookabove acircumflexdotbelow -30
+KPX Yhookabove ahookabove -30
+KPX Yhookabove aeacute -60
+KPX Yhookabove AEacute -80
+KPX Yhookabove gacute -50
+KPX Yhookabove gcaron -35
+KPX Yhookabove uhungarumlaut -25
+KPX Yhookabove uring -25
+KPX Yhookabove ubreve -25
+KPX Yhookabove umacron -25
+KPX Yhookabove utilde -25
+KPX Yhookabove oe -50
+KPX Yhookabove OE -35
+KPX Yhookabove ohungarumlaut -35
+KPX Yhookabove obreve -35
+KPX Yhookabove omacron -35
+KPX Yhookabove gdotaccent -35
+KPX Yhookabove gbreve -35
+KPX Yhookabove gcircumflex -35
+KPX Yhookabove ecaron -35
+KPX Yhookabove edotaccent -35
+KPX Yhookabove ebreve -35
+KPX Yhookabove emacron -35
+KPX Yhookabove abreve -30
+KPX Yhookabove amacron -30
+KPX Yhookabove udieresis -25
+KPX Yhookabove ucircumflex -25
+KPX Yhookabove uacute -40
+KPX Yhookabove ugrave -25
+KPX Yhookabove odieresis -35
+KPX Yhookabove otilde -35
+KPX Yhookabove ocircumflex -35
+KPX Yhookabove oacute -55
+KPX Yhookabove ograve -35
+KPX Yhookabove edieresis -35
+KPX Yhookabove ecircumflex -35
+KPX Yhookabove eacute -55
+KPX Yhookabove egrave -35
+KPX Yhookabove ae -60
+KPX Yhookabove aring -30
+KPX Yhookabove adieresis -30
+KPX Yhookabove atilde -30
+KPX Yhookabove acircumflex -30
+KPX Yhookabove aacute -40
+KPX Yhookabove agrave -30
+KPX Yhookabove AE -80
+KPX Yhookabove u -50
+KPX yhookabove aeacute -20
+KPX yhookabove oe -25
+KPX yhookabove ae -20
+KPX Ytilde zcaron -50
+KPX Ytilde zdotaccent -50
+KPX Ytilde zacute -50
+KPX Ytilde z -50
+KPX Ytilde ccaron -75
+KPX Ytilde cdotaccent -75
+KPX Ytilde ccircumflex -75
+KPX Ytilde cacute -75
+KPX Ytilde ccedilla -75
+KPX Ytilde c -75
+KPX Ytilde scaron -50
+KPX Ytilde scedilla -50
+KPX Ytilde scircumflex -50
+KPX Ytilde sacute -50
+KPX Ytilde s -50
+KPX Ytilde odieresis.sc -20
+KPX Ytilde otilde.sc -20
+KPX Ytilde ocircumflex.sc -20
+KPX Ytilde oacute.sc -30
+KPX Ytilde ograve.sc -20
+KPX Ytilde ae.sc -55
+KPX Ytilde aring.sc -15
+KPX Ytilde adieresis.sc -15
+KPX Ytilde atilde.sc -15
+KPX Ytilde acircumflex.sc -15
+KPX Ytilde aacute.sc -25
+KPX Ytilde agrave.sc -15
+KPX Ytilde tcaron.sc 15
+KPX Ytilde scircumflex.sc -10
+KPX Ytilde sacute.sc -15
+KPX Ytilde omacron.sc -20
+KPX Ytilde ohungarumlaut.sc -20
+KPX Ytilde obreve.sc -20
+KPX Ytilde gdotaccent.sc -20
+KPX Ytilde gcircumflex.sc -20
+KPX Ytilde gbreve.sc -20
+KPX Ytilde cdotaccent.sc -20
+KPX Ytilde ccircumflex.sc -20
+KPX Ytilde ccaron.sc -20
+KPX Ytilde cacute.sc -30
+KPX Ytilde aeacute.sc -55
+KPX Ytilde amacron.sc -15
+KPX Ytilde abreve.sc -15
+KPX Ytilde scaron.sc -10
+KPX Ytilde ohorntilde.sc -20
+KPX Ytilde ohornhookabove.sc -20
+KPX Ytilde ohorngrave.sc -20
+KPX Ytilde ohorndotbelow.sc -20
+KPX Ytilde ohornacute.sc -20
+KPX Ytilde ohookabove.sc -20
+KPX Ytilde oe.sc -25
+KPX Ytilde ocircumflexdotbelow.sc -20
+KPX Ytilde gcaron.sc -20
+KPX Ytilde gacute.sc -30
+KPX Ytilde ahookabove.sc -15
+KPX Ytilde acircumflexdotbelow.sc -15
+KPX Ytilde abrevedotbelow.sc -15
+KPX Ytilde uhorndotbelow -25
+KPX Ytilde uhorntilde -25
+KPX Ytilde uhornhookabove -25
+KPX Ytilde uhorngrave -25
+KPX Ytilde uhornacute -25
+KPX Ytilde uhookabove -25
+KPX Ytilde ohorndotbelow -35
+KPX Ytilde ohorntilde -35
+KPX Ytilde ohornhookabove -35
+KPX Ytilde ohorngrave -35
+KPX Ytilde ohornacute -35
+KPX Ytilde ocircumflexdotbelow -35
+KPX Ytilde ohookabove -35
+KPX Ytilde ecircumflexdotbelow -35
+KPX Ytilde etilde -35
+KPX Ytilde ehookabove -35
+KPX Ytilde abrevedotbelow -30
+KPX Ytilde acircumflexdotbelow -30
+KPX Ytilde ahookabove -30
+KPX Ytilde aeacute -60
+KPX Ytilde AEacute -80
+KPX Ytilde gacute -50
+KPX Ytilde gcaron -35
+KPX Ytilde uhungarumlaut -25
+KPX Ytilde uring -25
+KPX Ytilde ubreve -25
+KPX Ytilde umacron -25
+KPX Ytilde utilde -25
+KPX Ytilde oe -50
+KPX Ytilde OE -35
+KPX Ytilde ohungarumlaut -35
+KPX Ytilde obreve -35
+KPX Ytilde omacron -35
+KPX Ytilde gdotaccent -35
+KPX Ytilde gbreve -35
+KPX Ytilde gcircumflex -35
+KPX Ytilde ecaron -35
+KPX Ytilde edotaccent -35
+KPX Ytilde ebreve -35
+KPX Ytilde emacron -35
+KPX Ytilde abreve -30
+KPX Ytilde amacron -30
+KPX Ytilde udieresis -25
+KPX Ytilde ucircumflex -25
+KPX Ytilde uacute -40
+KPX Ytilde ugrave -25
+KPX Ytilde odieresis -35
+KPX Ytilde otilde -35
+KPX Ytilde ocircumflex -35
+KPX Ytilde oacute -55
+KPX Ytilde ograve -35
+KPX Ytilde edieresis -35
+KPX Ytilde ecircumflex -35
+KPX Ytilde eacute -55
+KPX Ytilde egrave -35
+KPX Ytilde ae -60
+KPX Ytilde aring -30
+KPX Ytilde adieresis -30
+KPX Ytilde atilde -30
+KPX Ytilde acircumflex -30
+KPX Ytilde aacute -40
+KPX Ytilde agrave -30
+KPX Ytilde AE -80
+KPX ytilde aeacute -20
+KPX ytilde oe -25
+KPX ytilde ae -20
+KPX quoteleft T_h 25
+KPX quoteleft ydieresis.sc 25
+KPX quoteleft ae.sc -115
+KPX quoteleft aring.sc -85
+KPX quoteleft adieresis.sc -85
+KPX quoteleft y.sc 25
+KPX quoteleft w.sc 25
+KPX quoteleft v.sc 20
+KPX quoteleft t.sc 25
+KPX quoteleft a.sc -85
+KPX quoteleft ycircumflex.sc 25
+KPX quoteleft wgrave.sc 25
+KPX quoteleft wdieresis.sc 25
+KPX quoteleft wcircumflex.sc 25
+KPX quoteleft wacute.sc 25
+KPX quoteleft uni021B.sc 25
+KPX quoteleft tcaron.sc 25
+KPX quoteleft aeacute.sc -115
+KPX quoteleft aogonek.sc -85
+KPX quoteleft amacron.sc -85
+KPX quoteleft quoteleft -35
+KPX quoteleft Wdieresis 25
+KPX quoteleft Wacute 25
+KPX quoteleft Wgrave 25
+KPX quoteleft uni021A 25
+KPX quoteleft AEacute -115
+KPX quoteleft Ydieresis 25
+KPX quoteleft Ycircumflex 25
+KPX quoteleft Wcircumflex 25
+KPX quoteleft Tcaron 25
+KPX quoteleft Aogonek -85
+KPX quoteleft Amacron -85
+KPX quoteleft AE -115
+KPX quoteleft Aring -85
+KPX quoteleft Adieresis -85
+KPX quoteleft Y 25
+KPX quoteleft W 25
+KPX quoteleft V 20
+KPX quoteleft T 25
+KPX quoteleft A -85
+KPX quoteright ae.sc -115
+KPX quoteright aring.sc -85
+KPX quoteright adieresis.sc -85
+KPX quoteright a.sc -85
+KPX quoteright aeacute.sc -115
+KPX quoteright aogonek.sc -85
+KPX quoteright amacron.sc -85
+KPX quoteright AEacute -115
+KPX quoteright oogonek -20
+KPX quoteright ohungarumlaut -20
+KPX quoteright obreve -20
+KPX quoteright omacron -20
+KPX quoteright dcaron -30
+KPX quoteright Aogonek -85
+KPX quoteright Amacron -85
+KPX quoteright oslash -20
+KPX quoteright odieresis -20
+KPX quoteright AE -115
+KPX quoteright Aring -85
+KPX quoteright Adieresis -85
+KPX quoteright o -20
+KPX quoteright d -30
+KPX quoteright A -85
+KPX quoteright period -20
+KPX quoteright comma -35
+KPX quotedblleft T_h 20
+KPX quotedblleft ydieresis.sc 20
+KPX quotedblleft ae.sc -115
+KPX quotedblleft aring.sc -85
+KPX quotedblleft adieresis.sc -85
+KPX quotedblleft y.sc 20
+KPX quotedblleft w.sc 20
+KPX quotedblleft v.sc 20
+KPX quotedblleft t.sc 20
+KPX quotedblleft a.sc -85
+KPX quotedblleft ycircumflex.sc 20
+KPX quotedblleft wgrave.sc 20
+KPX quotedblleft wdieresis.sc 20
+KPX quotedblleft wcircumflex.sc 20
+KPX quotedblleft wacute.sc 20
+KPX quotedblleft uni021B.sc 20
+KPX quotedblleft tcaron.sc 20
+KPX quotedblleft aeacute.sc -115
+KPX quotedblleft aogonek.sc -85
+KPX quotedblleft amacron.sc -85
+KPX quotedblleft Wdieresis 20
+KPX quotedblleft Wacute 20
+KPX quotedblleft Wgrave 20
+KPX quotedblleft uni021A 20
+KPX quotedblleft AEacute -115
+KPX quotedblleft Ydieresis 20
+KPX quotedblleft Ycircumflex 20
+KPX quotedblleft Wcircumflex 20
+KPX quotedblleft Tcaron 20
+KPX quotedblleft Aogonek -85
+KPX quotedblleft Amacron -85
+KPX quotedblleft AE -115
+KPX quotedblleft Aring -85
+KPX quotedblleft Adieresis -85
+KPX quotedblleft Y 20
+KPX quotedblleft W 20
+KPX quotedblleft V 20
+KPX quotedblleft T 20
+KPX quotedblleft A -85
+KPX quotedblright T_h 20
+KPX quotedblright ydieresis.sc 20
+KPX quotedblright ae.sc -115
+KPX quotedblright aring.sc -85
+KPX quotedblright adieresis.sc -85
+KPX quotedblright y.sc 20
+KPX quotedblright w.sc 20
+KPX quotedblright v.sc 20
+KPX quotedblright t.sc 20
+KPX quotedblright a.sc -85
+KPX quotedblright ycircumflex.sc 20
+KPX quotedblright wgrave.sc 20
+KPX quotedblright wdieresis.sc 20
+KPX quotedblright wcircumflex.sc 20
+KPX quotedblright wacute.sc 20
+KPX quotedblright uni021B.sc 20
+KPX quotedblright tcaron.sc 20
+KPX quotedblright aeacute.sc -115
+KPX quotedblright aogonek.sc -85
+KPX quotedblright amacron.sc -85
+KPX quotedblright Wdieresis 20
+KPX quotedblright Wacute 20
+KPX quotedblright Wgrave 20
+KPX quotedblright uni021A 20
+KPX quotedblright AEacute -115
+KPX quotedblright Ydieresis 20
+KPX quotedblright Ycircumflex 20
+KPX quotedblright Wcircumflex 20
+KPX quotedblright Tcaron 20
+KPX quotedblright Aogonek -85
+KPX quotedblright Amacron -85
+KPX quotedblright AE -115
+KPX quotedblright Aring -85
+KPX quotedblright Adieresis -85
+KPX quotedblright Y 20
+KPX quotedblright W 20
+KPX quotedblright V 20
+KPX quotedblright T 20
+KPX quotedblright A -85
+KPX quotedblbase T_h -60
+KPX quotedblbase ydieresis.sc -75
+KPX quotedblbase ae.sc 15
+KPX quotedblbase aring.sc 15
+KPX quotedblbase adieresis.sc 15
+KPX quotedblbase y.sc -75
+KPX quotedblbase w.sc -35
+KPX quotedblbase v.sc -95
+KPX quotedblbase t.sc -60
+KPX quotedblbase a.sc 15
+KPX quotedblbase ycircumflex.sc -75
+KPX quotedblbase wgrave.sc -35
+KPX quotedblbase wdieresis.sc -35
+KPX quotedblbase wcircumflex.sc -35
+KPX quotedblbase wacute.sc -35
+KPX quotedblbase uni021B.sc -60
+KPX quotedblbase tcaron.sc -60
+KPX quotedblbase aeacute.sc 15
+KPX quotedblbase aogonek.sc 15
+KPX quotedblbase amacron.sc 15
+KPX quotedblbase Wdieresis -35
+KPX quotedblbase Wacute -35
+KPX quotedblbase Wgrave -35
+KPX quotedblbase uni021A -60
+KPX quotedblbase AEacute 15
+KPX quotedblbase Ydieresis -75
+KPX quotedblbase Ycircumflex -75
+KPX quotedblbase Wcircumflex -35
+KPX quotedblbase Tcaron -60
+KPX quotedblbase Aogonek 15
+KPX quotedblbase Amacron 15
+KPX quotedblbase AE 15
+KPX quotedblbase Aring 15
+KPX quotedblbase Adieresis 15
+KPX quotedblbase Y -75
+KPX quotedblbase W -35
+KPX quotedblbase V -95
+KPX quotedblbase T -60
+KPX quotedblbase A 15
+KPX guilsinglright T_h -125
+KPX guilsinglright Wdieresis -75
+KPX guilsinglright Wacute -75
+KPX guilsinglright Wgrave -75
+KPX guilsinglright uni021A -125
+KPX guilsinglright AEacute -85
+KPX guilsinglright Ydieresis -130
+KPX guilsinglright Ycircumflex -130
+KPX guilsinglright Wcircumflex -75
+KPX guilsinglright Tcaron -125
+KPX guilsinglright Aogonek -75
+KPX guilsinglright Amacron -75
+KPX guilsinglright AE -85
+KPX guilsinglright Aring -75
+KPX guilsinglright Adieresis -75
+KPX guilsinglright Y -130
+KPX guilsinglright W -75
+KPX guilsinglright V -120
+KPX guilsinglright T -125
+KPX guilsinglright A -75
+KPX abreveacute.sc t.sc -35
+KPX abreveacute.sc c.sc -35
+KPX abrevedotbelow.sc t.sc -35
+KPX abrevedotbelow.sc c.sc -35
+KPX acircumflexacute.sc y.sc -45
+KPX acircumflexacute.sc u.sc -30
+KPX acircumflexacute.sc t.sc -35
+KPX acircumflexacute.sc c.sc -35
+KPX acircumflexdotbelow.sc y.sc -45
+KPX acircumflexdotbelow.sc u.sc -30
+KPX acircumflexdotbelow.sc t.sc -35
+KPX acircumflexdotbelow.sc c.sc -35
+KPX acircumflexgrave.sc y.sc -45
+KPX acircumflexgrave.sc u.sc -30
+KPX acircumflexhookabove.sc y.sc -45
+KPX acircumflexhookabove.sc u.sc -30
+KPX acircumflextilde.sc y.sc -45
+KPX acircumflextilde.sc u.sc -30
+KPX adotbelow.sc y.sc -45
+KPX adotbelow.sc u.sc -30
+KPX adotbelow.sc t.sc -35
+KPX adotbelow.sc o.sc -30
+KPX adotbelow.sc c.sc -35
+KPX ahookabove.sc y.sc -45
+KPX ahookabove.sc u.sc -30
+KPX ahookabove.sc o.sc -30
+KPX dcroat.sc atilde.sc -45
+KPX dcroat.sc acircumflex.sc -45
+KPX dcroat.sc aacute.sc -45
+KPX dcroat.sc agrave.sc -45
+KPX dcroat.sc a.sc -45
+KPX dcroat.sc abreve.sc -45
+KPX dcroat.sc ahookabove.sc -45
+KPX dcroat.sc adotbelow.sc -45
+KPX dcroat.sc acircumflextilde.sc -45
+KPX dcroat.sc acircumflexhookabove.sc -45
+KPX dcroat.sc acircumflexgrave.sc -45
+KPX dcroat.sc acircumflexdotbelow.sc -45
+KPX dcroat.sc acircumflexacute.sc -45
+KPX dcroat.sc abrevetilde.sc -45
+KPX dcroat.sc abrevehookabove.sc -45
+KPX dcroat.sc abrevegrave.sc -45
+KPX dcroat.sc abrevedotbelow.sc -45
+KPX dcroat.sc abreveacute.sc -45
+KPX gacute.sc ydieresis.sc -10
+KPX gacute.sc ae.sc -10
+KPX gacute.sc aring.sc -10
+KPX gacute.sc adieresis.sc -10
+KPX gacute.sc y.sc -10
+KPX gacute.sc w.sc -10
+KPX gacute.sc v.sc -15
+KPX gacute.sc t.sc -10
+KPX gacute.sc a.sc -10
+KPX gacute.sc ycircumflex.sc -10
+KPX gacute.sc wgrave.sc -10
+KPX gacute.sc wdieresis.sc -10
+KPX gacute.sc wcircumflex.sc -10
+KPX gacute.sc wacute.sc -10
+KPX gacute.sc uni021B.sc -10
+KPX gacute.sc tcaron.sc -10
+KPX gacute.sc aeacute.sc -10
+KPX gacute.sc aogonek.sc -10
+KPX gacute.sc amacron.sc -10
+KPX gcaron.sc ydieresis.sc -10
+KPX gcaron.sc ae.sc -10
+KPX gcaron.sc aring.sc -10
+KPX gcaron.sc adieresis.sc -10
+KPX gcaron.sc y.sc -10
+KPX gcaron.sc w.sc -10
+KPX gcaron.sc v.sc -15
+KPX gcaron.sc t.sc -10
+KPX gcaron.sc a.sc -10
+KPX gcaron.sc ycircumflex.sc -10
+KPX gcaron.sc wgrave.sc -10
+KPX gcaron.sc wdieresis.sc -10
+KPX gcaron.sc wcircumflex.sc -10
+KPX gcaron.sc wacute.sc -10
+KPX gcaron.sc uni021B.sc -10
+KPX gcaron.sc tcaron.sc -10
+KPX gcaron.sc aeacute.sc -10
+KPX gcaron.sc aogonek.sc -10
+KPX gcaron.sc amacron.sc -10
+KPX jacute.sc ae.sc -15
+KPX jacute.sc aring.sc -20
+KPX jacute.sc adieresis.sc -20
+KPX jacute.sc a.sc -20
+KPX jacute.sc aeacute.sc -15
+KPX jacute.sc aogonek.sc -20
+KPX jacute.sc amacron.sc -20
+KPX lslash.sc ydieresis.sc -40
+KPX lslash.sc yacute.sc -40
+KPX lslash.sc udieresis.sc -15
+KPX lslash.sc ucircumflex.sc -15
+KPX lslash.sc uacute.sc -15
+KPX lslash.sc ugrave.sc -15
+KPX lslash.sc ccedilla.sc -5
+KPX lslash.sc ae.sc 15
+KPX lslash.sc aring.sc 10
+KPX lslash.sc adieresis.sc 10
+KPX lslash.sc y.sc -40
+KPX lslash.sc w.sc -35
+KPX lslash.sc v.sc -50
+KPX lslash.sc u.sc -15
+KPX lslash.sc t.sc -35
+KPX lslash.sc g.sc -10
+KPX lslash.sc c.sc -5
+KPX lslash.sc a.sc 10
+KPX lslash.sc ygrave.sc -40
+KPX lslash.sc ycircumflex.sc -40
+KPX lslash.sc wgrave.sc -35
+KPX lslash.sc wdieresis.sc -35
+KPX lslash.sc wcircumflex.sc -35
+KPX lslash.sc wacute.sc -35
+KPX lslash.sc utilde.sc -15
+KPX lslash.sc uring.sc -15
+KPX lslash.sc uogonek.sc -15
+KPX lslash.sc umacron.sc -15
+KPX lslash.sc uhungarumlaut.sc -15
+KPX lslash.sc ubreve.sc -15
+KPX lslash.sc uni021B.sc -35
+KPX lslash.sc tcaron.sc -35
+KPX lslash.sc gdotaccent.sc -10
+KPX lslash.sc gcommaaccent.sc -10
+KPX lslash.sc gcircumflex.sc -10
+KPX lslash.sc gbreve.sc -10
+KPX lslash.sc cdotaccent.sc -5
+KPX lslash.sc ccircumflex.sc -5
+KPX lslash.sc ccaron.sc -5
+KPX lslash.sc cacute.sc -5
+KPX lslash.sc aeacute.sc 15
+KPX lslash.sc aogonek.sc 10
+KPX lslash.sc amacron.sc 10
+KPX lslash.sc ytilde.sc -40
+KPX lslash.sc yhookabove.sc -40
+KPX lslash.sc ydotbelow.sc -40
+KPX lslash.sc uhorntilde.sc -15
+KPX lslash.sc uhornhookabove.sc -15
+KPX lslash.sc uhorngrave.sc -15
+KPX lslash.sc uhorndotbelow.sc -15
+KPX lslash.sc uhornacute.sc -15
+KPX lslash.sc uhookabove.sc -15
+KPX lslash.sc udotbelow.sc -15
+KPX lslash.sc gcaron.sc -10
+KPX lslash.sc gacute.sc -10
+KPX lslash.sc quotedblright -80
+KPX lslash.sc quoteright -80
+KPX lslash.sc hyphen 20
+KPX odotbelow.sc a.sc -35
+KPX ohookabove.sc a.sc -35
+KPX oogonek.sc ydieresis.sc -25
+KPX oogonek.sc ae.sc -35
+KPX oogonek.sc aring.sc -35
+KPX oogonek.sc adieresis.sc -35
+KPX oogonek.sc y.sc -25
+KPX oogonek.sc x.sc -25
+KPX oogonek.sc w.sc -20
+KPX oogonek.sc v.sc -35
+KPX oogonek.sc a.sc -35
+KPX oogonek.sc ycircumflex.sc -25
+KPX oogonek.sc wgrave.sc -20
+KPX oogonek.sc wdieresis.sc -20
+KPX oogonek.sc wcircumflex.sc -20
+KPX oogonek.sc wacute.sc -20
+KPX oogonek.sc aeacute.sc -35
+KPX oogonek.sc aogonek.sc -35
+KPX oogonek.sc amacron.sc -35
+KPX rdotaccent.sc ydieresis.sc -20
+KPX rdotaccent.sc udieresis.sc -25
+KPX rdotaccent.sc ucircumflex.sc -25
+KPX rdotaccent.sc oslash.sc -25
+KPX rdotaccent.sc odieresis.sc -25
+KPX rdotaccent.sc ccedilla.sc -25
+KPX rdotaccent.sc y.sc -20
+KPX rdotaccent.sc w.sc -25
+KPX rdotaccent.sc v.sc -25
+KPX rdotaccent.sc u.sc -25
+KPX rdotaccent.sc t.sc -15
+KPX rdotaccent.sc o.sc -25
+KPX rdotaccent.sc g.sc -25
+KPX rdotaccent.sc c.sc -25
+KPX rdotaccent.sc ycircumflex.sc -20
+KPX rdotaccent.sc wgrave.sc -25
+KPX rdotaccent.sc wdieresis.sc -25
+KPX rdotaccent.sc wcircumflex.sc -25
+KPX rdotaccent.sc wacute.sc -25
+KPX rdotaccent.sc uring.sc -25
+KPX rdotaccent.sc uogonek.sc -25
+KPX rdotaccent.sc umacron.sc -25
+KPX rdotaccent.sc uhungarumlaut.sc -25
+KPX rdotaccent.sc ubreve.sc -25
+KPX rdotaccent.sc uni021B.sc -15
+KPX rdotaccent.sc tcaron.sc -15
+KPX rdotaccent.sc omacron.sc -25
+KPX rdotaccent.sc ohungarumlaut.sc -25
+KPX rdotaccent.sc obreve.sc -25
+KPX rdotaccent.sc gdotaccent.sc -25
+KPX rdotaccent.sc gcommaaccent.sc -25
+KPX rdotaccent.sc gcircumflex.sc -25
+KPX rdotaccent.sc gbreve.sc -25
+KPX rdotaccent.sc cdotaccent.sc -25
+KPX rdotaccent.sc ccircumflex.sc -25
+KPX rdotaccent.sc ccaron.sc -25
+KPX rdotaccent.sc cacute.sc -25
+KPX rdotaccent.sc oogonek.sc -25
+KPX rdotaccent.sc oe.sc -20
+KPX rdotaccent.sc gcaron.sc -25
+KPX rdotaccent.sc gacute.sc -25
+KPX rdotaccent.sc hyphen -20
+KPX scaron.sc ae.sc -20
+KPX scaron.sc aring.sc -15
+KPX scaron.sc adieresis.sc -15
+KPX scaron.sc a.sc -15
+KPX scaron.sc aeacute.sc -20
+KPX scaron.sc aogonek.sc -15
+KPX scaron.sc amacron.sc -15
+KPX udotbelow.sc a.sc -35
+KPX uhookabove.sc a.sc -35
+KPX uhornacute.sc a.sc -35
+KPX uhorndotbelow.sc a.sc -35
+KPX uhorngrave.sc a.sc -35
+KPX uhornhookabove.sc a.sc -35
+KPX uhorntilde.sc a.sc -35
+KPX ydotbelow.sc t.sc 25
+KPX ydotbelow.sc c.sc -30
+KPX f_k ecircumflexdotbelow -15
+KPX f_k ecircumflexhookabove -15
+KPX f_k ecircumflexgrave -15
+KPX f_k ecircumflexacute -15
+KPX f_k etilde -15
+KPX f_k ehookabove -15
+KPX f_k edotbelow -15
+KPX f_k uni0219 15
+KPX f_k oogonek -15
+KPX f_k scaron 15
+KPX f_k scedilla 15
+KPX f_k scircumflex 15
+KPX f_k sacute 15
+KPX f_k ohungarumlaut -15
+KPX f_k obreve -15
+KPX f_k omacron -15
+KPX f_k ecaron -15
+KPX f_k eogonek -15
+KPX f_k edotaccent -15
+KPX f_k ebreve -15
+KPX f_k emacron -15
+KPX f_k oslash -15
+KPX f_k odieresis -15
+KPX f_k edieresis -15
+KPX f_k ecircumflex -15
+KPX f_k eacute -15
+KPX f_k egrave -15
+KPX f_k s 15
+KPX f_k o -15
+KPX f_k e -15
+KPX f_k W -30
+KPX f_k V -45
+KPX f_k period 10
+KPX f_k hyphen -35
+KPX hyphen.prop one.prop -25
+KPX hyphen.prop seven.prop -35
+KPX hyphen.prop two.prop -10
+KPX Jacute ae.sc -20
+KPX Jacute aring.sc -25
+KPX Jacute adieresis.sc -25
+KPX Jacute a.sc -25
+KPX Jacute aeacute.sc -20
+KPX Jacute aogonek.sc -25
+KPX Jacute amacron.sc -25
+KPX Jacute AEacute -25
+KPX Jacute Aogonek -30
+KPX Jacute Amacron -30
+KPX Jacute AE -25
+KPX Jacute Aring -30
+KPX Jacute Adieresis -30
+KPX Jacute A -30
+KPX seven.prop six.prop -10
+KPX seven.prop four.prop -25
+KPX seven.prop hyphen.prop -25
+KPX amacron.sc ydieresis.sc -45
+KPX amacron.sc udieresis.sc -30
+KPX amacron.sc ucircumflex.sc -30
+KPX amacron.sc oslash.sc -30
+KPX amacron.sc odieresis.sc -30
+KPX amacron.sc ccedilla.sc -35
+KPX amacron.sc y.sc -45
+KPX amacron.sc w.sc -50
+KPX amacron.sc v.sc -85
+KPX amacron.sc u.sc -30
+KPX amacron.sc t.sc -35
+KPX amacron.sc q.sc -25
+KPX amacron.sc o.sc -30
+KPX amacron.sc g.sc -35
+KPX amacron.sc c.sc -35
+KPX amacron.sc ycircumflex.sc -45
+KPX amacron.sc wgrave.sc -50
+KPX amacron.sc wdieresis.sc -50
+KPX amacron.sc wcircumflex.sc -50
+KPX amacron.sc wacute.sc -50
+KPX amacron.sc uring.sc -30
+KPX amacron.sc uogonek.sc -30
+KPX amacron.sc umacron.sc -30
+KPX amacron.sc uhungarumlaut.sc -30
+KPX amacron.sc ubreve.sc -30
+KPX amacron.sc uni021B.sc -35
+KPX amacron.sc tcaron.sc -35
+KPX amacron.sc omacron.sc -30
+KPX amacron.sc ohungarumlaut.sc -30
+KPX amacron.sc obreve.sc -30
+KPX amacron.sc gdotaccent.sc -35
+KPX amacron.sc gcommaaccent.sc -35
+KPX amacron.sc gcircumflex.sc -35
+KPX amacron.sc gbreve.sc -35
+KPX amacron.sc cdotaccent.sc -35
+KPX amacron.sc ccircumflex.sc -35
+KPX amacron.sc ccaron.sc -35
+KPX amacron.sc cacute.sc -35
+KPX amacron.sc oogonek.sc -30
+KPX amacron.sc gcaron.sc -35
+KPX amacron.sc gacute.sc -35
+KPX amacron.sc quotedblright -85
+KPX amacron.sc quoteright -80
+KPX amacron.sc period 10
+KPX amacron.sc hyphen -10
+KPX aogonek.sc ydieresis.sc -45
+KPX aogonek.sc udieresis.sc -30
+KPX aogonek.sc ucircumflex.sc -30
+KPX aogonek.sc oslash.sc -30
+KPX aogonek.sc odieresis.sc -30
+KPX aogonek.sc ccedilla.sc -35
+KPX aogonek.sc y.sc -45
+KPX aogonek.sc w.sc -50
+KPX aogonek.sc v.sc -85
+KPX aogonek.sc u.sc -30
+KPX aogonek.sc t.sc -35
+KPX aogonek.sc q.sc -25
+KPX aogonek.sc o.sc -30
+KPX aogonek.sc g.sc -35
+KPX aogonek.sc c.sc -35
+KPX aogonek.sc ycircumflex.sc -45
+KPX aogonek.sc wgrave.sc -50
+KPX aogonek.sc wdieresis.sc -50
+KPX aogonek.sc wcircumflex.sc -50
+KPX aogonek.sc wacute.sc -50
+KPX aogonek.sc uring.sc -30
+KPX aogonek.sc uogonek.sc -30
+KPX aogonek.sc umacron.sc -30
+KPX aogonek.sc uhungarumlaut.sc -30
+KPX aogonek.sc ubreve.sc -30
+KPX aogonek.sc uni021B.sc -35
+KPX aogonek.sc tcaron.sc -35
+KPX aogonek.sc omacron.sc -30
+KPX aogonek.sc ohungarumlaut.sc -30
+KPX aogonek.sc obreve.sc -30
+KPX aogonek.sc gdotaccent.sc -35
+KPX aogonek.sc gcommaaccent.sc -35
+KPX aogonek.sc gcircumflex.sc -35
+KPX aogonek.sc gbreve.sc -35
+KPX aogonek.sc cdotaccent.sc -35
+KPX aogonek.sc ccircumflex.sc -35
+KPX aogonek.sc ccaron.sc -35
+KPX aogonek.sc cacute.sc -35
+KPX aogonek.sc oogonek.sc -30
+KPX aogonek.sc gcaron.sc -35
+KPX aogonek.sc gacute.sc -35
+KPX aogonek.sc quotedblright -85
+KPX aogonek.sc quoteright -80
+KPX aogonek.sc period 10
+KPX aogonek.sc hyphen -10
+KPX cacute.sc oslash.sc -10
+KPX cacute.sc odieresis.sc -10
+KPX cacute.sc aring.sc 5
+KPX cacute.sc adieresis.sc 5
+KPX cacute.sc o.sc -10
+KPX cacute.sc k.sc 5
+KPX cacute.sc h.sc 10
+KPX cacute.sc a.sc 5
+KPX cacute.sc omacron.sc -10
+KPX cacute.sc ohungarumlaut.sc -10
+KPX cacute.sc obreve.sc -10
+KPX cacute.sc kcommaaccent.sc 5
+KPX cacute.sc hcircumflex.sc 10
+KPX cacute.sc aogonek.sc 5
+KPX cacute.sc amacron.sc 5
+KPX cacute.sc oogonek.sc -10
+KPX ccaron.sc oslash.sc -10
+KPX ccaron.sc odieresis.sc -10
+KPX ccaron.sc aring.sc 5
+KPX ccaron.sc adieresis.sc 5
+KPX ccaron.sc o.sc -10
+KPX ccaron.sc k.sc 5
+KPX ccaron.sc h.sc 10
+KPX ccaron.sc a.sc 5
+KPX ccaron.sc omacron.sc -10
+KPX ccaron.sc ohungarumlaut.sc -10
+KPX ccaron.sc obreve.sc -10
+KPX ccaron.sc kcommaaccent.sc 5
+KPX ccaron.sc hcircumflex.sc 10
+KPX ccaron.sc aogonek.sc 5
+KPX ccaron.sc amacron.sc 5
+KPX ccaron.sc oogonek.sc -10
+KPX ccircumflex.sc oslash.sc -10
+KPX ccircumflex.sc odieresis.sc -10
+KPX ccircumflex.sc aring.sc 5
+KPX ccircumflex.sc adieresis.sc 5
+KPX ccircumflex.sc o.sc -10
+KPX ccircumflex.sc k.sc 5
+KPX ccircumflex.sc h.sc 10
+KPX ccircumflex.sc a.sc 5
+KPX ccircumflex.sc omacron.sc -10
+KPX ccircumflex.sc ohungarumlaut.sc -10
+KPX ccircumflex.sc obreve.sc -10
+KPX ccircumflex.sc kcommaaccent.sc 5
+KPX ccircumflex.sc hcircumflex.sc 10
+KPX ccircumflex.sc aogonek.sc 5
+KPX ccircumflex.sc amacron.sc 5
+KPX ccircumflex.sc oogonek.sc -10
+KPX cdotaccent.sc oslash.sc -10
+KPX cdotaccent.sc odieresis.sc -10
+KPX cdotaccent.sc aring.sc 5
+KPX cdotaccent.sc adieresis.sc 5
+KPX cdotaccent.sc o.sc -10
+KPX cdotaccent.sc k.sc 5
+KPX cdotaccent.sc h.sc 10
+KPX cdotaccent.sc a.sc 5
+KPX cdotaccent.sc omacron.sc -10
+KPX cdotaccent.sc ohungarumlaut.sc -10
+KPX cdotaccent.sc obreve.sc -10
+KPX cdotaccent.sc kcommaaccent.sc 5
+KPX cdotaccent.sc hcircumflex.sc 10
+KPX cdotaccent.sc aogonek.sc 5
+KPX cdotaccent.sc amacron.sc 5
+KPX cdotaccent.sc oogonek.sc -10
+KPX dcaron.sc ydieresis.sc -20
+KPX dcaron.sc aring.sc -45
+KPX dcaron.sc adieresis.sc -45
+KPX dcaron.sc y.sc -20
+KPX dcaron.sc x.sc -25
+KPX dcaron.sc w.sc -25
+KPX dcaron.sc v.sc -25
+KPX dcaron.sc j.sc -15
+KPX dcaron.sc a.sc -45
+KPX dcaron.sc ycircumflex.sc -20
+KPX dcaron.sc wgrave.sc -25
+KPX dcaron.sc wdieresis.sc -25
+KPX dcaron.sc wcircumflex.sc -25
+KPX dcaron.sc wacute.sc -25
+KPX dcaron.sc jcircumflex.sc -15
+KPX dcaron.sc aogonek.sc -45
+KPX dcaron.sc amacron.sc -45
+KPX dcaron.sc jacute.sc -15
+KPX gbreve.sc ydieresis.sc -10
+KPX gbreve.sc ae.sc -10
+KPX gbreve.sc aring.sc -10
+KPX gbreve.sc adieresis.sc -10
+KPX gbreve.sc y.sc -10
+KPX gbreve.sc w.sc -10
+KPX gbreve.sc v.sc -15
+KPX gbreve.sc t.sc -10
+KPX gbreve.sc a.sc -10
+KPX gbreve.sc ycircumflex.sc -10
+KPX gbreve.sc wgrave.sc -10
+KPX gbreve.sc wdieresis.sc -10
+KPX gbreve.sc wcircumflex.sc -10
+KPX gbreve.sc wacute.sc -10
+KPX gbreve.sc uni021B.sc -10
+KPX gbreve.sc tcaron.sc -10
+KPX gbreve.sc aeacute.sc -10
+KPX gbreve.sc aogonek.sc -10
+KPX gbreve.sc amacron.sc -10
+KPX gcircumflex.sc ydieresis.sc -10
+KPX gcircumflex.sc ae.sc -10
+KPX gcircumflex.sc aring.sc -10
+KPX gcircumflex.sc adieresis.sc -10
+KPX gcircumflex.sc y.sc -10
+KPX gcircumflex.sc w.sc -10
+KPX gcircumflex.sc v.sc -15
+KPX gcircumflex.sc t.sc -10
+KPX gcircumflex.sc a.sc -10
+KPX gcircumflex.sc ycircumflex.sc -10
+KPX gcircumflex.sc wgrave.sc -10
+KPX gcircumflex.sc wdieresis.sc -10
+KPX gcircumflex.sc wcircumflex.sc -10
+KPX gcircumflex.sc wacute.sc -10
+KPX gcircumflex.sc uni021B.sc -10
+KPX gcircumflex.sc tcaron.sc -10
+KPX gcircumflex.sc aeacute.sc -10
+KPX gcircumflex.sc aogonek.sc -10
+KPX gcircumflex.sc amacron.sc -10
+KPX gcommaaccent.sc ydieresis.sc -10
+KPX gcommaaccent.sc ae.sc -10
+KPX gcommaaccent.sc aring.sc -10
+KPX gcommaaccent.sc adieresis.sc -10
+KPX gcommaaccent.sc y.sc -10
+KPX gcommaaccent.sc w.sc -10
+KPX gcommaaccent.sc v.sc -15
+KPX gcommaaccent.sc t.sc -10
+KPX gcommaaccent.sc a.sc -10
+KPX gcommaaccent.sc ycircumflex.sc -10
+KPX gcommaaccent.sc wgrave.sc -10
+KPX gcommaaccent.sc wdieresis.sc -10
+KPX gcommaaccent.sc wcircumflex.sc -10
+KPX gcommaaccent.sc wacute.sc -10
+KPX gcommaaccent.sc uni021B.sc -10
+KPX gcommaaccent.sc tcaron.sc -10
+KPX gcommaaccent.sc aeacute.sc -10
+KPX gcommaaccent.sc aogonek.sc -10
+KPX gcommaaccent.sc amacron.sc -10
+KPX gdotaccent.sc ydieresis.sc -10
+KPX gdotaccent.sc ae.sc -10
+KPX gdotaccent.sc aring.sc -10
+KPX gdotaccent.sc adieresis.sc -10
+KPX gdotaccent.sc y.sc -10
+KPX gdotaccent.sc w.sc -10
+KPX gdotaccent.sc v.sc -15
+KPX gdotaccent.sc t.sc -10
+KPX gdotaccent.sc a.sc -10
+KPX gdotaccent.sc ycircumflex.sc -10
+KPX gdotaccent.sc wgrave.sc -10
+KPX gdotaccent.sc wdieresis.sc -10
+KPX gdotaccent.sc wcircumflex.sc -10
+KPX gdotaccent.sc wacute.sc -10
+KPX gdotaccent.sc uni021B.sc -10
+KPX gdotaccent.sc tcaron.sc -10
+KPX gdotaccent.sc aeacute.sc -10
+KPX gdotaccent.sc aogonek.sc -10
+KPX gdotaccent.sc amacron.sc -10
+KPX jcircumflex.sc ae.sc -15
+KPX jcircumflex.sc aring.sc -20
+KPX jcircumflex.sc adieresis.sc -20
+KPX jcircumflex.sc a.sc -20
+KPX jcircumflex.sc aeacute.sc -15
+KPX jcircumflex.sc aogonek.sc -20
+KPX jcircumflex.sc amacron.sc -20
+KPX kcommaaccent.sc oslash.sc -25
+KPX kcommaaccent.sc odieresis.sc -25
+KPX kcommaaccent.sc ccedilla.sc -35
+KPX kcommaaccent.sc t.sc 15
+KPX kcommaaccent.sc o.sc -25
+KPX kcommaaccent.sc g.sc -35
+KPX kcommaaccent.sc c.sc -35
+KPX kcommaaccent.sc uni021B.sc 15
+KPX kcommaaccent.sc tcaron.sc 15
+KPX kcommaaccent.sc omacron.sc -25
+KPX kcommaaccent.sc ohungarumlaut.sc -25
+KPX kcommaaccent.sc obreve.sc -25
+KPX kcommaaccent.sc gdotaccent.sc -35
+KPX kcommaaccent.sc gcommaaccent.sc -35
+KPX kcommaaccent.sc gcircumflex.sc -35
+KPX kcommaaccent.sc gbreve.sc -35
+KPX kcommaaccent.sc cdotaccent.sc -35
+KPX kcommaaccent.sc ccircumflex.sc -35
+KPX kcommaaccent.sc ccaron.sc -35
+KPX kcommaaccent.sc cacute.sc -35
+KPX kcommaaccent.sc oogonek.sc -25
+KPX kcommaaccent.sc oe.sc -25
+KPX kcommaaccent.sc gcaron.sc -35
+KPX kcommaaccent.sc gacute.sc -35
+KPX kcommaaccent.sc hyphen -45
+KPX lacute.sc ydieresis.sc -50
+KPX lacute.sc udieresis.sc -15
+KPX lacute.sc ucircumflex.sc -15
+KPX lacute.sc ccedilla.sc -5
+KPX lacute.sc ae.sc 15
+KPX lacute.sc aring.sc 10
+KPX lacute.sc adieresis.sc 10
+KPX lacute.sc y.sc -50
+KPX lacute.sc w.sc -45
+KPX lacute.sc v.sc -65
+KPX lacute.sc u.sc -15
+KPX lacute.sc t.sc -45
+KPX lacute.sc g.sc -10
+KPX lacute.sc c.sc -5
+KPX lacute.sc a.sc 10
+KPX lacute.sc ycircumflex.sc -50
+KPX lacute.sc wgrave.sc -45
+KPX lacute.sc wdieresis.sc -45
+KPX lacute.sc wcircumflex.sc -45
+KPX lacute.sc wacute.sc -45
+KPX lacute.sc uring.sc -15
+KPX lacute.sc uogonek.sc -15
+KPX lacute.sc umacron.sc -15
+KPX lacute.sc uhungarumlaut.sc -15
+KPX lacute.sc ubreve.sc -15
+KPX lacute.sc uni021B.sc -45
+KPX lacute.sc tcaron.sc -45
+KPX lacute.sc gdotaccent.sc -10
+KPX lacute.sc gcommaaccent.sc -10
+KPX lacute.sc gcircumflex.sc -10
+KPX lacute.sc gbreve.sc -10
+KPX lacute.sc cdotaccent.sc -5
+KPX lacute.sc ccircumflex.sc -5
+KPX lacute.sc ccaron.sc -5
+KPX lacute.sc cacute.sc -5
+KPX lacute.sc aeacute.sc 15
+KPX lacute.sc aogonek.sc 10
+KPX lacute.sc amacron.sc 10
+KPX lacute.sc gcaron.sc -10
+KPX lacute.sc gacute.sc -10
+KPX lacute.sc quotedblright -80
+KPX lacute.sc quoteright -80
+KPX lacute.sc hyphen 20
+KPX lcaron.sc ydieresis.sc -25
+KPX lcaron.sc yacute.sc -25
+KPX lcaron.sc udieresis.sc -10
+KPX lcaron.sc ucircumflex.sc -10
+KPX lcaron.sc uacute.sc -10
+KPX lcaron.sc ugrave.sc -10
+KPX lcaron.sc ccedilla.sc -5
+KPX lcaron.sc ae.sc 15
+KPX lcaron.sc aring.sc 10
+KPX lcaron.sc adieresis.sc 10
+KPX lcaron.sc y.sc -25
+KPX lcaron.sc w.sc -20
+KPX lcaron.sc v.sc -30
+KPX lcaron.sc u.sc -10
+KPX lcaron.sc t.sc -20
+KPX lcaron.sc g.sc -10
+KPX lcaron.sc c.sc -5
+KPX lcaron.sc a.sc 10
+KPX lcaron.sc ygrave.sc -25
+KPX lcaron.sc ycircumflex.sc -25
+KPX lcaron.sc wgrave.sc -20
+KPX lcaron.sc wdieresis.sc -20
+KPX lcaron.sc wcircumflex.sc -20
+KPX lcaron.sc wacute.sc -20
+KPX lcaron.sc utilde.sc -10
+KPX lcaron.sc uring.sc -10
+KPX lcaron.sc uogonek.sc -10
+KPX lcaron.sc umacron.sc -10
+KPX lcaron.sc uhungarumlaut.sc -10
+KPX lcaron.sc ubreve.sc -10
+KPX lcaron.sc uni021B.sc -20
+KPX lcaron.sc tcaron.sc -20
+KPX lcaron.sc gdotaccent.sc -10
+KPX lcaron.sc gcommaaccent.sc -10
+KPX lcaron.sc gcircumflex.sc -10
+KPX lcaron.sc gbreve.sc -10
+KPX lcaron.sc cdotaccent.sc -5
+KPX lcaron.sc ccircumflex.sc -5
+KPX lcaron.sc ccaron.sc -5
+KPX lcaron.sc cacute.sc -5
+KPX lcaron.sc aeacute.sc 15
+KPX lcaron.sc aogonek.sc 10
+KPX lcaron.sc amacron.sc 10
+KPX lcaron.sc ytilde.sc -25
+KPX lcaron.sc yhookabove.sc -25
+KPX lcaron.sc ydotbelow.sc -25
+KPX lcaron.sc uhorntilde.sc -10
+KPX lcaron.sc uhornhookabove.sc -10
+KPX lcaron.sc uhorngrave.sc -10
+KPX lcaron.sc uhorndotbelow.sc -10
+KPX lcaron.sc uhornacute.sc -10
+KPX lcaron.sc uhookabove.sc -10
+KPX lcaron.sc udotbelow.sc -10
+KPX lcaron.sc gcaron.sc -10
+KPX lcaron.sc gacute.sc -10
+KPX lcaron.sc quotedblright -80
+KPX lcaron.sc quoteright -80
+KPX lcaron.sc hyphen 20
+KPX lcommaaccent.sc ydieresis.sc -50
+KPX lcommaaccent.sc udieresis.sc -15
+KPX lcommaaccent.sc ucircumflex.sc -15
+KPX lcommaaccent.sc ccedilla.sc -5
+KPX lcommaaccent.sc ae.sc 15
+KPX lcommaaccent.sc aring.sc 10
+KPX lcommaaccent.sc adieresis.sc 10
+KPX lcommaaccent.sc y.sc -50
+KPX lcommaaccent.sc w.sc -45
+KPX lcommaaccent.sc v.sc -65
+KPX lcommaaccent.sc u.sc -15
+KPX lcommaaccent.sc t.sc -45
+KPX lcommaaccent.sc g.sc -10
+KPX lcommaaccent.sc c.sc -5
+KPX lcommaaccent.sc a.sc 10
+KPX lcommaaccent.sc ycircumflex.sc -50
+KPX lcommaaccent.sc wgrave.sc -45
+KPX lcommaaccent.sc wdieresis.sc -45
+KPX lcommaaccent.sc wcircumflex.sc -45
+KPX lcommaaccent.sc wacute.sc -45
+KPX lcommaaccent.sc uring.sc -15
+KPX lcommaaccent.sc uogonek.sc -15
+KPX lcommaaccent.sc umacron.sc -15
+KPX lcommaaccent.sc uhungarumlaut.sc -15
+KPX lcommaaccent.sc ubreve.sc -15
+KPX lcommaaccent.sc uni021B.sc -45
+KPX lcommaaccent.sc tcaron.sc -45
+KPX lcommaaccent.sc gdotaccent.sc -10
+KPX lcommaaccent.sc gcommaaccent.sc -10
+KPX lcommaaccent.sc gcircumflex.sc -10
+KPX lcommaaccent.sc gbreve.sc -10
+KPX lcommaaccent.sc cdotaccent.sc -5
+KPX lcommaaccent.sc ccircumflex.sc -5
+KPX lcommaaccent.sc ccaron.sc -5
+KPX lcommaaccent.sc cacute.sc -5
+KPX lcommaaccent.sc aeacute.sc 15
+KPX lcommaaccent.sc aogonek.sc 10
+KPX lcommaaccent.sc amacron.sc 10
+KPX lcommaaccent.sc gcaron.sc -10
+KPX lcommaaccent.sc gacute.sc -10
+KPX lcommaaccent.sc quotedblright -80
+KPX lcommaaccent.sc quoteright -80
+KPX lcommaaccent.sc hyphen 20
+KPX nacute.sc oslash.sc -15
+KPX nacute.sc odieresis.sc -15
+KPX nacute.sc ccedilla.sc -15
+KPX nacute.sc ae.sc -15
+KPX nacute.sc aring.sc -15
+KPX nacute.sc adieresis.sc -15
+KPX nacute.sc o.sc -15
+KPX nacute.sc g.sc -15
+KPX nacute.sc c.sc -15
+KPX nacute.sc a.sc -15
+KPX nacute.sc omacron.sc -15
+KPX nacute.sc ohungarumlaut.sc -15
+KPX nacute.sc obreve.sc -15
+KPX nacute.sc gdotaccent.sc -15
+KPX nacute.sc gcommaaccent.sc -15
+KPX nacute.sc gcircumflex.sc -15
+KPX nacute.sc gbreve.sc -15
+KPX nacute.sc cdotaccent.sc -15
+KPX nacute.sc ccircumflex.sc -15
+KPX nacute.sc ccaron.sc -15
+KPX nacute.sc cacute.sc -15
+KPX nacute.sc aeacute.sc -15
+KPX nacute.sc aogonek.sc -15
+KPX nacute.sc amacron.sc -15
+KPX nacute.sc oogonek.sc -15
+KPX nacute.sc gcaron.sc -15
+KPX nacute.sc gacute.sc -15
+KPX nacute.sc comma -10
+KPX ncaron.sc oslash.sc -15
+KPX ncaron.sc odieresis.sc -15
+KPX ncaron.sc ccedilla.sc -15
+KPX ncaron.sc ae.sc -15
+KPX ncaron.sc aring.sc -15
+KPX ncaron.sc adieresis.sc -15
+KPX ncaron.sc o.sc -15
+KPX ncaron.sc g.sc -15
+KPX ncaron.sc c.sc -15
+KPX ncaron.sc a.sc -15
+KPX ncaron.sc omacron.sc -15
+KPX ncaron.sc ohungarumlaut.sc -15
+KPX ncaron.sc obreve.sc -15
+KPX ncaron.sc gdotaccent.sc -15
+KPX ncaron.sc gcommaaccent.sc -15
+KPX ncaron.sc gcircumflex.sc -15
+KPX ncaron.sc gbreve.sc -15
+KPX ncaron.sc cdotaccent.sc -15
+KPX ncaron.sc ccircumflex.sc -15
+KPX ncaron.sc ccaron.sc -15
+KPX ncaron.sc cacute.sc -15
+KPX ncaron.sc aeacute.sc -15
+KPX ncaron.sc aogonek.sc -15
+KPX ncaron.sc amacron.sc -15
+KPX ncaron.sc oogonek.sc -15
+KPX ncaron.sc gcaron.sc -15
+KPX ncaron.sc gacute.sc -15
+KPX ncaron.sc comma -10
+KPX ncommaaccent.sc oslash.sc -15
+KPX ncommaaccent.sc odieresis.sc -15
+KPX ncommaaccent.sc ccedilla.sc -15
+KPX ncommaaccent.sc ae.sc -15
+KPX ncommaaccent.sc aring.sc -15
+KPX ncommaaccent.sc adieresis.sc -15
+KPX ncommaaccent.sc o.sc -15
+KPX ncommaaccent.sc g.sc -15
+KPX ncommaaccent.sc c.sc -15
+KPX ncommaaccent.sc a.sc -15
+KPX ncommaaccent.sc omacron.sc -15
+KPX ncommaaccent.sc ohungarumlaut.sc -15
+KPX ncommaaccent.sc obreve.sc -15
+KPX ncommaaccent.sc gdotaccent.sc -15
+KPX ncommaaccent.sc gcommaaccent.sc -15
+KPX ncommaaccent.sc gcircumflex.sc -15
+KPX ncommaaccent.sc gbreve.sc -15
+KPX ncommaaccent.sc cdotaccent.sc -15
+KPX ncommaaccent.sc ccircumflex.sc -15
+KPX ncommaaccent.sc ccaron.sc -15
+KPX ncommaaccent.sc cacute.sc -15
+KPX ncommaaccent.sc aeacute.sc -15
+KPX ncommaaccent.sc aogonek.sc -15
+KPX ncommaaccent.sc amacron.sc -15
+KPX ncommaaccent.sc oogonek.sc -15
+KPX ncommaaccent.sc gcaron.sc -15
+KPX ncommaaccent.sc gacute.sc -15
+KPX ncommaaccent.sc comma -10
+KPX obreve.sc ydieresis.sc -25
+KPX obreve.sc ae.sc -35
+KPX obreve.sc aring.sc -35
+KPX obreve.sc adieresis.sc -35
+KPX obreve.sc y.sc -25
+KPX obreve.sc x.sc -25
+KPX obreve.sc w.sc -20
+KPX obreve.sc v.sc -35
+KPX obreve.sc a.sc -35
+KPX obreve.sc ycircumflex.sc -25
+KPX obreve.sc wgrave.sc -20
+KPX obreve.sc wdieresis.sc -20
+KPX obreve.sc wcircumflex.sc -20
+KPX obreve.sc wacute.sc -20
+KPX obreve.sc aeacute.sc -35
+KPX obreve.sc aogonek.sc -35
+KPX obreve.sc amacron.sc -35
+KPX ohungarumlaut.sc ydieresis.sc -25
+KPX ohungarumlaut.sc ae.sc -35
+KPX ohungarumlaut.sc aring.sc -35
+KPX ohungarumlaut.sc adieresis.sc -35
+KPX ohungarumlaut.sc y.sc -25
+KPX ohungarumlaut.sc x.sc -25
+KPX ohungarumlaut.sc w.sc -20
+KPX ohungarumlaut.sc v.sc -35
+KPX ohungarumlaut.sc a.sc -35
+KPX ohungarumlaut.sc ycircumflex.sc -25
+KPX ohungarumlaut.sc wgrave.sc -20
+KPX ohungarumlaut.sc wdieresis.sc -20
+KPX ohungarumlaut.sc wcircumflex.sc -20
+KPX ohungarumlaut.sc wacute.sc -20
+KPX ohungarumlaut.sc aeacute.sc -35
+KPX ohungarumlaut.sc aogonek.sc -35
+KPX ohungarumlaut.sc amacron.sc -35
+KPX omacron.sc ydieresis.sc -25
+KPX omacron.sc ae.sc -35
+KPX omacron.sc aring.sc -35
+KPX omacron.sc adieresis.sc -35
+KPX omacron.sc y.sc -25
+KPX omacron.sc x.sc -25
+KPX omacron.sc w.sc -20
+KPX omacron.sc v.sc -35
+KPX omacron.sc a.sc -35
+KPX omacron.sc ycircumflex.sc -25
+KPX omacron.sc wgrave.sc -20
+KPX omacron.sc wdieresis.sc -20
+KPX omacron.sc wcircumflex.sc -20
+KPX omacron.sc wacute.sc -20
+KPX omacron.sc aeacute.sc -35
+KPX omacron.sc aogonek.sc -35
+KPX omacron.sc amacron.sc -35
+KPX racute.sc ydieresis.sc -20
+KPX racute.sc udieresis.sc -25
+KPX racute.sc ucircumflex.sc -25
+KPX racute.sc oslash.sc -25
+KPX racute.sc odieresis.sc -25
+KPX racute.sc ccedilla.sc -25
+KPX racute.sc y.sc -20
+KPX racute.sc w.sc -25
+KPX racute.sc v.sc -25
+KPX racute.sc u.sc -25
+KPX racute.sc t.sc -15
+KPX racute.sc o.sc -25
+KPX racute.sc g.sc -25
+KPX racute.sc c.sc -25
+KPX racute.sc ycircumflex.sc -20
+KPX racute.sc wgrave.sc -25
+KPX racute.sc wdieresis.sc -25
+KPX racute.sc wcircumflex.sc -25
+KPX racute.sc wacute.sc -25
+KPX racute.sc uring.sc -25
+KPX racute.sc uogonek.sc -25
+KPX racute.sc umacron.sc -25
+KPX racute.sc uhungarumlaut.sc -25
+KPX racute.sc ubreve.sc -25
+KPX racute.sc uni021B.sc -15
+KPX racute.sc tcaron.sc -15
+KPX racute.sc omacron.sc -25
+KPX racute.sc ohungarumlaut.sc -25
+KPX racute.sc obreve.sc -25
+KPX racute.sc gdotaccent.sc -25
+KPX racute.sc gcommaaccent.sc -25
+KPX racute.sc gcircumflex.sc -25
+KPX racute.sc gbreve.sc -25
+KPX racute.sc cdotaccent.sc -25
+KPX racute.sc ccircumflex.sc -25
+KPX racute.sc ccaron.sc -25
+KPX racute.sc cacute.sc -25
+KPX racute.sc oogonek.sc -25
+KPX racute.sc oe.sc -20
+KPX racute.sc gcaron.sc -25
+KPX racute.sc gacute.sc -25
+KPX racute.sc hyphen -20
+KPX rcaron.sc ydieresis.sc -20
+KPX rcaron.sc udieresis.sc -25
+KPX rcaron.sc ucircumflex.sc -25
+KPX rcaron.sc oslash.sc -25
+KPX rcaron.sc odieresis.sc -25
+KPX rcaron.sc ccedilla.sc -25
+KPX rcaron.sc y.sc -20
+KPX rcaron.sc w.sc -25
+KPX rcaron.sc v.sc -25
+KPX rcaron.sc u.sc -25
+KPX rcaron.sc t.sc -15
+KPX rcaron.sc o.sc -25
+KPX rcaron.sc g.sc -25
+KPX rcaron.sc c.sc -25
+KPX rcaron.sc ycircumflex.sc -20
+KPX rcaron.sc wgrave.sc -25
+KPX rcaron.sc wdieresis.sc -25
+KPX rcaron.sc wcircumflex.sc -25
+KPX rcaron.sc wacute.sc -25
+KPX rcaron.sc uring.sc -25
+KPX rcaron.sc uogonek.sc -25
+KPX rcaron.sc umacron.sc -25
+KPX rcaron.sc uhungarumlaut.sc -25
+KPX rcaron.sc ubreve.sc -25
+KPX rcaron.sc uni021B.sc -15
+KPX rcaron.sc tcaron.sc -15
+KPX rcaron.sc omacron.sc -25
+KPX rcaron.sc ohungarumlaut.sc -25
+KPX rcaron.sc obreve.sc -25
+KPX rcaron.sc gdotaccent.sc -25
+KPX rcaron.sc gcommaaccent.sc -25
+KPX rcaron.sc gcircumflex.sc -25
+KPX rcaron.sc gbreve.sc -25
+KPX rcaron.sc cdotaccent.sc -25
+KPX rcaron.sc ccircumflex.sc -25
+KPX rcaron.sc ccaron.sc -25
+KPX rcaron.sc cacute.sc -25
+KPX rcaron.sc oogonek.sc -25
+KPX rcaron.sc oe.sc -20
+KPX rcaron.sc gcaron.sc -25
+KPX rcaron.sc gacute.sc -25
+KPX rcaron.sc hyphen -20
+KPX rcommaaccent.sc ydieresis.sc -20
+KPX rcommaaccent.sc udieresis.sc -25
+KPX rcommaaccent.sc ucircumflex.sc -25
+KPX rcommaaccent.sc oslash.sc -25
+KPX rcommaaccent.sc odieresis.sc -25
+KPX rcommaaccent.sc ccedilla.sc -25
+KPX rcommaaccent.sc y.sc -20
+KPX rcommaaccent.sc w.sc -25
+KPX rcommaaccent.sc v.sc -25
+KPX rcommaaccent.sc u.sc -25
+KPX rcommaaccent.sc t.sc -15
+KPX rcommaaccent.sc o.sc -25
+KPX rcommaaccent.sc g.sc -25
+KPX rcommaaccent.sc c.sc -25
+KPX rcommaaccent.sc ycircumflex.sc -20
+KPX rcommaaccent.sc wgrave.sc -25
+KPX rcommaaccent.sc wdieresis.sc -25
+KPX rcommaaccent.sc wcircumflex.sc -25
+KPX rcommaaccent.sc wacute.sc -25
+KPX rcommaaccent.sc uring.sc -25
+KPX rcommaaccent.sc uogonek.sc -25
+KPX rcommaaccent.sc umacron.sc -25
+KPX rcommaaccent.sc uhungarumlaut.sc -25
+KPX rcommaaccent.sc ubreve.sc -25
+KPX rcommaaccent.sc uni021B.sc -15
+KPX rcommaaccent.sc tcaron.sc -15
+KPX rcommaaccent.sc omacron.sc -25
+KPX rcommaaccent.sc ohungarumlaut.sc -25
+KPX rcommaaccent.sc obreve.sc -25
+KPX rcommaaccent.sc gdotaccent.sc -25
+KPX rcommaaccent.sc gcommaaccent.sc -25
+KPX rcommaaccent.sc gcircumflex.sc -25
+KPX rcommaaccent.sc gbreve.sc -25
+KPX rcommaaccent.sc cdotaccent.sc -25
+KPX rcommaaccent.sc ccircumflex.sc -25
+KPX rcommaaccent.sc ccaron.sc -25
+KPX rcommaaccent.sc cacute.sc -25
+KPX rcommaaccent.sc oogonek.sc -25
+KPX rcommaaccent.sc oe.sc -20
+KPX rcommaaccent.sc gcaron.sc -25
+KPX rcommaaccent.sc gacute.sc -25
+KPX rcommaaccent.sc hyphen -20
+KPX sacute.sc ae.sc -20
+KPX sacute.sc aring.sc -15
+KPX sacute.sc adieresis.sc -15
+KPX sacute.sc a.sc -15
+KPX sacute.sc aeacute.sc -20
+KPX sacute.sc aogonek.sc -15
+KPX sacute.sc amacron.sc -15
+KPX scedilla.sc ae.sc -20
+KPX scedilla.sc aring.sc -15
+KPX scedilla.sc adieresis.sc -15
+KPX scedilla.sc a.sc -15
+KPX scedilla.sc aeacute.sc -20
+KPX scedilla.sc aogonek.sc -15
+KPX scedilla.sc amacron.sc -15
+KPX scircumflex.sc ae.sc -20
+KPX scircumflex.sc aring.sc -15
+KPX scircumflex.sc adieresis.sc -15
+KPX scircumflex.sc a.sc -15
+KPX scircumflex.sc aeacute.sc -20
+KPX scircumflex.sc aogonek.sc -15
+KPX scircumflex.sc amacron.sc -15
+KPX uni0219.sc ae.sc -20
+KPX uni0219.sc aring.sc -15
+KPX uni0219.sc adieresis.sc -15
+KPX uni0219.sc a.sc -15
+KPX uni0219.sc aeacute.sc -20
+KPX uni0219.sc aogonek.sc -15
+KPX uni0219.sc amacron.sc -15
+KPX tcaron.sc ydieresis.sc 20
+KPX tcaron.sc oslash.sc -5
+KPX tcaron.sc odieresis.sc -5
+KPX tcaron.sc ccedilla.sc -5
+KPX tcaron.sc ae.sc -35
+KPX tcaron.sc aring.sc -35
+KPX tcaron.sc adieresis.sc -35
+KPX tcaron.sc y.sc 20
+KPX tcaron.sc w.sc 20
+KPX tcaron.sc v.sc 20
+KPX tcaron.sc o.sc -5
+KPX tcaron.sc j.sc 15
+KPX tcaron.sc g.sc -10
+KPX tcaron.sc c.sc -5
+KPX tcaron.sc a.sc -35
+KPX tcaron.sc ycircumflex.sc 20
+KPX tcaron.sc wgrave.sc 20
+KPX tcaron.sc wdieresis.sc 20
+KPX tcaron.sc wcircumflex.sc 20
+KPX tcaron.sc wacute.sc 20
+KPX tcaron.sc omacron.sc -5
+KPX tcaron.sc ohungarumlaut.sc -5
+KPX tcaron.sc obreve.sc -5
+KPX tcaron.sc jcircumflex.sc 15
+KPX tcaron.sc gdotaccent.sc -10
+KPX tcaron.sc gcommaaccent.sc -10
+KPX tcaron.sc gcircumflex.sc -10
+KPX tcaron.sc gbreve.sc -10
+KPX tcaron.sc cdotaccent.sc -5
+KPX tcaron.sc ccircumflex.sc -5
+KPX tcaron.sc ccaron.sc -5
+KPX tcaron.sc cacute.sc -5
+KPX tcaron.sc aeacute.sc -35
+KPX tcaron.sc aogonek.sc -35
+KPX tcaron.sc amacron.sc -35
+KPX tcaron.sc oogonek.sc -5
+KPX tcaron.sc jacute.sc 15
+KPX tcaron.sc gcaron.sc -10
+KPX tcaron.sc gacute.sc -10
+KPX tcaron.sc semicolon -43
+KPX tcaron.sc colon -18
+KPX tcaron.sc period -65
+KPX tcaron.sc hyphen -60
+KPX tcaron.sc comma -70
+KPX uni021B.sc ydieresis.sc 20
+KPX uni021B.sc oslash.sc -5
+KPX uni021B.sc odieresis.sc -5
+KPX uni021B.sc ccedilla.sc -5
+KPX uni021B.sc ae.sc -35
+KPX uni021B.sc aring.sc -35
+KPX uni021B.sc adieresis.sc -35
+KPX uni021B.sc y.sc 20
+KPX uni021B.sc w.sc 20
+KPX uni021B.sc v.sc 20
+KPX uni021B.sc o.sc -5
+KPX uni021B.sc j.sc 15
+KPX uni021B.sc g.sc -10
+KPX uni021B.sc c.sc -5
+KPX uni021B.sc a.sc -35
+KPX uni021B.sc ycircumflex.sc 20
+KPX uni021B.sc wgrave.sc 20
+KPX uni021B.sc wdieresis.sc 20
+KPX uni021B.sc wcircumflex.sc 20
+KPX uni021B.sc wacute.sc 20
+KPX uni021B.sc omacron.sc -5
+KPX uni021B.sc ohungarumlaut.sc -5
+KPX uni021B.sc obreve.sc -5
+KPX uni021B.sc jcircumflex.sc 15
+KPX uni021B.sc gdotaccent.sc -10
+KPX uni021B.sc gcommaaccent.sc -10
+KPX uni021B.sc gcircumflex.sc -10
+KPX uni021B.sc gbreve.sc -10
+KPX uni021B.sc cdotaccent.sc -5
+KPX uni021B.sc ccircumflex.sc -5
+KPX uni021B.sc ccaron.sc -5
+KPX uni021B.sc cacute.sc -5
+KPX uni021B.sc aeacute.sc -35
+KPX uni021B.sc aogonek.sc -35
+KPX uni021B.sc amacron.sc -35
+KPX uni021B.sc oogonek.sc -5
+KPX uni021B.sc jacute.sc 15
+KPX uni021B.sc gcaron.sc -10
+KPX uni021B.sc gacute.sc -10
+KPX uni021B.sc semicolon -70
+KPX uni021B.sc colon -65
+KPX uni021B.sc period -65
+KPX uni021B.sc hyphen -60
+KPX uni021B.sc comma -70
+KPX ubreve.sc ae.sc -35
+KPX ubreve.sc aring.sc -35
+KPX ubreve.sc adieresis.sc -35
+KPX ubreve.sc a.sc -35
+KPX ubreve.sc aeacute.sc -35
+KPX ubreve.sc aogonek.sc -35
+KPX ubreve.sc amacron.sc -35
+KPX ubreve.sc period -15
+KPX ubreve.sc comma -25
+KPX uhungarumlaut.sc ae.sc -35
+KPX uhungarumlaut.sc aring.sc -35
+KPX uhungarumlaut.sc adieresis.sc -35
+KPX uhungarumlaut.sc a.sc -35
+KPX uhungarumlaut.sc aeacute.sc -35
+KPX uhungarumlaut.sc aogonek.sc -35
+KPX uhungarumlaut.sc amacron.sc -35
+KPX uhungarumlaut.sc period -15
+KPX uhungarumlaut.sc comma -25
+KPX umacron.sc ae.sc -35
+KPX umacron.sc aring.sc -35
+KPX umacron.sc adieresis.sc -35
+KPX umacron.sc a.sc -35
+KPX umacron.sc aeacute.sc -35
+KPX umacron.sc aogonek.sc -35
+KPX umacron.sc amacron.sc -35
+KPX umacron.sc period -15
+KPX umacron.sc comma -25
+KPX uogonek.sc ae.sc -35
+KPX uogonek.sc aring.sc -35
+KPX uogonek.sc adieresis.sc -35
+KPX uogonek.sc a.sc -35
+KPX uogonek.sc aeacute.sc -35
+KPX uogonek.sc aogonek.sc -35
+KPX uogonek.sc amacron.sc -35
+KPX uogonek.sc period -15
+KPX uogonek.sc comma -25
+KPX uring.sc ae.sc -35
+KPX uring.sc aring.sc -35
+KPX uring.sc adieresis.sc -35
+KPX uring.sc a.sc -35
+KPX uring.sc aeacute.sc -35
+KPX uring.sc aogonek.sc -35
+KPX uring.sc amacron.sc -35
+KPX uring.sc period -15
+KPX uring.sc comma -25
+KPX utilde.sc a.sc -35
+KPX wacute.sc oslash.sc -25
+KPX wacute.sc odieresis.sc -25
+KPX wacute.sc ccedilla.sc -25
+KPX wacute.sc ae.sc -55
+KPX wacute.sc aring.sc -55
+KPX wacute.sc adieresis.sc -55
+KPX wacute.sc t.sc 20
+KPX wacute.sc s.sc -15
+KPX wacute.sc o.sc -25
+KPX wacute.sc g.sc -25
+KPX wacute.sc c.sc -25
+KPX wacute.sc a.sc -55
+KPX wacute.sc uni021B.sc 20
+KPX wacute.sc tcaron.sc 20
+KPX wacute.sc uni0219.sc -15
+KPX wacute.sc scircumflex.sc -15
+KPX wacute.sc scedilla.sc -15
+KPX wacute.sc sacute.sc -15
+KPX wacute.sc omacron.sc -25
+KPX wacute.sc ohungarumlaut.sc -25
+KPX wacute.sc obreve.sc -25
+KPX wacute.sc gdotaccent.sc -25
+KPX wacute.sc gcommaaccent.sc -25
+KPX wacute.sc gcircumflex.sc -25
+KPX wacute.sc gbreve.sc -25
+KPX wacute.sc cdotaccent.sc -25
+KPX wacute.sc ccircumflex.sc -25
+KPX wacute.sc ccaron.sc -25
+KPX wacute.sc cacute.sc -25
+KPX wacute.sc aeacute.sc -55
+KPX wacute.sc aogonek.sc -55
+KPX wacute.sc amacron.sc -55
+KPX wacute.sc scaron.sc -15
+KPX wacute.sc oogonek.sc -25
+KPX wacute.sc gcaron.sc -25
+KPX wacute.sc gacute.sc -25
+KPX wacute.sc semicolon -55
+KPX wacute.sc colon -40
+KPX wacute.sc period -50
+KPX wacute.sc hyphen -20
+KPX wacute.sc comma -60
+KPX wcircumflex.sc oslash.sc -25
+KPX wcircumflex.sc odieresis.sc -25
+KPX wcircumflex.sc ccedilla.sc -25
+KPX wcircumflex.sc ae.sc -55
+KPX wcircumflex.sc aring.sc -55
+KPX wcircumflex.sc adieresis.sc -55
+KPX wcircumflex.sc t.sc 20
+KPX wcircumflex.sc s.sc -15
+KPX wcircumflex.sc o.sc -25
+KPX wcircumflex.sc g.sc -25
+KPX wcircumflex.sc c.sc -25
+KPX wcircumflex.sc a.sc -55
+KPX wcircumflex.sc uni021B.sc 20
+KPX wcircumflex.sc tcaron.sc 20
+KPX wcircumflex.sc uni0219.sc -15
+KPX wcircumflex.sc scircumflex.sc -15
+KPX wcircumflex.sc scedilla.sc -15
+KPX wcircumflex.sc sacute.sc -15
+KPX wcircumflex.sc omacron.sc -25
+KPX wcircumflex.sc ohungarumlaut.sc -25
+KPX wcircumflex.sc obreve.sc -25
+KPX wcircumflex.sc gdotaccent.sc -25
+KPX wcircumflex.sc gcommaaccent.sc -25
+KPX wcircumflex.sc gcircumflex.sc -25
+KPX wcircumflex.sc gbreve.sc -25
+KPX wcircumflex.sc cdotaccent.sc -25
+KPX wcircumflex.sc ccircumflex.sc -25
+KPX wcircumflex.sc ccaron.sc -25
+KPX wcircumflex.sc cacute.sc -25
+KPX wcircumflex.sc aeacute.sc -55
+KPX wcircumflex.sc aogonek.sc -55
+KPX wcircumflex.sc amacron.sc -55
+KPX wcircumflex.sc scaron.sc -15
+KPX wcircumflex.sc oogonek.sc -25
+KPX wcircumflex.sc gcaron.sc -25
+KPX wcircumflex.sc gacute.sc -25
+KPX wcircumflex.sc semicolon -55
+KPX wcircumflex.sc colon -40
+KPX wcircumflex.sc period -50
+KPX wcircumflex.sc hyphen -20
+KPX wcircumflex.sc comma -60
+KPX wdieresis.sc oslash.sc -25
+KPX wdieresis.sc odieresis.sc -25
+KPX wdieresis.sc ccedilla.sc -25
+KPX wdieresis.sc ae.sc -55
+KPX wdieresis.sc aring.sc -55
+KPX wdieresis.sc adieresis.sc -55
+KPX wdieresis.sc t.sc 20
+KPX wdieresis.sc s.sc -15
+KPX wdieresis.sc o.sc -25
+KPX wdieresis.sc g.sc -25
+KPX wdieresis.sc c.sc -25
+KPX wdieresis.sc a.sc -55
+KPX wdieresis.sc uni021B.sc 20
+KPX wdieresis.sc tcaron.sc 20
+KPX wdieresis.sc uni0219.sc -15
+KPX wdieresis.sc scircumflex.sc -15
+KPX wdieresis.sc scedilla.sc -15
+KPX wdieresis.sc sacute.sc -15
+KPX wdieresis.sc omacron.sc -25
+KPX wdieresis.sc ohungarumlaut.sc -25
+KPX wdieresis.sc obreve.sc -25
+KPX wdieresis.sc gdotaccent.sc -25
+KPX wdieresis.sc gcommaaccent.sc -25
+KPX wdieresis.sc gcircumflex.sc -25
+KPX wdieresis.sc gbreve.sc -25
+KPX wdieresis.sc cdotaccent.sc -25
+KPX wdieresis.sc ccircumflex.sc -25
+KPX wdieresis.sc ccaron.sc -25
+KPX wdieresis.sc cacute.sc -25
+KPX wdieresis.sc aeacute.sc -55
+KPX wdieresis.sc aogonek.sc -55
+KPX wdieresis.sc amacron.sc -55
+KPX wdieresis.sc scaron.sc -15
+KPX wdieresis.sc oogonek.sc -25
+KPX wdieresis.sc gcaron.sc -25
+KPX wdieresis.sc gacute.sc -25
+KPX wdieresis.sc semicolon -55
+KPX wdieresis.sc colon -40
+KPX wdieresis.sc period -50
+KPX wdieresis.sc hyphen -20
+KPX wdieresis.sc comma -60
+KPX wgrave.sc oslash.sc -25
+KPX wgrave.sc odieresis.sc -25
+KPX wgrave.sc ccedilla.sc -25
+KPX wgrave.sc ae.sc -55
+KPX wgrave.sc aring.sc -55
+KPX wgrave.sc adieresis.sc -55
+KPX wgrave.sc t.sc 20
+KPX wgrave.sc s.sc -15
+KPX wgrave.sc o.sc -25
+KPX wgrave.sc g.sc -25
+KPX wgrave.sc c.sc -25
+KPX wgrave.sc a.sc -55
+KPX wgrave.sc uni021B.sc 20
+KPX wgrave.sc tcaron.sc 20
+KPX wgrave.sc uni0219.sc -15
+KPX wgrave.sc scircumflex.sc -15
+KPX wgrave.sc scedilla.sc -15
+KPX wgrave.sc sacute.sc -15
+KPX wgrave.sc omacron.sc -25
+KPX wgrave.sc ohungarumlaut.sc -25
+KPX wgrave.sc obreve.sc -25
+KPX wgrave.sc gdotaccent.sc -25
+KPX wgrave.sc gcommaaccent.sc -25
+KPX wgrave.sc gcircumflex.sc -25
+KPX wgrave.sc gbreve.sc -25
+KPX wgrave.sc cdotaccent.sc -25
+KPX wgrave.sc ccircumflex.sc -25
+KPX wgrave.sc ccaron.sc -25
+KPX wgrave.sc cacute.sc -25
+KPX wgrave.sc aeacute.sc -55
+KPX wgrave.sc aogonek.sc -55
+KPX wgrave.sc amacron.sc -55
+KPX wgrave.sc scaron.sc -15
+KPX wgrave.sc oogonek.sc -25
+KPX wgrave.sc gcaron.sc -25
+KPX wgrave.sc gacute.sc -25
+KPX wgrave.sc semicolon -55
+KPX wgrave.sc colon -40
+KPX wgrave.sc period -50
+KPX wgrave.sc hyphen -20
+KPX wgrave.sc comma -60
+KPX ycircumflex.sc oslash.sc -30
+KPX ycircumflex.sc odieresis.sc -30
+KPX ycircumflex.sc ccedilla.sc -30
+KPX ycircumflex.sc ae.sc -25
+KPX ycircumflex.sc aring.sc -25
+KPX ycircumflex.sc adieresis.sc -25
+KPX ycircumflex.sc t.sc 25
+KPX ycircumflex.sc s.sc -15
+KPX ycircumflex.sc o.sc -30
+KPX ycircumflex.sc g.sc -30
+KPX ycircumflex.sc c.sc -30
+KPX ycircumflex.sc a.sc -25
+KPX ycircumflex.sc uni021B.sc 25
+KPX ycircumflex.sc tcaron.sc 25
+KPX ycircumflex.sc uni0219.sc -15
+KPX ycircumflex.sc scircumflex.sc -15
+KPX ycircumflex.sc scedilla.sc -15
+KPX ycircumflex.sc sacute.sc -15
+KPX ycircumflex.sc omacron.sc -30
+KPX ycircumflex.sc ohungarumlaut.sc -30
+KPX ycircumflex.sc obreve.sc -30
+KPX ycircumflex.sc gdotaccent.sc -30
+KPX ycircumflex.sc gcommaaccent.sc -30
+KPX ycircumflex.sc gcircumflex.sc -30
+KPX ycircumflex.sc gbreve.sc -30
+KPX ycircumflex.sc cdotaccent.sc -30
+KPX ycircumflex.sc ccircumflex.sc -30
+KPX ycircumflex.sc ccaron.sc -30
+KPX ycircumflex.sc cacute.sc -30
+KPX ycircumflex.sc aeacute.sc -25
+KPX ycircumflex.sc aogonek.sc -25
+KPX ycircumflex.sc amacron.sc -25
+KPX ycircumflex.sc scaron.sc -15
+KPX ycircumflex.sc oogonek.sc -30
+KPX ycircumflex.sc gcaron.sc -30
+KPX ycircumflex.sc gacute.sc -30
+KPX ycircumflex.sc semicolon -60
+KPX ycircumflex.sc colon -55
+KPX ycircumflex.sc period -50
+KPX ycircumflex.sc hyphen -45
+KPX ycircumflex.sc comma -55
+KPX a.sc ydieresis.sc -45
+KPX a.sc udieresis.sc -30
+KPX a.sc ucircumflex.sc -30
+KPX a.sc oslash.sc -30
+KPX a.sc odieresis.sc -30
+KPX a.sc ograve.sc -30
+KPX a.sc ccedilla.sc -35
+KPX a.sc y.sc -45
+KPX a.sc w.sc -50
+KPX a.sc v.sc -85
+KPX a.sc u.sc -30
+KPX a.sc t.sc -35
+KPX a.sc q.sc -25
+KPX a.sc o.sc -30
+KPX a.sc g.sc -35
+KPX a.sc c.sc -35
+KPX a.sc ycircumflex.sc -45
+KPX a.sc wgrave.sc -50
+KPX a.sc wdieresis.sc -50
+KPX a.sc wcircumflex.sc -50
+KPX a.sc wacute.sc -50
+KPX a.sc uring.sc -30
+KPX a.sc uogonek.sc -30
+KPX a.sc umacron.sc -30
+KPX a.sc uhungarumlaut.sc -30
+KPX a.sc ubreve.sc -30
+KPX a.sc uni021B.sc -35
+KPX a.sc tcaron.sc -35
+KPX a.sc omacron.sc -30
+KPX a.sc ohungarumlaut.sc -30
+KPX a.sc obreve.sc -30
+KPX a.sc gdotaccent.sc -35
+KPX a.sc gcommaaccent.sc -35
+KPX a.sc gcircumflex.sc -35
+KPX a.sc gbreve.sc -35
+KPX a.sc cdotaccent.sc -35
+KPX a.sc ccircumflex.sc -35
+KPX a.sc ccaron.sc -35
+KPX a.sc cacute.sc -35
+KPX a.sc oogonek.sc -30
+KPX a.sc gcaron.sc -35
+KPX a.sc gacute.sc -35
+KPX a.sc quotedblright -85
+KPX a.sc quoteright -80
+KPX a.sc ringhalfleft -95
+KPX a.sc ringhalfright -95
+KPX a.sc period 10
+KPX a.sc hyphen -10
+KPX b.sc ae.sc -25
+KPX b.sc aring.sc -25
+KPX b.sc adieresis.sc -25
+KPX b.sc atilde.sc -25
+KPX b.sc acircumflex.sc -25
+KPX b.sc aacute.sc -25
+KPX b.sc agrave.sc -25
+KPX b.sc w.sc -15
+KPX b.sc v.sc -15
+KPX b.sc a.sc -25
+KPX b.sc wgrave.sc -15
+KPX b.sc wdieresis.sc -15
+KPX b.sc wcircumflex.sc -15
+KPX b.sc wacute.sc -15
+KPX b.sc aeacute.sc -25
+KPX b.sc aogonek.sc -25
+KPX b.sc amacron.sc -25
+KPX b.sc abreve.sc -25
+KPX b.sc ahookabove.sc -25
+KPX b.sc adotbelow.sc -25
+KPX b.sc acircumflextilde.sc -25
+KPX b.sc acircumflexhookabove.sc -25
+KPX b.sc acircumflexgrave.sc -25
+KPX b.sc acircumflexdotbelow.sc -25
+KPX b.sc acircumflexacute.sc -25
+KPX b.sc abrevetilde.sc -25
+KPX b.sc abrevehookabove.sc -25
+KPX b.sc abrevegrave.sc -25
+KPX b.sc abrevedotbelow.sc -25
+KPX b.sc abreveacute.sc -25
+KPX c.sc oslash.sc -10
+KPX c.sc odieresis.sc -10
+KPX c.sc otilde.sc -10
+KPX c.sc ocircumflex.sc -10
+KPX c.sc oacute.sc -10
+KPX c.sc ograve.sc -10
+KPX c.sc aring.sc 5
+KPX c.sc adieresis.sc 5
+KPX c.sc atilde.sc 5
+KPX c.sc acircumflex.sc 5
+KPX c.sc aacute.sc 5
+KPX c.sc agrave.sc 5
+KPX c.sc o.sc -10
+KPX c.sc k.sc 5
+KPX c.sc h.sc 10
+KPX c.sc a.sc 5
+KPX c.sc omacron.sc -10
+KPX c.sc ohungarumlaut.sc -10
+KPX c.sc obreve.sc -10
+KPX c.sc kcommaaccent.sc 5
+KPX c.sc hcircumflex.sc 10
+KPX c.sc aogonek.sc 5
+KPX c.sc amacron.sc 5
+KPX c.sc abreve.sc 5
+KPX c.sc oogonek.sc -10
+KPX c.sc ohorntilde.sc -10
+KPX c.sc ohornhookabove.sc -10
+KPX c.sc ohorngrave.sc -10
+KPX c.sc ohorndotbelow.sc -10
+KPX c.sc ohornacute.sc -10
+KPX c.sc ohookabove.sc -10
+KPX c.sc odotbelow.sc -10
+KPX c.sc ocircumflextilde.sc -10
+KPX c.sc ocircumflexhookabove.sc -10
+KPX c.sc ocircumflexgrave.sc -10
+KPX c.sc ocircumflexdotbelow.sc -10
+KPX c.sc ocircumflexacute.sc -10
+KPX c.sc ahookabove.sc 5
+KPX c.sc adotbelow.sc 5
+KPX c.sc acircumflextilde.sc 5
+KPX c.sc acircumflexhookabove.sc 5
+KPX c.sc acircumflexgrave.sc 5
+KPX c.sc acircumflexdotbelow.sc 5
+KPX c.sc acircumflexacute.sc 5
+KPX c.sc abrevetilde.sc 5
+KPX c.sc abrevehookabove.sc 5
+KPX c.sc abrevegrave.sc 5
+KPX c.sc abrevedotbelow.sc 5
+KPX c.sc abreveacute.sc 5
+KPX d.sc ydieresis.sc -20
+KPX d.sc aring.sc -45
+KPX d.sc adieresis.sc -45
+KPX d.sc atilde.sc -45
+KPX d.sc acircumflex.sc -45
+KPX d.sc aacute.sc -45
+KPX d.sc agrave.sc -45
+KPX d.sc y.sc -20
+KPX d.sc x.sc -25
+KPX d.sc w.sc -25
+KPX d.sc v.sc -25
+KPX d.sc j.sc -15
+KPX d.sc a.sc -45
+KPX d.sc ycircumflex.sc -20
+KPX d.sc wgrave.sc -25
+KPX d.sc wdieresis.sc -25
+KPX d.sc wcircumflex.sc -25
+KPX d.sc wacute.sc -25
+KPX d.sc jcircumflex.sc -15
+KPX d.sc aogonek.sc -45
+KPX d.sc amacron.sc -45
+KPX d.sc abreve.sc -45
+KPX d.sc jacute.sc -15
+KPX d.sc ahookabove.sc -45
+KPX d.sc adotbelow.sc -45
+KPX d.sc acircumflextilde.sc -45
+KPX d.sc acircumflexhookabove.sc -45
+KPX d.sc acircumflexgrave.sc -45
+KPX d.sc acircumflexdotbelow.sc -45
+KPX d.sc acircumflexacute.sc -45
+KPX d.sc abrevehookabove.sc -45
+KPX d.sc abrevegrave.sc -45
+KPX d.sc abrevedotbelow.sc -45
+KPX d.sc abreveacute.sc -45
+KPX f.sc aring.sc -45
+KPX f.sc adieresis.sc -45
+KPX f.sc j.sc 15
+KPX f.sc a.sc -45
+KPX f.sc jcircumflex.sc 15
+KPX f.sc aogonek.sc -45
+KPX f.sc amacron.sc -45
+KPX f.sc jacute.sc 15
+KPX f.sc period -35
+KPX f.sc hyphen 20
+KPX f.sc comma -45
+KPX g.sc ydieresis.sc -10
+KPX g.sc ae.sc -10
+KPX g.sc aring.sc -10
+KPX g.sc adieresis.sc -10
+KPX g.sc atilde.sc -10
+KPX g.sc acircumflex.sc -10
+KPX g.sc aacute.sc -10
+KPX g.sc agrave.sc -10
+KPX g.sc y.sc -10
+KPX g.sc w.sc -10
+KPX g.sc v.sc -15
+KPX g.sc t.sc -10
+KPX g.sc a.sc -10
+KPX g.sc ycircumflex.sc -10
+KPX g.sc wgrave.sc -10
+KPX g.sc wdieresis.sc -10
+KPX g.sc wcircumflex.sc -10
+KPX g.sc wacute.sc -10
+KPX g.sc uni021B.sc -10
+KPX g.sc tcaron.sc -10
+KPX g.sc aeacute.sc -10
+KPX g.sc aogonek.sc -10
+KPX g.sc amacron.sc -10
+KPX g.sc abreve.sc -10
+KPX g.sc ahookabove.sc -10
+KPX g.sc adotbelow.sc -10
+KPX g.sc acircumflextilde.sc -10
+KPX g.sc acircumflexhookabove.sc -10
+KPX g.sc acircumflexgrave.sc -10
+KPX g.sc acircumflexdotbelow.sc -10
+KPX g.sc acircumflexacute.sc -10
+KPX g.sc abrevetilde.sc -10
+KPX g.sc abrevehookabove.sc -10
+KPX g.sc abrevegrave.sc -10
+KPX g.sc abrevedotbelow.sc -10
+KPX g.sc abreveacute.sc -10
+KPX j.sc ae.sc -15
+KPX j.sc aring.sc -20
+KPX j.sc adieresis.sc -20
+KPX j.sc a.sc -20
+KPX j.sc aeacute.sc -15
+KPX j.sc aogonek.sc -20
+KPX j.sc amacron.sc -20
+KPX k.sc oslash.sc -25
+KPX k.sc odieresis.sc -25
+KPX k.sc ccedilla.sc -35
+KPX k.sc t.sc 15
+KPX k.sc o.sc -25
+KPX k.sc g.sc -35
+KPX k.sc c.sc -35
+KPX k.sc uni021B.sc 15
+KPX k.sc tcaron.sc 15
+KPX k.sc omacron.sc -25
+KPX k.sc ohungarumlaut.sc -25
+KPX k.sc obreve.sc -25
+KPX k.sc gdotaccent.sc -35
+KPX k.sc gcommaaccent.sc -35
+KPX k.sc gcircumflex.sc -35
+KPX k.sc gbreve.sc -35
+KPX k.sc cdotaccent.sc -35
+KPX k.sc ccircumflex.sc -35
+KPX k.sc ccaron.sc -35
+KPX k.sc cacute.sc -35
+KPX k.sc oogonek.sc -25
+KPX k.sc oe.sc -25
+KPX k.sc gcaron.sc -35
+KPX k.sc gacute.sc -35
+KPX k.sc hyphen -45
+KPX l.sc ydieresis.sc -50
+KPX l.sc yacute.sc -50
+KPX l.sc udieresis.sc -15
+KPX l.sc ucircumflex.sc -15
+KPX l.sc uacute.sc -15
+KPX l.sc ugrave.sc -15
+KPX l.sc ccedilla.sc -5
+KPX l.sc ae.sc 15
+KPX l.sc aring.sc 10
+KPX l.sc adieresis.sc 10
+KPX l.sc atilde.sc 10
+KPX l.sc acircumflex.sc 10
+KPX l.sc aacute.sc 10
+KPX l.sc agrave.sc 10
+KPX l.sc y.sc -50
+KPX l.sc w.sc -45
+KPX l.sc v.sc -65
+KPX l.sc u.sc -15
+KPX l.sc t.sc -45
+KPX l.sc g.sc -10
+KPX l.sc c.sc -5
+KPX l.sc a.sc 10
+KPX l.sc ycircumflex.sc -50
+KPX l.sc wgrave.sc -45
+KPX l.sc wdieresis.sc -45
+KPX l.sc wcircumflex.sc -45
+KPX l.sc wacute.sc -45
+KPX l.sc utilde.sc -15
+KPX l.sc uring.sc -15
+KPX l.sc uogonek.sc -15
+KPX l.sc umacron.sc -15
+KPX l.sc uhungarumlaut.sc -15
+KPX l.sc ubreve.sc -15
+KPX l.sc uni021B.sc -45
+KPX l.sc tcaron.sc -45
+KPX l.sc gdotaccent.sc -10
+KPX l.sc gcommaaccent.sc -10
+KPX l.sc gcircumflex.sc -10
+KPX l.sc gbreve.sc -10
+KPX l.sc cdotaccent.sc -5
+KPX l.sc ccircumflex.sc -5
+KPX l.sc ccaron.sc -5
+KPX l.sc cacute.sc -5
+KPX l.sc aeacute.sc 15
+KPX l.sc aogonek.sc 10
+KPX l.sc amacron.sc 10
+KPX l.sc abreve.sc 10
+KPX l.sc uhorntilde.sc -15
+KPX l.sc uhornhookabove.sc -15
+KPX l.sc uhorngrave.sc -15
+KPX l.sc uhorndotbelow.sc -15
+KPX l.sc uhornacute.sc -15
+KPX l.sc uhookabove.sc -15
+KPX l.sc udotbelow.sc -15
+KPX l.sc gcaron.sc -10
+KPX l.sc gacute.sc -10
+KPX l.sc ahookabove.sc 10
+KPX l.sc adotbelow.sc 10
+KPX l.sc acircumflextilde.sc 10
+KPX l.sc acircumflexhookabove.sc 10
+KPX l.sc acircumflexgrave.sc 10
+KPX l.sc acircumflexdotbelow.sc 10
+KPX l.sc acircumflexacute.sc 10
+KPX l.sc abrevetilde.sc 10
+KPX l.sc abrevehookabove.sc 10
+KPX l.sc abrevegrave.sc 10
+KPX l.sc abrevedotbelow.sc 10
+KPX l.sc abreveacute.sc 10
+KPX l.sc quotedblright -80
+KPX l.sc quoteright -80
+KPX l.sc hyphen 20
+KPX n.sc oslash.sc -15
+KPX n.sc odieresis.sc -15
+KPX n.sc otilde.sc -15
+KPX n.sc ocircumflex.sc -15
+KPX n.sc oacute.sc -15
+KPX n.sc ograve.sc -15
+KPX n.sc ccedilla.sc -15
+KPX n.sc ae.sc -15
+KPX n.sc aring.sc -15
+KPX n.sc adieresis.sc -15
+KPX n.sc atilde.sc -15
+KPX n.sc acircumflex.sc -15
+KPX n.sc aacute.sc -15
+KPX n.sc agrave.sc -15
+KPX n.sc o.sc -15
+KPX n.sc g.sc -15
+KPX n.sc c.sc -15
+KPX n.sc a.sc -15
+KPX n.sc omacron.sc -15
+KPX n.sc ohungarumlaut.sc -15
+KPX n.sc obreve.sc -15
+KPX n.sc gdotaccent.sc -15
+KPX n.sc gcommaaccent.sc -15
+KPX n.sc gcircumflex.sc -15
+KPX n.sc gbreve.sc -15
+KPX n.sc cdotaccent.sc -15
+KPX n.sc ccircumflex.sc -15
+KPX n.sc ccaron.sc -15
+KPX n.sc cacute.sc -15
+KPX n.sc aeacute.sc -15
+KPX n.sc aogonek.sc -15
+KPX n.sc amacron.sc -15
+KPX n.sc abreve.sc -15
+KPX n.sc oogonek.sc -15
+KPX n.sc ohorntilde.sc -15
+KPX n.sc ohornhookabove.sc -15
+KPX n.sc ohorngrave.sc -15
+KPX n.sc ohorndotbelow.sc -15
+KPX n.sc ohornacute.sc -15
+KPX n.sc ohookabove.sc -15
+KPX n.sc odotbelow.sc -15
+KPX n.sc ocircumflextilde.sc -15
+KPX n.sc ocircumflexhookabove.sc -15
+KPX n.sc ocircumflexgrave.sc -15
+KPX n.sc ocircumflexdotbelow.sc -15
+KPX n.sc ocircumflexacute.sc -15
+KPX n.sc gcaron.sc -15
+KPX n.sc gacute.sc -15
+KPX n.sc ahookabove.sc -15
+KPX n.sc adotbelow.sc -15
+KPX n.sc acircumflextilde.sc -15
+KPX n.sc acircumflexhookabove.sc -15
+KPX n.sc acircumflexgrave.sc -15
+KPX n.sc acircumflexdotbelow.sc -15
+KPX n.sc acircumflexacute.sc -15
+KPX n.sc abrevegrave.sc -15
+KPX n.sc abrevedotbelow.sc -15
+KPX n.sc abreveacute.sc -15
+KPX n.sc comma -10
+KPX o.sc ydieresis.sc -25
+KPX o.sc ae.sc -35
+KPX o.sc aring.sc -35
+KPX o.sc adieresis.sc -35
+KPX o.sc atilde.sc -35
+KPX o.sc aacute.sc -35
+KPX o.sc agrave.sc -35
+KPX o.sc y.sc -25
+KPX o.sc x.sc -25
+KPX o.sc w.sc -20
+KPX o.sc v.sc -35
+KPX o.sc a.sc -35
+KPX o.sc ycircumflex.sc -25
+KPX o.sc wgrave.sc -20
+KPX o.sc wdieresis.sc -20
+KPX o.sc wcircumflex.sc -20
+KPX o.sc wacute.sc -20
+KPX o.sc aeacute.sc -35
+KPX o.sc aogonek.sc -35
+KPX o.sc amacron.sc -35
+KPX o.sc abreve.sc -35
+KPX o.sc ahookabove.sc -35
+KPX o.sc adotbelow.sc -35
+KPX o.sc abrevetilde.sc -35
+KPX o.sc abrevehookabove.sc -35
+KPX o.sc abrevegrave.sc -35
+KPX o.sc abrevedotbelow.sc -35
+KPX o.sc abreveacute.sc -35
+KPX p.sc ae.sc -60
+KPX p.sc aring.sc -60
+KPX p.sc adieresis.sc -60
+KPX p.sc aacute.sc -60
+KPX p.sc a.sc -60
+KPX p.sc aeacute.sc -60
+KPX p.sc aogonek.sc -60
+KPX p.sc amacron.sc -60
+KPX p.sc period -85
+KPX p.sc hyphen -30
+KPX p.sc comma -95
+KPX r.sc ydieresis.sc -20
+KPX r.sc udieresis.sc -25
+KPX r.sc ucircumflex.sc -25
+KPX r.sc uacute.sc -25
+KPX r.sc ugrave.sc -25
+KPX r.sc oslash.sc -25
+KPX r.sc odieresis.sc -25
+KPX r.sc otilde.sc -25
+KPX r.sc ocircumflex.sc -25
+KPX r.sc oacute.sc -25
+KPX r.sc ograve.sc -25
+KPX r.sc ccedilla.sc -25
+KPX r.sc y.sc -20
+KPX r.sc w.sc -25
+KPX r.sc v.sc -25
+KPX r.sc u.sc -25
+KPX r.sc t.sc -15
+KPX r.sc o.sc -25
+KPX r.sc g.sc -25
+KPX r.sc c.sc -25
+KPX r.sc ycircumflex.sc -20
+KPX r.sc wgrave.sc -25
+KPX r.sc wdieresis.sc -25
+KPX r.sc wcircumflex.sc -25
+KPX r.sc wacute.sc -25
+KPX r.sc utilde.sc -25
+KPX r.sc uring.sc -25
+KPX r.sc uogonek.sc -25
+KPX r.sc umacron.sc -25
+KPX r.sc uhungarumlaut.sc -25
+KPX r.sc ubreve.sc -25
+KPX r.sc uni021B.sc -15
+KPX r.sc tcaron.sc -15
+KPX r.sc omacron.sc -25
+KPX r.sc ohungarumlaut.sc -25
+KPX r.sc obreve.sc -25
+KPX r.sc gdotaccent.sc -25
+KPX r.sc gcommaaccent.sc -25
+KPX r.sc gcircumflex.sc -25
+KPX r.sc gbreve.sc -25
+KPX r.sc cdotaccent.sc -25
+KPX r.sc ccircumflex.sc -25
+KPX r.sc ccaron.sc -25
+KPX r.sc cacute.sc -25
+KPX r.sc uhorntilde.sc -25
+KPX r.sc uhornhookabove.sc -25
+KPX r.sc uhorngrave.sc -25
+KPX r.sc uhorndotbelow.sc -25
+KPX r.sc uhornacute.sc -25
+KPX r.sc uhookabove.sc -25
+KPX r.sc udotbelow.sc -25
+KPX r.sc oogonek.sc -25
+KPX r.sc ohorntilde.sc -25
+KPX r.sc ohornhookabove.sc -25
+KPX r.sc ohorngrave.sc -25
+KPX r.sc ohorndotbelow.sc -25
+KPX r.sc ohornacute.sc -25
+KPX r.sc ohookabove.sc -25
+KPX r.sc oe.sc -20
+KPX r.sc odotbelow.sc -25
+KPX r.sc ocircumflextilde.sc -25
+KPX r.sc ocircumflexhookabove.sc -25
+KPX r.sc ocircumflexgrave.sc -25
+KPX r.sc ocircumflexdotbelow.sc -25
+KPX r.sc ocircumflexacute.sc -25
+KPX r.sc gcaron.sc -25
+KPX r.sc gacute.sc -25
+KPX r.sc hyphen -20
+KPX s.sc ae.sc -20
+KPX s.sc aring.sc -15
+KPX s.sc adieresis.sc -15
+KPX s.sc atilde.sc -15
+KPX s.sc acircumflex.sc -15
+KPX s.sc aacute.sc -15
+KPX s.sc agrave.sc -15
+KPX s.sc a.sc -15
+KPX s.sc aeacute.sc -20
+KPX s.sc aogonek.sc -15
+KPX s.sc amacron.sc -15
+KPX s.sc abreve.sc -15
+KPX s.sc ahookabove.sc -15
+KPX s.sc adotbelow.sc -15
+KPX s.sc acircumflextilde.sc -15
+KPX s.sc acircumflexhookabove.sc -15
+KPX s.sc acircumflexgrave.sc -15
+KPX s.sc acircumflexdotbelow.sc -15
+KPX s.sc acircumflexacute.sc -15
+KPX s.sc abrevetilde.sc -15
+KPX s.sc abrevegrave.sc -15
+KPX s.sc abrevedotbelow.sc -15
+KPX s.sc abreveacute.sc -15
+KPX t.sc ydieresis.sc 20
+KPX t.sc oslash.sc -5
+KPX t.sc odieresis.sc -5
+KPX t.sc otilde.sc -5
+KPX t.sc ocircumflex.sc -5
+KPX t.sc oacute.sc -5
+KPX t.sc ograve.sc -5
+KPX t.sc ccedilla.sc -5
+KPX t.sc ae.sc -35
+KPX t.sc aring.sc -35
+KPX t.sc adieresis.sc -35
+KPX t.sc atilde.sc -35
+KPX t.sc acircumflex.sc -35
+KPX t.sc aacute.sc -35
+KPX t.sc agrave.sc -35
+KPX t.sc y.sc 20
+KPX t.sc w.sc 20
+KPX t.sc v.sc 20
+KPX t.sc o.sc -5
+KPX t.sc j.sc 15
+KPX t.sc g.sc -10
+KPX t.sc c.sc -5
+KPX t.sc a.sc -35
+KPX t.sc ycircumflex.sc 20
+KPX t.sc wgrave.sc 20
+KPX t.sc wdieresis.sc 20
+KPX t.sc wcircumflex.sc 20
+KPX t.sc wacute.sc 20
+KPX t.sc omacron.sc -5
+KPX t.sc ohungarumlaut.sc -5
+KPX t.sc obreve.sc -5
+KPX t.sc jcircumflex.sc 15
+KPX t.sc gdotaccent.sc -10
+KPX t.sc gcommaaccent.sc -10
+KPX t.sc gcircumflex.sc -10
+KPX t.sc gbreve.sc -10
+KPX t.sc cdotaccent.sc -5
+KPX t.sc ccircumflex.sc -5
+KPX t.sc ccaron.sc -5
+KPX t.sc cacute.sc -5
+KPX t.sc aeacute.sc -35
+KPX t.sc aogonek.sc -35
+KPX t.sc amacron.sc -35
+KPX t.sc abreve.sc -35
+KPX t.sc oogonek.sc -5
+KPX t.sc ohornhookabove.sc -5
+KPX t.sc ohorngrave.sc -5
+KPX t.sc ohorndotbelow.sc -5
+KPX t.sc ohornacute.sc -5
+KPX t.sc ohookabove.sc -5
+KPX t.sc odotbelow.sc -5
+KPX t.sc ocircumflexhookabove.sc -5
+KPX t.sc ocircumflexgrave.sc -5
+KPX t.sc ocircumflexdotbelow.sc -5
+KPX t.sc ocircumflexacute.sc -5
+KPX t.sc jacute.sc 15
+KPX t.sc gcaron.sc -10
+KPX t.sc gacute.sc -10
+KPX t.sc ahookabove.sc -35
+KPX t.sc adotbelow.sc -35
+KPX t.sc acircumflexhookabove.sc -35
+KPX t.sc acircumflexgrave.sc -35
+KPX t.sc acircumflexdotbelow.sc -35
+KPX t.sc acircumflexacute.sc -35
+KPX t.sc abrevehookabove.sc -35
+KPX t.sc abrevegrave.sc -35
+KPX t.sc abrevedotbelow.sc -35
+KPX t.sc abreveacute.sc -35
+KPX t.sc semicolon -43
+KPX t.sc colon -32
+KPX t.sc period -65
+KPX t.sc hyphen -60
+KPX t.sc comma -70
+KPX u.sc ae.sc -35
+KPX u.sc aring.sc -35
+KPX u.sc adieresis.sc -35
+KPX u.sc atilde.sc -35
+KPX u.sc acircumflex.sc -35
+KPX u.sc aacute.sc -35
+KPX u.sc agrave.sc -35
+KPX u.sc a.sc -35
+KPX u.sc aeacute.sc -35
+KPX u.sc aogonek.sc -35
+KPX u.sc amacron.sc -35
+KPX u.sc abreve.sc -35
+KPX u.sc ahookabove.sc -35
+KPX u.sc adotbelow.sc -35
+KPX u.sc acircumflextilde.sc -35
+KPX u.sc acircumflexhookabove.sc -35
+KPX u.sc acircumflexgrave.sc -35
+KPX u.sc acircumflexdotbelow.sc -35
+KPX u.sc acircumflexacute.sc -35
+KPX u.sc abrevehookabove.sc -35
+KPX u.sc abrevegrave.sc -35
+KPX u.sc abrevedotbelow.sc -35
+KPX u.sc abreveacute.sc -35
+KPX u.sc period -15
+KPX u.sc comma -25
+KPX v.sc oslash.sc -35
+KPX v.sc odieresis.sc -35
+KPX v.sc otilde.sc -35
+KPX v.sc ocircumflex.sc -35
+KPX v.sc oacute.sc -35
+KPX v.sc ograve.sc -35
+KPX v.sc ccedilla.sc -35
+KPX v.sc ae.sc -80
+KPX v.sc aring.sc -80
+KPX v.sc adieresis.sc -80
+KPX v.sc atilde.sc -80
+KPX v.sc acircumflex.sc -80
+KPX v.sc aacute.sc -80
+KPX v.sc agrave.sc -80
+KPX v.sc t.sc 20
+KPX v.sc s.sc -15
+KPX v.sc o.sc -35
+KPX v.sc g.sc -35
+KPX v.sc c.sc -35
+KPX v.sc a.sc -80
+KPX v.sc uni021B.sc 20
+KPX v.sc tcaron.sc 20
+KPX v.sc uni0219.sc -15
+KPX v.sc scircumflex.sc -15
+KPX v.sc scedilla.sc -15
+KPX v.sc sacute.sc -15
+KPX v.sc omacron.sc -35
+KPX v.sc ohungarumlaut.sc -35
+KPX v.sc obreve.sc -35
+KPX v.sc gdotaccent.sc -35
+KPX v.sc gcommaaccent.sc -35
+KPX v.sc gcircumflex.sc -35
+KPX v.sc gbreve.sc -35
+KPX v.sc cdotaccent.sc -35
+KPX v.sc ccircumflex.sc -35
+KPX v.sc ccaron.sc -35
+KPX v.sc cacute.sc -35
+KPX v.sc aeacute.sc -80
+KPX v.sc aogonek.sc -80
+KPX v.sc amacron.sc -80
+KPX v.sc abreve.sc -80
+KPX v.sc scaron.sc -15
+KPX v.sc oogonek.sc -35
+KPX v.sc ohorntilde.sc -35
+KPX v.sc ohornhookabove.sc -35
+KPX v.sc ohorngrave.sc -35
+KPX v.sc ohorndotbelow.sc -35
+KPX v.sc ohornacute.sc -35
+KPX v.sc ohookabove.sc -35
+KPX v.sc odotbelow.sc -35
+KPX v.sc ocircumflextilde.sc -35
+KPX v.sc ocircumflexhookabove.sc -35
+KPX v.sc ocircumflexgrave.sc -35
+KPX v.sc ocircumflexdotbelow.sc -35
+KPX v.sc ocircumflexacute.sc -35
+KPX v.sc gcaron.sc -35
+KPX v.sc gacute.sc -35
+KPX v.sc ahookabove.sc -80
+KPX v.sc adotbelow.sc -80
+KPX v.sc acircumflextilde.sc -80
+KPX v.sc acircumflexhookabove.sc -80
+KPX v.sc acircumflexgrave.sc -80
+KPX v.sc acircumflexdotbelow.sc -80
+KPX v.sc acircumflexacute.sc -80
+KPX v.sc abrevehookabove.sc -80
+KPX v.sc abrevegrave.sc -80
+KPX v.sc abrevedotbelow.sc -80
+KPX v.sc abreveacute.sc -80
+KPX v.sc semicolon -75
+KPX v.sc colon -65
+KPX v.sc period -90
+KPX v.sc hyphen -50
+KPX v.sc comma -100
+KPX w.sc oslash.sc -25
+KPX w.sc odieresis.sc -25
+KPX w.sc ccedilla.sc -25
+KPX w.sc ae.sc -55
+KPX w.sc aring.sc -55
+KPX w.sc adieresis.sc -55
+KPX w.sc t.sc 20
+KPX w.sc s.sc -15
+KPX w.sc o.sc -25
+KPX w.sc g.sc -25
+KPX w.sc c.sc -25
+KPX w.sc a.sc -55
+KPX w.sc uni021B.sc 20
+KPX w.sc tcaron.sc 20
+KPX w.sc uni0219.sc -15
+KPX w.sc scircumflex.sc -15
+KPX w.sc scedilla.sc -15
+KPX w.sc sacute.sc -15
+KPX w.sc omacron.sc -25
+KPX w.sc ohungarumlaut.sc -25
+KPX w.sc obreve.sc -25
+KPX w.sc gdotaccent.sc -25
+KPX w.sc gcommaaccent.sc -25
+KPX w.sc gcircumflex.sc -25
+KPX w.sc gbreve.sc -25
+KPX w.sc cdotaccent.sc -25
+KPX w.sc ccircumflex.sc -25
+KPX w.sc ccaron.sc -25
+KPX w.sc cacute.sc -25
+KPX w.sc aeacute.sc -55
+KPX w.sc aogonek.sc -55
+KPX w.sc amacron.sc -55
+KPX w.sc scaron.sc -15
+KPX w.sc oogonek.sc -25
+KPX w.sc gcaron.sc -25
+KPX w.sc gacute.sc -25
+KPX w.sc semicolon -55
+KPX w.sc colon -40
+KPX w.sc period -50
+KPX w.sc hyphen -20
+KPX w.sc comma -60
+KPX x.sc oslash.sc -25
+KPX x.sc odieresis.sc -25
+KPX x.sc otilde.sc -25
+KPX x.sc ocircumflex.sc -25
+KPX x.sc oacute.sc -25
+KPX x.sc ograve.sc -25
+KPX x.sc ccedilla.sc -25
+KPX x.sc q.sc -25
+KPX x.sc o.sc -25
+KPX x.sc c.sc -25
+KPX x.sc omacron.sc -25
+KPX x.sc ohungarumlaut.sc -25
+KPX x.sc obreve.sc -25
+KPX x.sc cdotaccent.sc -25
+KPX x.sc ccircumflex.sc -25
+KPX x.sc ccaron.sc -25
+KPX x.sc cacute.sc -25
+KPX x.sc oogonek.sc -25
+KPX x.sc ohorntilde.sc -25
+KPX x.sc ohornhookabove.sc -25
+KPX x.sc ohorngrave.sc -25
+KPX x.sc ohorndotbelow.sc -25
+KPX x.sc ohornacute.sc -25
+KPX x.sc ohookabove.sc -25
+KPX x.sc odotbelow.sc -25
+KPX x.sc ocircumflexhookabove.sc -25
+KPX x.sc ocircumflexgrave.sc -25
+KPX x.sc ocircumflexdotbelow.sc -25
+KPX x.sc ocircumflexacute.sc -25
+KPX x.sc hyphen -20
+KPX y.sc oslash.sc -30
+KPX y.sc odieresis.sc -30
+KPX y.sc ccedilla.sc -30
+KPX y.sc ae.sc -25
+KPX y.sc aring.sc -25
+KPX y.sc adieresis.sc -25
+KPX y.sc t.sc 25
+KPX y.sc s.sc -15
+KPX y.sc o.sc -30
+KPX y.sc g.sc -30
+KPX y.sc c.sc -30
+KPX y.sc a.sc -25
+KPX y.sc uni021B.sc 25
+KPX y.sc tcaron.sc 25
+KPX y.sc uni0219.sc -15
+KPX y.sc scircumflex.sc -15
+KPX y.sc scedilla.sc -15
+KPX y.sc sacute.sc -15
+KPX y.sc omacron.sc -30
+KPX y.sc ohungarumlaut.sc -30
+KPX y.sc obreve.sc -30
+KPX y.sc gdotaccent.sc -30
+KPX y.sc gcommaaccent.sc -30
+KPX y.sc gcircumflex.sc -30
+KPX y.sc gbreve.sc -30
+KPX y.sc cdotaccent.sc -30
+KPX y.sc ccircumflex.sc -30
+KPX y.sc ccaron.sc -30
+KPX y.sc cacute.sc -30
+KPX y.sc aeacute.sc -25
+KPX y.sc aogonek.sc -25
+KPX y.sc amacron.sc -25
+KPX y.sc scaron.sc -15
+KPX y.sc oogonek.sc -30
+KPX y.sc gcaron.sc -30
+KPX y.sc gacute.sc -30
+KPX y.sc semicolon -60
+KPX y.sc colon -55
+KPX y.sc period -50
+KPX y.sc hyphen -45
+KPX y.sc comma -55
+KPX agrave.sc y.sc -45
+KPX agrave.sc u.sc -30
+KPX agrave.sc o.sc -30
+KPX aacute.sc y.sc -45
+KPX aacute.sc u.sc -30
+KPX aacute.sc t.sc -35
+KPX aacute.sc o.sc -30
+KPX aacute.sc c.sc -35
+KPX acircumflex.sc y.sc -45
+KPX acircumflex.sc u.sc -30
+KPX atilde.sc y.sc -45
+KPX atilde.sc o.sc -30
+KPX adieresis.sc ydieresis.sc -45
+KPX adieresis.sc udieresis.sc -30
+KPX adieresis.sc ucircumflex.sc -30
+KPX adieresis.sc oslash.sc -30
+KPX adieresis.sc odieresis.sc -30
+KPX adieresis.sc ccedilla.sc -35
+KPX adieresis.sc y.sc -45
+KPX adieresis.sc w.sc -50
+KPX adieresis.sc v.sc -85
+KPX adieresis.sc u.sc -30
+KPX adieresis.sc t.sc -35
+KPX adieresis.sc q.sc -25
+KPX adieresis.sc o.sc -30
+KPX adieresis.sc g.sc -35
+KPX adieresis.sc c.sc -35
+KPX adieresis.sc ycircumflex.sc -45
+KPX adieresis.sc wgrave.sc -50
+KPX adieresis.sc wdieresis.sc -50
+KPX adieresis.sc wcircumflex.sc -50
+KPX adieresis.sc wacute.sc -50
+KPX adieresis.sc uring.sc -30
+KPX adieresis.sc uogonek.sc -30
+KPX adieresis.sc umacron.sc -30
+KPX adieresis.sc uhungarumlaut.sc -30
+KPX adieresis.sc ubreve.sc -30
+KPX adieresis.sc uni021B.sc -35
+KPX adieresis.sc tcaron.sc -35
+KPX adieresis.sc omacron.sc -30
+KPX adieresis.sc ohungarumlaut.sc -30
+KPX adieresis.sc obreve.sc -30
+KPX adieresis.sc gdotaccent.sc -35
+KPX adieresis.sc gcommaaccent.sc -35
+KPX adieresis.sc gcircumflex.sc -35
+KPX adieresis.sc gbreve.sc -35
+KPX adieresis.sc cdotaccent.sc -35
+KPX adieresis.sc ccircumflex.sc -35
+KPX adieresis.sc ccaron.sc -35
+KPX adieresis.sc cacute.sc -35
+KPX adieresis.sc oogonek.sc -30
+KPX adieresis.sc gcaron.sc -35
+KPX adieresis.sc gacute.sc -35
+KPX adieresis.sc quotedblright -85
+KPX adieresis.sc quoteright -80
+KPX adieresis.sc period 10
+KPX adieresis.sc hyphen -10
+KPX aring.sc ydieresis.sc -45
+KPX aring.sc udieresis.sc -30
+KPX aring.sc ucircumflex.sc -30
+KPX aring.sc oslash.sc -30
+KPX aring.sc odieresis.sc -30
+KPX aring.sc ccedilla.sc -35
+KPX aring.sc y.sc -45
+KPX aring.sc w.sc -50
+KPX aring.sc v.sc -85
+KPX aring.sc u.sc -30
+KPX aring.sc t.sc -35
+KPX aring.sc q.sc -25
+KPX aring.sc o.sc -30
+KPX aring.sc g.sc -35
+KPX aring.sc c.sc -35
+KPX aring.sc ycircumflex.sc -45
+KPX aring.sc wgrave.sc -50
+KPX aring.sc wdieresis.sc -50
+KPX aring.sc wcircumflex.sc -50
+KPX aring.sc wacute.sc -50
+KPX aring.sc uring.sc -30
+KPX aring.sc uogonek.sc -30
+KPX aring.sc umacron.sc -30
+KPX aring.sc uhungarumlaut.sc -30
+KPX aring.sc ubreve.sc -30
+KPX aring.sc uni021B.sc -35
+KPX aring.sc tcaron.sc -35
+KPX aring.sc omacron.sc -30
+KPX aring.sc ohungarumlaut.sc -30
+KPX aring.sc obreve.sc -30
+KPX aring.sc gdotaccent.sc -35
+KPX aring.sc gcommaaccent.sc -35
+KPX aring.sc gcircumflex.sc -35
+KPX aring.sc gbreve.sc -35
+KPX aring.sc cdotaccent.sc -35
+KPX aring.sc ccircumflex.sc -35
+KPX aring.sc ccaron.sc -35
+KPX aring.sc cacute.sc -35
+KPX aring.sc oogonek.sc -30
+KPX aring.sc gcaron.sc -35
+KPX aring.sc gacute.sc -35
+KPX aring.sc quotedblright -85
+KPX aring.sc quoteright -80
+KPX aring.sc period 10
+KPX aring.sc hyphen -10
+KPX ccedilla.sc oslash.sc -10
+KPX ccedilla.sc odieresis.sc -10
+KPX ccedilla.sc aring.sc 5
+KPX ccedilla.sc adieresis.sc 5
+KPX ccedilla.sc o.sc -10
+KPX ccedilla.sc k.sc 5
+KPX ccedilla.sc h.sc 10
+KPX ccedilla.sc a.sc 5
+KPX ccedilla.sc omacron.sc -10
+KPX ccedilla.sc ohungarumlaut.sc -10
+KPX ccedilla.sc obreve.sc -10
+KPX ccedilla.sc kcommaaccent.sc 5
+KPX ccedilla.sc hcircumflex.sc 10
+KPX ccedilla.sc aogonek.sc 5
+KPX ccedilla.sc amacron.sc 5
+KPX ccedilla.sc oogonek.sc -10
+KPX ntilde.sc oslash.sc -15
+KPX ntilde.sc odieresis.sc -15
+KPX ntilde.sc ccedilla.sc -15
+KPX ntilde.sc ae.sc -15
+KPX ntilde.sc aring.sc -15
+KPX ntilde.sc adieresis.sc -15
+KPX ntilde.sc o.sc -15
+KPX ntilde.sc g.sc -15
+KPX ntilde.sc c.sc -15
+KPX ntilde.sc a.sc -15
+KPX ntilde.sc omacron.sc -15
+KPX ntilde.sc ohungarumlaut.sc -15
+KPX ntilde.sc obreve.sc -15
+KPX ntilde.sc gdotaccent.sc -15
+KPX ntilde.sc gcommaaccent.sc -15
+KPX ntilde.sc gcircumflex.sc -15
+KPX ntilde.sc gbreve.sc -15
+KPX ntilde.sc cdotaccent.sc -15
+KPX ntilde.sc ccircumflex.sc -15
+KPX ntilde.sc ccaron.sc -15
+KPX ntilde.sc cacute.sc -15
+KPX ntilde.sc aeacute.sc -15
+KPX ntilde.sc aogonek.sc -15
+KPX ntilde.sc amacron.sc -15
+KPX ntilde.sc oogonek.sc -15
+KPX ntilde.sc gcaron.sc -15
+KPX ntilde.sc gacute.sc -15
+KPX ntilde.sc comma -10
+KPX ograve.sc a.sc -35
+KPX oacute.sc a.sc -35
+KPX odieresis.sc ydieresis.sc -25
+KPX odieresis.sc ae.sc -35
+KPX odieresis.sc aring.sc -35
+KPX odieresis.sc adieresis.sc -35
+KPX odieresis.sc y.sc -25
+KPX odieresis.sc x.sc -25
+KPX odieresis.sc w.sc -20
+KPX odieresis.sc v.sc -35
+KPX odieresis.sc a.sc -35
+KPX odieresis.sc ycircumflex.sc -25
+KPX odieresis.sc wgrave.sc -20
+KPX odieresis.sc wdieresis.sc -20
+KPX odieresis.sc wcircumflex.sc -20
+KPX odieresis.sc wacute.sc -20
+KPX odieresis.sc aeacute.sc -35
+KPX odieresis.sc aogonek.sc -35
+KPX odieresis.sc amacron.sc -35
+KPX oslash.sc ydieresis.sc -25
+KPX oslash.sc ae.sc -35
+KPX oslash.sc aring.sc -35
+KPX oslash.sc adieresis.sc -35
+KPX oslash.sc y.sc -25
+KPX oslash.sc x.sc -25
+KPX oslash.sc w.sc -20
+KPX oslash.sc v.sc -35
+KPX oslash.sc a.sc -35
+KPX oslash.sc ycircumflex.sc -25
+KPX oslash.sc wgrave.sc -20
+KPX oslash.sc wdieresis.sc -20
+KPX oslash.sc wcircumflex.sc -20
+KPX oslash.sc wacute.sc -20
+KPX oslash.sc aeacute.sc -35
+KPX oslash.sc aogonek.sc -35
+KPX oslash.sc amacron.sc -35
+KPX ugrave.sc a.sc -35
+KPX uacute.sc a.sc -35
+KPX ucircumflex.sc ae.sc -35
+KPX ucircumflex.sc aring.sc -35
+KPX ucircumflex.sc adieresis.sc -35
+KPX ucircumflex.sc a.sc -35
+KPX ucircumflex.sc aeacute.sc -35
+KPX ucircumflex.sc aogonek.sc -35
+KPX ucircumflex.sc amacron.sc -35
+KPX ucircumflex.sc period -15
+KPX ucircumflex.sc comma -25
+KPX udieresis.sc ae.sc -35
+KPX udieresis.sc aring.sc -35
+KPX udieresis.sc adieresis.sc -35
+KPX udieresis.sc a.sc -35
+KPX udieresis.sc aeacute.sc -35
+KPX udieresis.sc aogonek.sc -35
+KPX udieresis.sc amacron.sc -35
+KPX udieresis.sc period -15
+KPX udieresis.sc comma -25
+KPX yacute.sc t.sc 25
+KPX yacute.sc c.sc -30
+KPX ydieresis.sc oslash.sc -30
+KPX ydieresis.sc odieresis.sc -30
+KPX ydieresis.sc ccedilla.sc -30
+KPX ydieresis.sc ae.sc -25
+KPX ydieresis.sc aring.sc -25
+KPX ydieresis.sc adieresis.sc -25
+KPX ydieresis.sc t.sc 25
+KPX ydieresis.sc s.sc -15
+KPX ydieresis.sc o.sc -30
+KPX ydieresis.sc g.sc -30
+KPX ydieresis.sc c.sc -30
+KPX ydieresis.sc a.sc -25
+KPX ydieresis.sc uni021B.sc 25
+KPX ydieresis.sc tcaron.sc 25
+KPX ydieresis.sc uni0219.sc -15
+KPX ydieresis.sc scircumflex.sc -15
+KPX ydieresis.sc scedilla.sc -15
+KPX ydieresis.sc sacute.sc -15
+KPX ydieresis.sc omacron.sc -30
+KPX ydieresis.sc ohungarumlaut.sc -30
+KPX ydieresis.sc obreve.sc -30
+KPX ydieresis.sc gdotaccent.sc -30
+KPX ydieresis.sc gcommaaccent.sc -30
+KPX ydieresis.sc gcircumflex.sc -30
+KPX ydieresis.sc gbreve.sc -30
+KPX ydieresis.sc cdotaccent.sc -30
+KPX ydieresis.sc ccircumflex.sc -30
+KPX ydieresis.sc ccaron.sc -30
+KPX ydieresis.sc cacute.sc -30
+KPX ydieresis.sc aeacute.sc -25
+KPX ydieresis.sc aogonek.sc -25
+KPX ydieresis.sc amacron.sc -25
+KPX ydieresis.sc scaron.sc -15
+KPX ydieresis.sc oogonek.sc -30
+KPX ydieresis.sc gcaron.sc -30
+KPX ydieresis.sc gacute.sc -30
+KPX ydieresis.sc semicolon -60
+KPX ydieresis.sc colon -55
+KPX ydieresis.sc period -50
+KPX ydieresis.sc hyphen -45
+KPX ydieresis.sc comma -55
+KPX ff jacute 10
+KPX ff quoteright 20
+KPX ff ohorndotbelow -5
+KPX ff ohorntilde -5
+KPX ff ohornhookabove -5
+KPX ff ohorngrave -5
+KPX ff ohornacute -5
+KPX ff ocircumflexdotbelow -5
+KPX ff ohookabove -5
+KPX ff ihookabove 10
+KPX ff ecircumflexdotbelow -10
+KPX ff etilde -10
+KPX ff ehookabove -10
+KPX ff abrevedotbelow -10
+KPX ff acircumflexdotbelow -10
+KPX ff ahookabove -10
+KPX ff uni021B 15
+KPX ff aeacute -15
+KPX ff oogonek -10
+KPX ff tcaron 10
+KPX ff oe -15
+KPX ff ohungarumlaut -5
+KPX ff obreve -5
+KPX ff omacron -5
+KPX ff lslash 25
+KPX ff lcaron 15
+KPX ff lcommaaccent 25
+KPX ff lacute 20
+KPX ff jcircumflex 10
+KPX ff iogonek 15
+KPX ff ibreve 10
+KPX ff imacron 10
+KPX ff itilde 10
+KPX ff ecaron -10
+KPX ff eogonek -15
+KPX ff edotaccent -10
+KPX ff ebreve -10
+KPX ff emacron -10
+KPX ff aogonek -15
+KPX ff abreve -10
+KPX ff amacron -10
+KPX ff oslash -10
+KPX ff odieresis -5
+KPX ff otilde -5
+KPX ff ocircumflex -5
+KPX ff oacute -10
+KPX ff ograve -5
+KPX ff idieresis 10
+KPX ff icircumflex 10
+KPX ff iacute 10
+KPX ff igrave 10
+KPX ff edieresis -10
+KPX ff ecircumflex -10
+KPX ff eacute -10
+KPX ff egrave -10
+KPX ff ae -15
+KPX ff aring -10
+KPX ff adieresis -10
+KPX ff atilde -10
+KPX ff acircumflex -10
+KPX ff aacute -10
+KPX ff agrave -10
+KPX ff t 15
+KPX ff o -10
+KPX ff l 25
+KPX ff j 15
+KPX ff i 15
+KPX ff e -15
+KPX ff a -15
+KPX fi T_h -15
+KPX fi jacute -30
+KPX fi uni021A -15
+KPX fi Tcaron -15
+KPX fi jcircumflex -30
+KPX fi j -30
+KPX fi T -15
+KPX fl ycircumflex -20
+KPX fl ydieresis -20
+KPX fl yacute -20
+KPX fl y -20
+KPX fl v -20
+KPX ffi T_h -15
+KPX ffi jacute -30
+KPX ffi uni021A -15
+KPX ffi Tcaron -15
+KPX ffi jcircumflex -30
+KPX ffi j -30
+KPX ffi T -15
+KPX ffl ycircumflex -20
+KPX ffl ydieresis -20
+KPX ffl yacute -20
+KPX ffl y -20
+KPX ffl v -20
+KPX T_h ycircumflex -25
+KPX T_h ydieresis -25
+KPX T_h y -25
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/fonts/newpx/afm/zplrsl.afm b/fonts/newpx/afm/zplrsl.afm
new file mode 100644
index 0000000000..e95baed30a
--- /dev/null
+++ b/fonts/newpx/afm/zplrsl.afm
@@ -0,0 +1,13644 @@
+StartFontMetrics 2.0
+Comment Generated by FontForge 20200314
+Comment Creation Date: Thu May 20 11:44:12 2021
+FontName TeXGyrePagellaX-Slanted
+FullName TeXGyrePagellaX-RSlanted
+FamilyName TeXGyrePagellaX
+Weight Regular
+Notice (Copyright 2006, 2009 for TeX Gyre extensions by B. Jackowski and J.M. Nowacki (on behalf of TeX users groups). This work is released under the GUST Font License -- see http://tug.org/fonts/licenses/G)
+Comment UST-FONT-LICENSE.txt for details.
+Comment
+Comment Copyright (c) 2013--2021 Michael Sharpe for added superior figures, letters and symbols.
+ItalicAngle -10
+IsFixedPitch false
+UnderlinePosition -50
+UnderlineThickness 50
+Version 2.004
+EncodingScheme FontSpecific
+FontBBox -435 -283 1315 1098
+CapHeight 700
+XHeight 449
+Ascender 667
+Descender -250
+StartCharMetrics 1185
+C -1 ; WX 280 ; N .notdef ; B 0 0 0 0 ;
+C -1 ; WX 250 ; N space ; B 0 0 0 0 ;
+C -1 ; WX 278 ; N exclam ; B 89 -5 316 694 ;
+C -1 ; WX 371 ; N quotedbl ; B 168 469 437 709 ;
+C -1 ; WX 500 ; N numbersign ; B 43 0 579 684 ;
+C -1 ; WX 500 ; N dollar ; B 34 -116 536 731 ;
+C -1 ; WX 840 ; N percent ; B 128 -20 834 709 ;
+C -1 ; WX 778 ; N ampersand ; B 69 -20 811 689 ;
+C -1 ; WX 208 ; N quotesingle ; B 177 469 265 709 ;
+C -1 ; WX 333 ; N parenleft ; B 96 -215 424 726 ;
+C -1 ; WX 333 ; N parenright ; B -2 -215 331 726 ;
+C -1 ; WX 389 ; N asterisk ; B 112 342 456 689 ;
+C -1 ; WX 606 ; N plus ; B 79 -13 615 513 ;
+C -1 ; WX 250 ; N comma ; B -9 -155 237 123 ;
+C -1 ; WX 333 ; N hyphen ; B 56 215 362 287 ;
+C -1 ; WX 250 ; N period ; B 75 -5 193 111 ;
+C -1 ; WX 606 ; N slash ; B 66 -119 647 726 ;
+C -1 ; WX 500 ; N zero ; B 72 -20 544 689 ;
+C -1 ; WX 500 ; N one ; B 95 -3 423 694 ;
+C -1 ; WX 500 ; N two ; B 15 -3 524 689 ;
+C -1 ; WX 500 ; N three ; B 42 -20 516 689 ;
+C -1 ; WX 500 ; N four ; B 38 -3 516 694 ;
+C -1 ; WX 500 ; N five ; B 37 -20 558 689 ;
+C -1 ; WX 500 ; N six ; B 68 -20 534 689 ;
+C -1 ; WX 500 ; N seven ; B 58 -3 618 689 ;
+C -1 ; WX 500 ; N eight ; B 55 -20 535 689 ;
+C -1 ; WX 500 ; N nine ; B 61 -20 539 689 ;
+C -1 ; WX 250 ; N colon ; B 74 -5 253 456 ;
+C -1 ; WX 250 ; N semicolon ; B -9 -153 280 456 ;
+C -1 ; WX 606 ; N less ; B 108 20 611 480 ;
+C -1 ; WX 606 ; N equal ; B 64 136 630 365 ;
+C -1 ; WX 606 ; N greater ; B 73 20 575 480 ;
+C -1 ; WX 444 ; N question ; B 139 -5 493 694 ;
+C -1 ; WX 747 ; N at ; B 76 -20 800 694 ;
+C -1 ; WX 778 ; N A ; B 14 -3 761 700 ;
+C -1 ; WX 611 ; N B ; B 64 -3 643 692 ;
+C -1 ; WX 709 ; N C ; B 75 -20 782 709 ;
+C -1 ; WX 774 ; N D ; B 56 -3 825 692 ;
+C -1 ; WX 611 ; N E ; B 33 -3 677 692 ;
+C -1 ; WX 556 ; N F ; B 21 -3 657 692 ;
+C -1 ; WX 763 ; N G ; B 75 -20 810 709 ;
+C -1 ; WX 832 ; N H ; B 21 -3 932 692 ;
+C -1 ; WX 337 ; N I ; B 21 -3 437 692 ; L J IJ ;
+C -1 ; WX 333 ; N J ; B -44 -195 433 692 ;
+C -1 ; WX 726 ; N K ; B 21 -3 814 692 ;
+C -1 ; WX 611 ; N L ; B 64 -3 616 692 ;
+C -1 ; WX 946 ; N M ; B 15 -13 1042 692 ;
+C -1 ; WX 831 ; N N ; B 16 -20 935 692 ;
+C -1 ; WX 786 ; N O ; B 75 -20 836 709 ;
+C -1 ; WX 604 ; N P ; B 21 -3 678 692 ;
+C -1 ; WX 786 ; N Q ; B 74 -176 836 709 ;
+C -1 ; WX 668 ; N R ; B 21 -3 675 692 ;
+C -1 ; WX 525 ; N S ; B 33 -20 579 709 ;
+C -1 ; WX 613 ; N T ; B 119 -3 717 692 ;
+C -1 ; WX 778 ; N U ; B 129 -20 881 692 ;
+C -1 ; WX 722 ; N V ; B 125 -9 828 692 ;
+C -1 ; WX 1000 ; N W ; B 125 -9 1106 700 ;
+C -1 ; WX 667 ; N X ; B 13 -3 760 700 ;
+C -1 ; WX 667 ; N Y ; B 124 -3 776 705 ;
+C -1 ; WX 667 ; N Z ; B 14 -3 755 692 ;
+C -1 ; WX 333 ; N bracketleft ; B 49 -184 415 726 ;
+C -1 ; WX 606 ; N backslash ; B 209 0 512 726 ;
+C -1 ; WX 333 ; N bracketright ; B 14 -184 380 726 ;
+C -1 ; WX 606 ; N asciicircum ; B 101 283 604 689 ;
+C -1 ; WX 500 ; N underscore ; B -22 -125 487 -75 ;
+C -1 ; WX 333 ; N grave ; B 143 506 344 677 ;
+C -1 ; WX 500 ; N a ; B 49 -12 476 469 ;
+C -1 ; WX 553 ; N b ; B 57 -12 560 726 ;
+C -1 ; WX 444 ; N c ; B 58 -20 490 469 ;
+C -1 ; WX 611 ; N d ; B 67 -12 623 726 ;
+C -1 ; WX 479 ; N e ; B 59 -20 501 469 ;
+C -1 ; WX 333 ; N f ; B 22 -3 467 728 ; L l fl ; L i fi ; L f ff ; L k f_k ;
+C -1 ; WX 556 ; N g ; B 6 -283 618 469 ;
+C -1 ; WX 582 ; N h ; B 5 -3 577 726 ;
+C -1 ; WX 291 ; N i ; B 20 -3 309 687 ; L j ij ;
+C -1 ; WX 234 ; N j ; B -83 -283 280 687 ;
+C -1 ; WX 556 ; N k ; B 20 -12 592 726 ;
+C -1 ; WX 291 ; N l ; B 20 -3 315 726 ;
+C -1 ; WX 883 ; N m ; B 15 -3 874 469 ;
+C -1 ; WX 582 ; N n ; B 5 -3 577 469 ;
+C -1 ; WX 546 ; N o ; B 65 -20 561 469 ;
+C -1 ; WX 601 ; N p ; B -42 -281 606 469 ;
+C -1 ; WX 560 ; N q ; B 66 -281 580 469 ;
+C -1 ; WX 395 ; N r ; B 20 -3 455 469 ;
+C -1 ; WX 424 ; N s ; B 31 -20 432 469 ;
+C -1 ; WX 326 ; N t ; B 89 -12 396 621 ;
+C -1 ; WX 603 ; N u ; B 89 -12 586 469 ;
+C -1 ; WX 565 ; N v ; B 82 -7 620 459 ;
+C -1 ; WX 834 ; N w ; B 82 -7 889 469 ;
+C -1 ; WX 516 ; N x ; B 20 -3 559 469 ;
+C -1 ; WX 556 ; N y ; B -20 -283 625 459 ;
+C -1 ; WX 500 ; N z ; B 19 -3 536 462 ;
+C -1 ; WX 333 ; N braceleft ; B 106 -175 417 726 ;
+C -1 ; WX 606 ; N bar ; B 243 -184 459 726 ;
+C -1 ; WX 333 ; N braceright ; B 13 -175 323 726 ;
+C -1 ; WX 606 ; N asciitilde ; B 88 182 610 341 ;
+C -1 ; WX 333 ; N uni00A0 ; B 0 0 0 0 ;
+C -1 ; WX 278 ; N exclamdown ; B 41 -245 268 454 ;
+C -1 ; WX 500 ; N cent ; B 94 -101 523 562 ;
+C -1 ; WX 500 ; N sterling ; B 10 -13 596 694 ;
+C -1 ; WX 500 ; N currency ; B 55 96 555 531 ;
+C -1 ; WX 500 ; N yen ; B 108 -3 618 701 ;
+C -1 ; WX 606 ; N brokenbar ; B 243 -184 459 726 ;
+C -1 ; WX 500 ; N section ; B 13 -219 535 709 ;
+C -1 ; WX 333 ; N dieresis ; B 120 542 421 642 ;
+C -1 ; WX 747 ; N copyright ; B 82 -19 781 668 ;
+C -1 ; WX 333 ; N ordfeminine ; B 88 361 388 709 ;
+C -1 ; WX 500 ; N guillemotleft ; B 93 71 523 428 ;
+C -1 ; WX 606 ; N logicalnot ; B 94 164 630 365 ;
+C -1 ; WX 333 ; N uni00AD ; B 56 215 362 287 ;
+C -1 ; WX 747 ; N registered ; B 82 -19 781 668 ;
+C -1 ; WX 333 ; N macron ; B 111 566 432 619 ;
+C -1 ; WX 400 ; N degree ; B 142 389 448 689 ;
+C -1 ; WX 606 ; N plusminus ; B 40 0 625 569 ;
+C -1 ; WX 300 ; N two.superior ; B 54 271 366 686 ;
+C -1 ; WX 300 ; N three.superior ; B 70 261 361 686 ;
+C -1 ; WX 333 ; N acute ; B 167 506 416 677 ;
+C -1 ; WX 603 ; N uni00B5 ; B 57 -236 586 469 ;
+C -1 ; WX 628 ; N paragraph ; B 132 -150 711 695 ;
+C -1 ; WX 250 ; N periodcentered ; B 110 192 228 308 ;
+C -1 ; WX 333 ; N cedilla ; B 59 -225 281 10 ;
+C -1 ; WX 300 ; N one.superior ; B 102 271 306 689 ;
+C -1 ; WX 333 ; N ordmasculine ; B 73 355 426 709 ;
+C -1 ; WX 500 ; N guillemotright ; B 65 71 495 428 ;
+C -1 ; WX 750 ; N onequarter ; B 98 -3 780 692 ;
+C -1 ; WX 750 ; N onehalf ; B 83 -3 765 692 ;
+C -1 ; WX 750 ; N threequarters ; B 81 -3 789 689 ;
+C -1 ; WX 444 ; N questiondown ; B 30 -245 384 454 ;
+C -1 ; WX 778 ; N Agrave ; B 14 -3 761 888 ;
+C -1 ; WX 778 ; N Aacute ; B 14 -3 761 888 ;
+C -1 ; WX 778 ; N Acircumflex ; B 14 -3 761 887 ;
+C -1 ; WX 778 ; N Atilde ; B 14 -3 761 872 ;
+C -1 ; WX 778 ; N Adieresis ; B 14 -3 761 869 ;
+C -1 ; WX 778 ; N Aring ; B 14 -3 761 939 ;
+C -1 ; WX 944 ; N AE ; B -11 -3 1013 692 ;
+C -1 ; WX 709 ; N Ccedilla ; B 75 -225 782 709 ;
+C -1 ; WX 611 ; N Egrave ; B 33 -3 677 888 ;
+C -1 ; WX 611 ; N Eacute ; B 33 -3 677 888 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 33 -3 677 887 ;
+C -1 ; WX 611 ; N Edieresis ; B 33 -3 677 869 ;
+C -1 ; WX 337 ; N Igrave ; B 21 -3 437 888 ;
+C -1 ; WX 337 ; N Iacute ; B 21 -3 459 888 ;
+C -1 ; WX 337 ; N Icircumflex ; B 21 -3 470 887 ;
+C -1 ; WX 337 ; N Idieresis ; B 21 -3 464 869 ;
+C -1 ; WX 774 ; N Eth ; B 56 -3 825 692 ;
+C -1 ; WX 831 ; N Ntilde ; B 16 -20 935 872 ;
+C -1 ; WX 786 ; N Ograve ; B 75 -20 836 888 ;
+C -1 ; WX 786 ; N Oacute ; B 75 -20 836 888 ;
+C -1 ; WX 786 ; N Ocircumflex ; B 75 -20 836 887 ;
+C -1 ; WX 786 ; N Otilde ; B 75 -20 836 872 ;
+C -1 ; WX 786 ; N Odieresis ; B 75 -20 836 869 ;
+C -1 ; WX 606 ; N multiply ; B 112 44 582 456 ;
+C -1 ; WX 833 ; N Oslash ; B 32 -20 917 709 ;
+C -1 ; WX 778 ; N Ugrave ; B 129 -20 881 888 ;
+C -1 ; WX 778 ; N Uacute ; B 129 -20 881 888 ;
+C -1 ; WX 778 ; N Ucircumflex ; B 129 -20 881 887 ;
+C -1 ; WX 778 ; N Udieresis ; B 129 -20 881 869 ;
+C -1 ; WX 667 ; N Yacute ; B 124 -3 776 888 ;
+C -1 ; WX 604 ; N Thorn ; B 31 -3 645 692 ;
+C -1 ; WX 556 ; N germandbls ; B 22 -9 603 731 ;
+C -1 ; WX 500 ; N agrave ; B 49 -12 476 677 ;
+C -1 ; WX 500 ; N aacute ; B 49 -12 495 677 ;
+C -1 ; WX 500 ; N acircumflex ; B 49 -12 492 676 ;
+C -1 ; WX 500 ; N atilde ; B 49 -12 525 645 ;
+C -1 ; WX 500 ; N adieresis ; B 49 -12 500 642 ;
+C -1 ; WX 500 ; N aring ; B 49 -12 476 692 ;
+C -1 ; WX 758 ; N ae ; B 46 -20 785 469 ;
+C -1 ; WX 444 ; N ccedilla ; B 58 -225 490 469 ;
+C -1 ; WX 479 ; N egrave ; B 59 -20 501 677 ;
+C -1 ; WX 479 ; N eacute ; B 59 -20 511 677 ;
+C -1 ; WX 479 ; N ecircumflex ; B 59 -20 508 676 ;
+C -1 ; WX 479 ; N edieresis ; B 59 -20 516 642 ;
+C -1 ; WX 287 ; N igrave ; B 20 -3 324 677 ;
+C -1 ; WX 287 ; N iacute ; B 20 -3 395 677 ;
+C -1 ; WX 287 ; N icircumflex ; B 20 -3 392 676 ;
+C -1 ; WX 287 ; N idieresis ; B 20 -3 400 642 ;
+C -1 ; WX 546 ; N eth ; B 65 -20 586 728 ;
+C -1 ; WX 582 ; N ntilde ; B 5 -3 577 645 ;
+C -1 ; WX 546 ; N ograve ; B 65 -20 561 677 ;
+C -1 ; WX 546 ; N oacute ; B 65 -20 561 677 ;
+C -1 ; WX 546 ; N ocircumflex ; B 65 -20 561 676 ;
+C -1 ; WX 546 ; N otilde ; B 65 -20 561 645 ;
+C -1 ; WX 546 ; N odieresis ; B 65 -20 561 642 ;
+C -1 ; WX 606 ; N divide ; B 79 19 615 481 ;
+C -1 ; WX 556 ; N oslash ; B 16 -23 609 474 ;
+C -1 ; WX 603 ; N ugrave ; B 89 -12 586 677 ;
+C -1 ; WX 603 ; N uacute ; B 89 -12 586 677 ;
+C -1 ; WX 603 ; N ucircumflex ; B 89 -12 586 676 ;
+C -1 ; WX 603 ; N udieresis ; B 89 -12 586 642 ;
+C -1 ; WX 556 ; N yacute ; B -20 -283 625 677 ;
+C -1 ; WX 601 ; N thorn ; B -52 -281 595 726 ;
+C -1 ; WX 556 ; N ydieresis ; B -20 -283 625 642 ;
+C -1 ; WX 778 ; N Amacron ; B 14 -3 761 846 ;
+C -1 ; WX 500 ; N amacron ; B 49 -12 511 619 ;
+C -1 ; WX 778 ; N Abreve ; B 14 -3 761 884 ;
+C -1 ; WX 500 ; N abreve ; B 49 -12 505 671 ;
+C -1 ; WX 778 ; N Aogonek ; B 14 -250 761 700 ;
+C -1 ; WX 500 ; N aogonek ; B 49 -250 476 469 ;
+C -1 ; WX 709 ; N Cacute ; B 75 -20 782 888 ;
+C -1 ; WX 444 ; N cacute ; B 58 -20 503 677 ;
+C -1 ; WX 709 ; N Ccircumflex ; B 75 -20 782 887 ;
+C -1 ; WX 444 ; N ccircumflex ; B 58 -20 500 676 ;
+C -1 ; WX 709 ; N Cdotaccent ; B 75 -20 782 869 ;
+C -1 ; WX 444 ; N cdotaccent ; B 58 -20 490 642 ;
+C -1 ; WX 709 ; N Ccaron ; B 75 -20 782 887 ;
+C -1 ; WX 444 ; N ccaron ; B 58 -20 529 676 ;
+C -1 ; WX 774 ; N Dcaron ; B 56 -3 825 887 ;
+C -1 ; WX 611 ; N dcaron ; B 67 -12 804 726 ;
+C -1 ; WX 774 ; N Dcroat ; B 56 -3 825 692 ;
+C -1 ; WX 611 ; N dcroat ; B 67 -12 683 726 ;
+C -1 ; WX 611 ; N Emacron ; B 33 -3 677 846 ;
+C -1 ; WX 479 ; N emacron ; B 59 -20 527 619 ;
+C -1 ; WX 611 ; N Ebreve ; B 33 -3 677 884 ;
+C -1 ; WX 479 ; N ebreve ; B 59 -20 521 671 ;
+C -1 ; WX 611 ; N Edotaccent ; B 33 -3 677 869 ;
+C -1 ; WX 479 ; N edotaccent ; B 59 -20 501 642 ;
+C -1 ; WX 611 ; N Eogonek ; B 33 -250 677 692 ;
+C -1 ; WX 479 ; N eogonek ; B 59 -250 501 469 ;
+C -1 ; WX 611 ; N Ecaron ; B 33 -3 677 887 ;
+C -1 ; WX 479 ; N ecaron ; B 59 -20 537 676 ;
+C -1 ; WX 763 ; N Gcircumflex ; B 75 -20 810 887 ;
+C -1 ; WX 556 ; N gcircumflex ; B 6 -283 618 676 ;
+C -1 ; WX 763 ; N Gbreve ; B 75 -20 810 884 ;
+C -1 ; WX 556 ; N gbreve ; B 6 -283 618 671 ;
+C -1 ; WX 763 ; N Gdotaccent ; B 75 -20 810 869 ;
+C -1 ; WX 556 ; N gdotaccent ; B 6 -283 618 642 ;
+C -1 ; WX 763 ; N Gcommaaccent ; B 75 -271 810 709 ;
+C -1 ; WX 556 ; N gcommaaccent ; B 6 -283 618 709 ;
+C -1 ; WX 832 ; N Hcircumflex ; B 21 -3 932 887 ;
+C -1 ; WX 582 ; N hcircumflex ; B 5 -3 598 921 ;
+C -1 ; WX 832 ; N Hbar ; B 21 -3 932 692 ;
+C -1 ; WX 646 ; N hbar ; B 39 -3 611 726 ;
+C -1 ; WX 337 ; N Itilde ; B 21 -3 489 872 ;
+C -1 ; WX 287 ; N itilde ; B 20 -3 425 645 ;
+C -1 ; WX 337 ; N Imacron ; B 21 -3 475 846 ;
+C -1 ; WX 287 ; N imacron ; B 20 -3 411 619 ;
+C -1 ; WX 337 ; N Ibreve ; B 21 -3 477 884 ;
+C -1 ; WX 287 ; N ibreve ; B 20 -3 405 671 ;
+C -1 ; WX 337 ; N Iogonek ; B 21 -250 437 692 ;
+C -1 ; WX 291 ; N iogonek ; B 15 -250 288 687 ;
+C -1 ; WX 337 ; N Idotaccent ; B 21 -3 437 869 ;
+C -1 ; WX 287 ; N dotlessi ; B 20 -3 276 469 ;
+C -1 ; WX 724 ; N IJ ; B 39 -195 806 692 ;
+C -1 ; WX 525 ; N ij ; B 20 -283 571 687 ;
+C -1 ; WX 333 ; N Jcircumflex ; B -44 -195 466 887 ;
+C -1 ; WX 234 ; N jcircumflex ; B -83 -283 363 676 ;
+C -1 ; WX 726 ; N Kcommaaccent ; B 21 -271 814 692 ;
+C -1 ; WX 556 ; N kcommaaccent ; B 20 -271 592 726 ;
+C -1 ; WX 611 ; N Lacute ; B 64 -3 616 888 ;
+C -1 ; WX 291 ; N lacute ; B 20 -3 429 922 ;
+C -1 ; WX 611 ; N Lcommaaccent ; B 64 -271 616 692 ;
+C -1 ; WX 291 ; N lcommaaccent ; B 3 -271 315 726 ;
+C -1 ; WX 611 ; N Lcaron ; B 64 -3 617 692 ;
+C -1 ; WX 291 ; N lcaron ; B 20 -3 496 726 ;
+C -1 ; WX 611 ; N Ldot ; B 64 -3 616 692 ;
+C -1 ; WX 291 ; N ldot ; B 20 -3 411 726 ;
+C -1 ; WX 611 ; N Lslash ; B 64 -3 616 692 ;
+C -1 ; WX 291 ; N lslash ; B 20 -3 388 726 ;
+C -1 ; WX 831 ; N Nacute ; B 16 -20 935 888 ;
+C -1 ; WX 582 ; N nacute ; B 5 -3 577 677 ;
+C -1 ; WX 831 ; N Ncommaaccent ; B 16 -271 935 692 ;
+C -1 ; WX 582 ; N ncommaaccent ; B 5 -271 577 469 ;
+C -1 ; WX 831 ; N Ncaron ; B 16 -20 935 887 ;
+C -1 ; WX 582 ; N ncaron ; B 5 -3 577 676 ;
+C -1 ; WX 831 ; N Eng ; B 16 -187 935 692 ;
+C -1 ; WX 582 ; N eng ; B 5 -167 552 469 ;
+C -1 ; WX 786 ; N Omacron ; B 75 -20 836 846 ;
+C -1 ; WX 546 ; N omacron ; B 65 -20 561 619 ;
+C -1 ; WX 786 ; N Obreve ; B 75 -20 836 884 ;
+C -1 ; WX 546 ; N obreve ; B 65 -20 561 671 ;
+C -1 ; WX 786 ; N Ohungarumlaut ; B 75 -20 836 888 ;
+C -1 ; WX 546 ; N ohungarumlaut ; B 65 -20 642 683 ;
+C -1 ; WX 998 ; N OE ; B 75 -20 1067 709 ;
+C -1 ; WX 827 ; N oe ; B 67 -20 853 469 ;
+C -1 ; WX 668 ; N Racute ; B 21 -3 675 888 ;
+C -1 ; WX 395 ; N racute ; B 20 -3 455 677 ;
+C -1 ; WX 668 ; N Rcommaaccent ; B 21 -271 675 692 ;
+C -1 ; WX 395 ; N rcommaaccent ; B 11 -271 455 469 ;
+C -1 ; WX 668 ; N Rcaron ; B 21 -3 675 887 ;
+C -1 ; WX 395 ; N rcaron ; B 20 -3 463 676 ;
+C -1 ; WX 525 ; N Sacute ; B 33 -20 579 888 ;
+C -1 ; WX 424 ; N sacute ; B 31 -20 445 677 ;
+C -1 ; WX 525 ; N Scircumflex ; B 33 -20 579 887 ;
+C -1 ; WX 424 ; N scircumflex ; B 31 -20 442 676 ;
+C -1 ; WX 525 ; N Scedilla ; B 33 -225 579 709 ;
+C -1 ; WX 424 ; N scedilla ; B 31 -225 432 469 ;
+C -1 ; WX 525 ; N Scaron ; B 33 -20 579 887 ;
+C -1 ; WX 424 ; N scaron ; B 31 -20 471 676 ;
+C -1 ; WX 613 ; N Tcedilla ; B 119 -225 717 692 ;
+C -1 ; WX 326 ; N tcedilla ; B 67 -225 396 621 ;
+C -1 ; WX 613 ; N Tcaron ; B 119 -3 717 887 ;
+C -1 ; WX 326 ; N tcaron ; B 89 -12 470 663 ;
+C -1 ; WX 778 ; N Utilde ; B 129 -20 881 872 ;
+C -1 ; WX 603 ; N utilde ; B 89 -12 586 645 ;
+C -1 ; WX 778 ; N Umacron ; B 129 -20 881 846 ;
+C -1 ; WX 603 ; N umacron ; B 89 -12 586 619 ;
+C -1 ; WX 778 ; N Ubreve ; B 129 -20 881 884 ;
+C -1 ; WX 603 ; N ubreve ; B 89 -12 586 671 ;
+C -1 ; WX 778 ; N Uring ; B 129 -20 881 939 ;
+C -1 ; WX 603 ; N uring ; B 89 -12 586 692 ;
+C -1 ; WX 778 ; N Uhungarumlaut ; B 129 -20 881 888 ;
+C -1 ; WX 603 ; N uhungarumlaut ; B 89 -12 664 683 ;
+C -1 ; WX 778 ; N Uogonek ; B 129 -250 881 692 ;
+C -1 ; WX 603 ; N uogonek ; B 89 -250 586 469 ;
+C -1 ; WX 1000 ; N Wcircumflex ; B 125 -9 1106 887 ;
+C -1 ; WX 834 ; N wcircumflex ; B 82 -7 889 676 ;
+C -1 ; WX 667 ; N Ycircumflex ; B 124 -3 776 887 ;
+C -1 ; WX 556 ; N ycircumflex ; B -20 -283 625 676 ;
+C -1 ; WX 667 ; N Ydieresis ; B 124 -3 776 869 ;
+C -1 ; WX 667 ; N Zacute ; B 14 -3 755 888 ;
+C -1 ; WX 500 ; N zacute ; B 19 -3 536 677 ;
+C -1 ; WX 667 ; N Zdotaccent ; B 14 -3 755 869 ;
+C -1 ; WX 500 ; N zdotaccent ; B 19 -3 536 642 ;
+C -1 ; WX 667 ; N Zcaron ; B 14 -3 755 887 ;
+C -1 ; WX 500 ; N zcaron ; B 19 -3 536 676 ;
+C -1 ; WX 333 ; N longs ; B 22 -3 467 728 ;
+C -1 ; WX 611 ; N Ereversed ; B 38 -3 694 692 ;
+C -1 ; WX 500 ; N florin ; B -46 -262 597 706 ;
+C -1 ; WX 786 ; N Ohorn ; B 75 -20 893 781 ;
+C -1 ; WX 546 ; N ohorn ; B 65 -20 660 532 ;
+C -1 ; WX 778 ; N Uhorn ; B 129 -20 937 781 ;
+C -1 ; WX 640 ; N uhorn ; B 89 -12 733 532 ;
+C -1 ; WX 778 ; N Acaron ; B 14 -3 761 887 ;
+C -1 ; WX 500 ; N acaron ; B 49 -12 521 676 ;
+C -1 ; WX 337 ; N Icaron ; B 21 -3 493 887 ;
+C -1 ; WX 287 ; N icaron ; B 20 -3 421 676 ;
+C -1 ; WX 786 ; N Ocaron ; B 75 -20 836 887 ;
+C -1 ; WX 546 ; N ocaron ; B 65 -20 561 676 ;
+C -1 ; WX 778 ; N Ucaron ; B 129 -20 881 887 ;
+C -1 ; WX 603 ; N ucaron ; B 89 -12 586 676 ;
+C -1 ; WX 778 ; N Udieresisacute ; B 129 -20 881 1065 ;
+C -1 ; WX 603 ; N udieresisacute ; B 89 -12 586 833 ;
+C -1 ; WX 778 ; N Udieresiscaron ; B 129 -20 881 1064 ;
+C -1 ; WX 603 ; N udieresiscaron ; B 89 -12 616 832 ;
+C -1 ; WX 778 ; N Udieresisgrave ; B 129 -20 881 1065 ;
+C -1 ; WX 603 ; N udieresisgrave ; B 89 -12 586 833 ;
+C -1 ; WX 479 ; N eturned ; B 52 -20 495 469 ;
+C -1 ; WX 763 ; N Gcaron ; B 75 -20 810 887 ;
+C -1 ; WX 556 ; N gcaron ; B 6 -283 618 676 ;
+C -1 ; WX 786 ; N Oogonek ; B 75 -250 836 709 ;
+C -1 ; WX 546 ; N oogonek ; B 65 -250 561 469 ;
+C -1 ; WX 234 ; N jcaron ; B -83 -283 392 676 ;
+C -1 ; WX 763 ; N Gacute ; B 75 -20 810 888 ;
+C -1 ; WX 556 ; N gacute ; B 6 -283 618 677 ;
+C -1 ; WX 778 ; N Aringacute ; B 14 -3 761 1098 ;
+C -1 ; WX 500 ; N aringacute ; B 49 -12 531 855 ;
+C -1 ; WX 944 ; N AEacute ; B -11 -3 1013 888 ;
+C -1 ; WX 758 ; N aeacute ; B 46 -20 785 677 ;
+C -1 ; WX 833 ; N Oslashacute ; B 32 -20 917 888 ;
+C -1 ; WX 556 ; N oslashacute ; B 16 -23 609 677 ;
+C -1 ; WX 778 ; N Adblgrave ; B 14 -3 761 888 ;
+C -1 ; WX 500 ; N adblgrave ; B 49 -12 476 683 ;
+C -1 ; WX 611 ; N Edblgrave ; B 33 -3 677 888 ;
+C -1 ; WX 479 ; N edblgrave ; B 59 -20 501 683 ;
+C -1 ; WX 337 ; N Idblgrave ; B 21 -3 439 888 ;
+C -1 ; WX 287 ; N idblgrave ; B 13 -3 352 683 ;
+C -1 ; WX 786 ; N Odblgrave ; B 75 -20 836 888 ;
+C -1 ; WX 546 ; N odblgrave ; B 65 -20 561 683 ;
+C -1 ; WX 668 ; N Rdblgrave ; B 21 -3 675 888 ;
+C -1 ; WX 395 ; N rdblgrave ; B 20 -3 455 683 ;
+C -1 ; WX 778 ; N Udblgrave ; B 129 -20 881 888 ;
+C -1 ; WX 603 ; N udblgrave ; B 89 -12 586 683 ;
+C -1 ; WX 525 ; N uni0218 ; B 33 -271 579 709 ;
+C -1 ; WX 424 ; N uni0219 ; B 31 -271 432 469 ;
+C -1 ; WX 613 ; N uni021A ; B 119 -271 717 692 ;
+C -1 ; WX 326 ; N uni021B ; B 20 -271 396 621 ;
+C -1 ; WX 234 ; N uni0237 ; B -83 -283 241 469 ;
+C -1 ; WX 479 ; N ereversed ; B 49 -20 493 469 ;
+C -1 ; WX 479 ; N schwa ; B 52 -20 495 469 ;
+C -1 ; WX 354 ; N ringhalfright ; B 104 338 410 680 ;
+C -1 ; WX 354 ; N ringhalfleft ; B 124 338 429 680 ;
+C -1 ; WX 333 ; N circumflex ; B 101 509 413 676 ;
+C -1 ; WX 333 ; N caron ; B 130 509 442 676 ;
+C -1 ; WX 333 ; N breve ; B 141 513 426 671 ;
+C -1 ; WX 250 ; N dotaccent ; B 178 542 280 642 ;
+C -1 ; WX 333 ; N ring ; B 170 492 373 692 ;
+C -1 ; WX 313 ; N ogonek ; B 19 -250 241 15 ;
+C -1 ; WX 333 ; N tilde ; B 97 540 446 645 ;
+C -1 ; WX 380 ; N hungarumlaut ; B 162 502 553 683 ;
+C -1 ; WX 0 ; N uni0300 ; B -273 506 -72 677 ;
+C -1 ; WX 0 ; N uni0301 ; B -249 506 0 677 ;
+C -1 ; WX 0 ; N uni0302 ; B -315 509 -3 676 ;
+C -1 ; WX 0 ; N uni0303 ; B -319 540 30 645 ;
+C -1 ; WX 0 ; N uni0304 ; B -305 566 16 619 ;
+C -1 ; WX 0 ; N uni0306 ; B -275 513 10 671 ;
+C -1 ; WX 0 ; N uni0307 ; B -197 542 -95 642 ;
+C -1 ; WX 0 ; N uni0308 ; B -296 542 5 642 ;
+C -1 ; WX 0 ; N uni0309 ; B -145 522 32 703 ;
+C -1 ; WX 0 ; N uni030A ; B -246 492 -43 692 ;
+C -1 ; WX 0 ; N uni030B ; B -278 502 113 683 ;
+C -1 ; WX 0 ; N uni030C ; B -286 509 26 676 ;
+C -1 ; WX 0 ; N uni030F ; B -383 502 -44 683 ;
+C -1 ; WX 0 ; N uni0311 ; B -300 513 -14 671 ;
+C -1 ; WX 0 ; N uni0323 ; B -251 -193 -149 -93 ;
+C -1 ; WX 0 ; N uni0326 ; B -393 -271 -221 -77 ;
+C -1 ; WX 0 ; N uni032E ; B -404 -207 -97 -78 ;
+C -1 ; WX 0 ; N uni032F ; B -424 -207 -118 -78 ;
+C -1 ; WX 0 ; N uni0330 ; B -430 -195 -82 -90 ;
+C -1 ; WX 0 ; N uni0331 ; B -435 -169 -113 -116 ;
+C -1 ; WX 0 ; N uni0332 ; B -435 -169 -113 -116 ;
+C -1 ; WX 778 ; N Alpha ; B 14 -3 761 700 ;
+C -1 ; WX 611 ; N Beta ; B 64 -3 643 692 ;
+C -1 ; WX 556 ; N Gamma ; B 21 -3 657 692 ;
+C -1 ; WX 590 ; N Delta ; B 14 0 576 731 ;
+C -1 ; WX 611 ; N Epsilon ; B 33 -3 677 692 ;
+C -1 ; WX 667 ; N Zeta ; B 14 -3 755 692 ;
+C -1 ; WX 832 ; N Eta ; B 21 -3 932 692 ;
+C -1 ; WX 786 ; N Theta ; B 75 -20 836 709 ;
+C -1 ; WX 337 ; N Iota ; B 21 -3 437 692 ;
+C -1 ; WX 726 ; N Kappa ; B 21 -3 814 692 ;
+C -1 ; WX 778 ; N Lambda ; B 14 -3 761 700 ;
+C -1 ; WX 946 ; N Mu ; B 15 -13 1042 692 ;
+C -1 ; WX 831 ; N Nu ; B 16 -20 935 692 ;
+C -1 ; WX 688 ; N Xi ; B 64 -4 728 690 ;
+C -1 ; WX 786 ; N Omicron ; B 75 -20 836 709 ;
+C -1 ; WX 772 ; N Pi ; B 21 -3 872 692 ;
+C -1 ; WX 604 ; N Rho ; B 21 -3 678 692 ;
+C -1 ; WX 615 ; N Sigma ; B 0 -69 626 781 ;
+C -1 ; WX 613 ; N Tau ; B 119 -3 717 692 ;
+C -1 ; WX 740 ; N Upsilon ; B 101 -4 837 691 ;
+C -1 ; WX 658 ; N Phi ; B 98 -3 683 692 ;
+C -1 ; WX 667 ; N Chi ; B 13 -3 760 700 ;
+C -1 ; WX 697 ; N Psi ; B 135 -3 758 692 ;
+C -1 ; WX 765 ; N Omega ; B 47 0 784 731 ;
+C -1 ; WX 702 ; N alpha ; B 76 -20 686 469 ;
+C -1 ; WX 578 ; N beta ; B -44 -244 599 712 ;
+C -1 ; WX 612 ; N gamma ; B 84 -250 651 469 ;
+C -1 ; WX 554 ; N delta ; B 72 -20 578 712 ;
+C -1 ; WX 510 ; N epsilon ; B 63 -16 508 465 ;
+C -1 ; WX 482 ; N zeta ; B 68 -250 521 699 ;
+C -1 ; WX 582 ; N eta ; B 78 -200 552 469 ;
+C -1 ; WX 490 ; N theta ; B 87 -20 524 712 ;
+C -1 ; WX 341 ; N iota ; B 98 -20 321 449 ;
+C -1 ; WX 553 ; N kappa ; B 40 -20 543 469 ;
+C -1 ; WX 602 ; N lambda ; B 43 -14 582 706 ;
+C -1 ; WX 681 ; N mu ; B 36 -262 661 449 ;
+C -1 ; WX 588 ; N nu ; B 101 -22 605 488 ;
+C -1 ; WX 538 ; N xi ; B 58 -250 592 699 ;
+C -1 ; WX 546 ; N omicron ; B 65 -20 561 469 ;
+C -1 ; WX 681 ; N pi ; B 52 -27 711 470 ;
+C -1 ; WX 541 ; N rho ; B 18 -239 545 469 ;
+C -1 ; WX 452 ; N uni03C2 ; B 85 -142 487 469 ;
+C -1 ; WX 586 ; N sigma ; B 73 -20 633 524 ;
+C -1 ; WX 572 ; N tau ; B 99 -20 602 470 ;
+C -1 ; WX 605 ; N upsilon ; B 99 -20 619 482 ;
+C -1 ; WX 636 ; N phi ; B 76 -248 643 469 ;
+C -1 ; WX 556 ; N chi ; B 41 -244 593 463 ;
+C -1 ; WX 687 ; N psi ; B 99 -250 701 702 ;
+C -1 ; WX 664 ; N omega ; B 73 -20 667 460 ;
+C -1 ; WX 655 ; N uni03D1 ; B 99 -20 694 712 ;
+C -1 ; WX 562 ; N uni03D5 ; B 73 -250 569 702 ;
+C -1 ; WX 664 ; N uni03D6 ; B 73 -20 672 588 ;
+C -1 ; WX 562 ; N uni03F1 ; B 63 -250 569 469 ;
+C -1 ; WX 491 ; N uni03F5 ; B 78 -20 511 469 ;
+C -1 ; WX 611 ; N baht ; B 64 -83 643 775 ;
+C -1 ; WX 774 ; N Ddotbelow ; B 56 -193 825 692 ;
+C -1 ; WX 611 ; N ddotbelow ; B 67 -193 623 726 ;
+C -1 ; WX 774 ; N Dlinebelow ; B 56 -169 825 692 ;
+C -1 ; WX 611 ; N dlinebelow ; B 67 -169 623 726 ;
+C -1 ; WX 832 ; N Hdotbelow ; B 21 -193 932 692 ;
+C -1 ; WX 582 ; N hdotbelow ; B 5 -193 577 726 ;
+C -1 ; WX 832 ; N Hdieresis ; B 21 -3 932 869 ;
+C -1 ; WX 582 ; N hdieresis ; B 5 -3 592 903 ;
+C -1 ; WX 832 ; N Hbrevebelow ; B 21 -207 932 692 ;
+C -1 ; WX 582 ; N hbrevebelow ; B 5 -207 577 726 ;
+C -1 ; WX 337 ; N Idieresisacute ; B 21 -3 490 1065 ;
+C -1 ; WX 287 ; N idieresisacute ; B 20 -3 426 833 ;
+C -1 ; WX 611 ; N Ldotbelow ; B 64 -193 616 692 ;
+C -1 ; WX 291 ; N ldotbelow ; B 20 -193 315 726 ;
+C -1 ; WX 611 ; N Ldotbelowmacron ; B 64 -193 616 846 ;
+C -1 ; WX 291 ; N ldotbelowmacron ; B 20 -193 458 880 ;
+C -1 ; WX 946 ; N Mdotbelow ; B 15 -193 1042 692 ;
+C -1 ; WX 883 ; N mdotbelow ; B 15 -193 874 469 ;
+C -1 ; WX 831 ; N Ndotaccent ; B 16 -20 935 869 ;
+C -1 ; WX 582 ; N ndotaccent ; B 5 -3 577 642 ;
+C -1 ; WX 831 ; N Ndotbelow ; B 16 -193 935 692 ;
+C -1 ; WX 582 ; N ndotbelow ; B 5 -193 577 469 ;
+C -1 ; WX 668 ; N Rdotaccent ; B 21 -3 675 869 ;
+C -1 ; WX 395 ; N rdotaccent ; B 20 -3 455 642 ;
+C -1 ; WX 668 ; N Rdotbelow ; B 21 -193 675 692 ;
+C -1 ; WX 395 ; N rdotbelow ; B 20 -193 455 469 ;
+C -1 ; WX 668 ; N Rdotbelowmacron ; B 21 -193 675 846 ;
+C -1 ; WX 395 ; N rdotbelowmacron ; B 20 -193 457 639 ;
+C -1 ; WX 525 ; N Sdotbelow ; B 33 -193 579 709 ;
+C -1 ; WX 424 ; N sdotbelow ; B 31 -193 432 469 ;
+C -1 ; WX 613 ; N Tdotbelow ; B 119 -193 717 692 ;
+C -1 ; WX 326 ; N tdotbelow ; B 87 -193 396 621 ;
+C -1 ; WX 613 ; N Tlinebelow ; B 119 -169 717 692 ;
+C -1 ; WX 326 ; N tlinebelow ; B -22 -169 396 621 ;
+C -1 ; WX 1000 ; N Wgrave ; B 125 -9 1106 888 ;
+C -1 ; WX 834 ; N wgrave ; B 82 -7 889 677 ;
+C -1 ; WX 1000 ; N Wacute ; B 125 -9 1106 888 ;
+C -1 ; WX 834 ; N wacute ; B 82 -7 889 677 ;
+C -1 ; WX 1000 ; N Wdieresis ; B 125 -9 1106 869 ;
+C -1 ; WX 834 ; N wdieresis ; B 82 -7 889 642 ;
+C -1 ; WX 667 ; N Zdotbelow ; B 14 -193 755 692 ;
+C -1 ; WX 500 ; N zdotbelow ; B 19 -193 536 462 ;
+C -1 ; WX 326 ; N tdieresis ; B 89 -12 427 798 ;
+C -1 ; WX 778 ; N Adotbelow ; B 14 -193 761 700 ;
+C -1 ; WX 500 ; N adotbelow ; B 49 -193 476 469 ;
+C -1 ; WX 778 ; N Ahookabove ; B 14 -3 761 946 ;
+C -1 ; WX 500 ; N ahookabove ; B 49 -12 476 703 ;
+C -1 ; WX 778 ; N Acircumflexacute ; B 14 -3 761 1046 ;
+C -1 ; WX 500 ; N acircumflexacute ; B 49 -12 505 803 ;
+C -1 ; WX 778 ; N Acircumflexgrave ; B 14 -3 761 1046 ;
+C -1 ; WX 500 ; N acircumflexgrave ; B 49 -12 505 803 ;
+C -1 ; WX 778 ; N Acircumflexhookabove ; B 14 -3 761 1088 ;
+C -1 ; WX 500 ; N acircumflexhookabove ; B 49 -12 555 845 ;
+C -1 ; WX 778 ; N Acircumflextilde ; B 14 -3 761 1022 ;
+C -1 ; WX 500 ; N acircumflextilde ; B 49 -12 549 779 ;
+C -1 ; WX 778 ; N Acircumflexdotbelow ; B 14 -193 761 887 ;
+C -1 ; WX 500 ; N acircumflexdotbelow ; B 49 -193 492 676 ;
+C -1 ; WX 778 ; N Abreveacute ; B 14 -3 761 1043 ;
+C -1 ; WX 500 ; N abreveacute ; B 49 -12 541 800 ;
+C -1 ; WX 778 ; N Abrevegrave ; B 14 -3 761 1043 ;
+C -1 ; WX 500 ; N abrevegrave ; B 49 -12 512 800 ;
+C -1 ; WX 778 ; N Abrevehookabove ; B 14 -3 761 1045 ;
+C -1 ; WX 500 ; N abrevehookabove ; B 49 -12 512 802 ;
+C -1 ; WX 778 ; N Abrevetilde ; B 14 -3 761 1015 ;
+C -1 ; WX 500 ; N abrevetilde ; B 49 -12 548 772 ;
+C -1 ; WX 778 ; N Abrevedotbelow ; B 14 -193 761 884 ;
+C -1 ; WX 500 ; N abrevedotbelow ; B 49 -193 505 671 ;
+C -1 ; WX 611 ; N Edotbelow ; B 33 -193 677 692 ;
+C -1 ; WX 479 ; N edotbelow ; B 59 -193 501 469 ;
+C -1 ; WX 611 ; N Ehookabove ; B 33 -3 677 946 ;
+C -1 ; WX 479 ; N ehookabove ; B 59 -20 501 703 ;
+C -1 ; WX 611 ; N Etilde ; B 33 -3 677 872 ;
+C -1 ; WX 479 ; N etilde ; B 59 -20 541 645 ;
+C -1 ; WX 611 ; N Ecircumflexacute ; B 33 -3 677 1046 ;
+C -1 ; WX 479 ; N ecircumflexacute ; B 59 -20 521 803 ;
+C -1 ; WX 611 ; N Ecircumflexgrave ; B 33 -3 677 1046 ;
+C -1 ; WX 479 ; N ecircumflexgrave ; B 59 -20 521 803 ;
+C -1 ; WX 611 ; N Ecircumflexhookabove ; B 33 -3 677 1088 ;
+C -1 ; WX 479 ; N ecircumflexhookabove ; B 59 -20 571 845 ;
+C -1 ; WX 611 ; N Ecircumflextilde ; B 33 -3 677 1022 ;
+C -1 ; WX 479 ; N ecircumflextilde ; B 59 -20 565 779 ;
+C -1 ; WX 611 ; N Ecircumflexdotbelow ; B 33 -193 677 887 ;
+C -1 ; WX 479 ; N ecircumflexdotbelow ; B 59 -193 508 676 ;
+C -1 ; WX 337 ; N Ihookabove ; B 21 -3 437 946 ;
+C -1 ; WX 287 ; N ihookabove ; B 20 -3 348 703 ;
+C -1 ; WX 337 ; N Idotbelow ; B 21 -193 437 692 ;
+C -1 ; WX 287 ; N idotbelow ; B 20 -193 309 687 ;
+C -1 ; WX 786 ; N Odotbelow ; B 75 -193 836 709 ;
+C -1 ; WX 546 ; N odotbelow ; B 65 -193 561 469 ;
+C -1 ; WX 786 ; N Ohookabove ; B 75 -20 836 946 ;
+C -1 ; WX 546 ; N ohookabove ; B 65 -20 561 703 ;
+C -1 ; WX 786 ; N Ocircumflexacute ; B 75 -20 836 1046 ;
+C -1 ; WX 546 ; N ocircumflexacute ; B 65 -20 561 803 ;
+C -1 ; WX 786 ; N Ocircumflexgrave ; B 75 -20 836 1046 ;
+C -1 ; WX 546 ; N ocircumflexgrave ; B 65 -20 561 803 ;
+C -1 ; WX 786 ; N Ocircumflexhookabove ; B 75 -20 836 1088 ;
+C -1 ; WX 546 ; N ocircumflexhookabove ; B 65 -20 588 845 ;
+C -1 ; WX 786 ; N Ocircumflextilde ; B 75 -20 836 1022 ;
+C -1 ; WX 546 ; N ocircumflextilde ; B 65 -20 582 779 ;
+C -1 ; WX 786 ; N Ocircumflexdotbelow ; B 75 -193 836 887 ;
+C -1 ; WX 546 ; N ocircumflexdotbelow ; B 65 -193 561 676 ;
+C -1 ; WX 786 ; N Ohornacute ; B 75 -20 893 888 ;
+C -1 ; WX 546 ; N ohornacute ; B 65 -20 660 677 ;
+C -1 ; WX 786 ; N Ohorngrave ; B 75 -20 893 888 ;
+C -1 ; WX 546 ; N ohorngrave ; B 65 -20 660 677 ;
+C -1 ; WX 786 ; N Ohornhookabove ; B 75 -20 893 946 ;
+C -1 ; WX 546 ; N ohornhookabove ; B 65 -20 660 703 ;
+C -1 ; WX 786 ; N Ohorntilde ; B 75 -20 893 872 ;
+C -1 ; WX 546 ; N ohorntilde ; B 65 -20 660 645 ;
+C -1 ; WX 786 ; N Ohorndotbelow ; B 75 -193 893 781 ;
+C -1 ; WX 546 ; N ohorndotbelow ; B 65 -193 660 532 ;
+C -1 ; WX 778 ; N Udotbelow ; B 129 -193 881 692 ;
+C -1 ; WX 603 ; N udotbelow ; B 89 -193 586 469 ;
+C -1 ; WX 778 ; N Uhookabove ; B 129 -20 881 946 ;
+C -1 ; WX 603 ; N uhookabove ; B 89 -12 586 703 ;
+C -1 ; WX 778 ; N Uhornacute ; B 129 -20 937 888 ;
+C -1 ; WX 640 ; N uhornacute ; B 89 -12 733 677 ;
+C -1 ; WX 778 ; N Uhorngrave ; B 129 -20 937 888 ;
+C -1 ; WX 640 ; N uhorngrave ; B 89 -12 733 677 ;
+C -1 ; WX 778 ; N Uhornhookabove ; B 129 -20 937 946 ;
+C -1 ; WX 640 ; N uhornhookabove ; B 89 -12 733 703 ;
+C -1 ; WX 778 ; N Uhorntilde ; B 129 -20 937 872 ;
+C -1 ; WX 640 ; N uhorntilde ; B 89 -12 733 645 ;
+C -1 ; WX 778 ; N Uhorndotbelow ; B 129 -193 937 781 ;
+C -1 ; WX 640 ; N uhorndotbelow ; B 89 -193 733 532 ;
+C -1 ; WX 667 ; N Ygrave ; B 124 -3 776 888 ;
+C -1 ; WX 556 ; N ygrave ; B -20 -283 625 677 ;
+C -1 ; WX 667 ; N Ydotbelow ; B 124 -193 776 705 ;
+C -1 ; WX 556 ; N ydotbelow ; B -20 -283 625 459 ;
+C -1 ; WX 667 ; N Yhookabove ; B 124 -3 776 946 ;
+C -1 ; WX 556 ; N yhookabove ; B -20 -283 625 703 ;
+C -1 ; WX 667 ; N Ytilde ; B 124 -3 776 872 ;
+C -1 ; WX 556 ; N ytilde ; B -20 -283 625 645 ;
+C -1 ; WX 333 ; N uni2010 ; B 58 215 364 287 ;
+C -1 ; WX 333 ; N uni2011 ; B 58 215 364 287 ;
+C -1 ; WX 500 ; N endash ; B 39 219 549 277 ;
+C -1 ; WX 1000 ; N emdash ; B 39 219 1049 277 ;
+C -1 ; WX 606 ; N dblverticalbar ; B 187 -184 515 726 ;
+C -1 ; WX 278 ; N quoteleft ; B 126 446 356 709 ;
+C -1 ; WX 278 ; N quoteright ; B 125 446 356 709 ;
+C -1 ; WX 278 ; N quotesinglbase ; B -3 -153 227 110 ;
+C -1 ; WX 500 ; N quotedblleft ; B 132 446 572 709 ;
+C -1 ; WX 500 ; N quotedblright ; B 131 446 572 709 ;
+C -1 ; WX 500 ; N quotedblbase ; B 26 -153 466 110 ;
+C -1 ; WX 500 ; N dagger ; B 104 -5 547 694 ;
+C -1 ; WX 500 ; N daggerdbl ; B 27 -249 552 694 ;
+C -1 ; WX 606 ; N bullet ; B 189 172 539 516 ;
+C -1 ; WX 1000 ; N ellipsis ; B 117 -5 901 111 ;
+C -1 ; WX 1000 ; N perthousand ; B 129 -20 992 709 ;
+C -1 ; WX 1323 ; N permyriad ; B 129 -20 1315 709 ;
+C -1 ; WX 331 ; N guilsinglleft ; B 109 71 338 428 ;
+C -1 ; WX 331 ; N guilsinglright ; B 81 71 310 428 ;
+C -1 ; WX 606 ; N referencemark ; B 62 -34 632 534 ;
+C -1 ; WX 444 ; N interrobang ; B 139 -5 493 734 ;
+C -1 ; WX 500 ; N uni203F ; B -5 -281 445 -163 ;
+C -1 ; WX 500 ; N uni2040 ; B 127 574 577 692 ;
+C -1 ; WX 167 ; N fraction ; B -166 0 458 689 ;
+C -1 ; WX 311 ; N quillbracketleft ; B 31 -170 398 721 ;
+C -1 ; WX 311 ; N quillbracketright ; B 10 -170 377 721 ;
+C -1 ; WX 500 ; N discount ; B 37 0 585 692 ;
+C -1 ; WX 500 ; N uni2054 ; B -24 -281 426 -163 ;
+C -1 ; WX 709 ; N colonmonetary ; B 75 -83 782 775 ;
+C -1 ; WX 500 ; N lira ; B 10 -13 596 694 ;
+C -1 ; WX 831 ; N naira ; B 16 -20 935 692 ;
+C -1 ; WX 1000 ; N won ; B 54 -9 1106 700 ;
+C -1 ; WX 542 ; N dong ; B 34 -34 604 692 ;
+C -1 ; WX 500 ; N Euro ; B 46 -20 614 689 ;
+C -1 ; WX 604 ; N peso ; B 21 -3 678 692 ;
+C -1 ; WX 1118 ; N centigrade ; B 142 -20 1150 709 ;
+C -1 ; WX 379 ; N l.script ; B 69 -20 429 712 ;
+C -1 ; WX 1096 ; N numero ; B -1 -20 1104 692 ;
+C -1 ; WX 747 ; N published ; B 82 -19 781 668 ;
+C -1 ; WX 706 ; N weierstrass ; B 39 -250 711 485 ;
+C -1 ; WX 668 ; N recipe ; B 21 -3 675 692 ;
+C -1 ; WX 938 ; N servicemark ; B 106 320 1016 700 ;
+C -1 ; WX 979 ; N trademark ; B 150 326 1057 692 ;
+C -1 ; WX 765 ; N ohm ; B 47 0 784 731 ;
+C -1 ; WX 765 ; N uni2127 ; B 104 -39 841 692 ;
+C -1 ; WX 772 ; N estimated ; B 90 0 792 623 ;
+C -1 ; WX 1000 ; N uni2190 ; B 102 6 969 494 ;
+C -1 ; WX 648 ; N uni2191 ; B 163 -170 651 692 ;
+C -1 ; WX 1000 ; N uni2192 ; B 119 6 986 494 ;
+C -1 ; WX 648 ; N uni2193 ; B 85 -192 573 670 ;
+C -1 ; WX 494 ; N partialdiff ; B 54 -10 541 753 ;
+C -1 ; WX 713 ; N summation ; B -8 -123 755 752 ;
+C -1 ; WX 606 ; N minus ; B 79 222 615 278 ;
+C -1 ; WX 606 ; N minusplus ; B 69 -69 654 500 ;
+C -1 ; WX 0 ; N fraction.alt ; B -251 0 373 689 ;
+C -1 ; WX 472 ; N asterisk.math ; B 71 42 484 458 ;
+C -1 ; WX 549 ; N radical ; B 84 -48 681 918 ;
+C -1 ; WX 833 ; N infinity ; B 160 112 780 488 ;
+C -1 ; WX 606 ; N anglearc ; B 96 -48 629 548 ;
+C -1 ; WX 606 ; N approxequal ; B 70 82 628 441 ;
+C -1 ; WX 606 ; N notequal ; B 64 34 630 466 ;
+C -1 ; WX 606 ; N lessequal ; B 75 -28 625 564 ;
+C -1 ; WX 606 ; N greaterequal ; B 75 -28 600 564 ;
+C -1 ; WX 500 ; N star ; B 69 34 537 480 ;
+C -1 ; WX 606 ; N diameter ; B 38 -19 656 519 ;
+C -1 ; WX 535 ; N angleleft ; B 88 -184 624 726 ;
+C -1 ; WX 535 ; N angleright ; B 8 -184 544 726 ;
+C -1 ; WX 553 ; N blanksymbol ; B 57 -12 560 726 ;
+C -1 ; WX 500 ; N uni2423 ; B 15 -140 497 208 ;
+C -1 ; WX 494 ; N lozenge ; B 84 0 532 740 ;
+C -1 ; WX 606 ; N openbullet ; B 189 172 539 516 ;
+C -1 ; WX 600 ; N uni266A ; B 71 -20 609 692 ;
+C -1 ; WX 500 ; N married ; B -76 26 664 475 ;
+C -1 ; WX 500 ; N divorced ; B -131 -199 719 699 ;
+C -1 ; WX 304 ; N dblbracketleft ; B 8 -184 392 726 ;
+C -1 ; WX 304 ; N dblbracketright ; B 8 -184 392 726 ;
+C -1 ; WX 606 ; N lessequal.slant ; B 103 -66 625 564 ;
+C -1 ; WX 606 ; N greaterequal.slant ; B 57 -66 589 564 ;
+C -1 ; WX 576 ; N abreveacute.sc ; B 22 -3 585 800 ;
+C -1 ; WX 576 ; N abrevedotbelow.sc ; B 22 -190 553 671 ;
+C -1 ; WX 576 ; N abrevegrave.sc ; B 22 -3 556 800 ;
+C -1 ; WX 576 ; N abrevehookabove.sc ; B 22 -3 556 802 ;
+C -1 ; WX 576 ; N abrevetilde.sc ; B 22 -3 592 772 ;
+C -1 ; WX 576 ; N acaron.sc ; B 22 -3 565 676 ;
+C -1 ; WX 576 ; N acircumflexacute.sc ; B 22 -3 553 803 ;
+C -1 ; WX 576 ; N acircumflexdotbelow.sc ; B 22 -190 553 676 ;
+C -1 ; WX 576 ; N acircumflexgrave.sc ; B 22 -3 553 803 ;
+C -1 ; WX 576 ; N acircumflexhookabove.sc ; B 22 -3 599 845 ;
+C -1 ; WX 576 ; N acircumflextilde.sc ; B 22 -3 593 779 ;
+C -1 ; WX 576 ; N adblgrave.sc ; B 22 -3 553 683 ;
+C -1 ; WX 576 ; N adotbelow.sc ; B 22 -193 553 456 ;
+C -1 ; WX 576 ; N ahookabove.sc ; B 22 -3 553 703 ;
+C -1 ; WX 576 ; N aogonekacute.sc ; B 22 -250 553 677 ;
+C -1 ; WX 576 ; N aringacute.sc ; B 22 -3 575 855 ;
+C -1 ; WX 576 ; N dcroat.sc ; B 52 -2 598 451 ;
+C -1 ; WX 576 ; N ddotbelow.sc ; B 51 -193 598 452 ;
+C -1 ; WX 576 ; N dlinebelow.sc ; B 51 -169 598 452 ;
+C -1 ; WX 266 ; N dotlessi.sc ; B 27 -3 319 452 ;
+C -1 ; WX 264 ; N dotlessj.sc ; B -19 -124 316 452 ;
+C -1 ; WX 449 ; N ecircumflexacute.sc ; B 35 -3 491 803 ;
+C -1 ; WX 449 ; N ecircumflexdotbelow.sc ; B 35 -190 491 676 ;
+C -1 ; WX 449 ; N ecircumflexgrave.sc ; B 35 -3 491 803 ;
+C -1 ; WX 449 ; N ecircumflexhookabove.sc ; B 35 -3 538 845 ;
+C -1 ; WX 449 ; N ecircumflextilde.sc ; B 35 -3 532 779 ;
+C -1 ; WX 449 ; N edblgrave.sc ; B 35 -3 491 683 ;
+C -1 ; WX 449 ; N edotbelow.sc ; B 35 -193 491 452 ;
+C -1 ; WX 449 ; N ehookabove.sc ; B 35 -3 491 703 ;
+C -1 ; WX 449 ; N eogonekacute.sc ; B 35 -250 491 677 ;
+C -1 ; WX 449 ; N ereversed.sc ; B 40 -3 503 452 ;
+C -1 ; WX 449 ; N etilde.sc ; B 35 -3 508 645 ;
+C -1 ; WX 449 ; N eturned.sc ; B 39 -3 494 452 ;
+C -1 ; WX 558 ; N gacute.sc ; B 60 -13 587 677 ;
+C -1 ; WX 558 ; N gcaron.sc ; B 60 -13 587 676 ;
+C -1 ; WX 833 ; N germandbls.sc ; B 49 -13 838 462 ;
+C -1 ; WX 614 ; N h_uni0303.sc ; B 27 -3 666 629 ;
+C -1 ; WX 614 ; N hbrevebelow.sc ; B 27 -207 666 452 ;
+C -1 ; WX 614 ; N hdieresis.sc ; B 27 -3 666 626 ;
+C -1 ; WX 266 ; N icaron.sc ; B 27 -3 409 676 ;
+C -1 ; WX 266 ; N idblgrave.sc ; B 1 -3 340 683 ;
+C -1 ; WX 266 ; N idieresisacute.sc ; B 27 -3 414 833 ;
+C -1 ; WX 266 ; N idotbelow.sc ; B 27 -193 319 452 ;
+C -1 ; WX 266 ; N ihookabove.sc ; B 27 -3 336 703 ;
+C -1 ; WX 266 ; N imacron.alt.sc ; B 27 -3 344 619 ;
+C -1 ; WX 266 ; N iogonekacute.sc ; B -7 -250 382 677 ;
+C -1 ; WX 264 ; N jacute.sc ; B -19 -124 380 677 ;
+C -1 ; WX 449 ; N l_uni0303.sc ; B 57 -3 453 645 ;
+C -1 ; WX 449 ; N lslash.sc ; B 57 -3 453 452 ;
+C -1 ; WX 587 ; N ocaron.sc ; B 60 -13 608 676 ;
+C -1 ; WX 587 ; N ocircumflexacute.sc ; B 60 -13 608 803 ;
+C -1 ; WX 587 ; N ocircumflexdotbelow.sc ; B 60 -180 608 676 ;
+C -1 ; WX 587 ; N ocircumflexgrave.sc ; B 60 -13 608 803 ;
+C -1 ; WX 587 ; N ocircumflexhookabove.sc ; B 60 -13 609 845 ;
+C -1 ; WX 587 ; N ocircumflextilde.sc ; B 60 -13 608 779 ;
+C -1 ; WX 587 ; N odblgrave.sc ; B 60 -13 608 683 ;
+C -1 ; WX 587 ; N odotbelow.sc ; B 60 -193 608 462 ;
+C -1 ; WX 723 ; N oe.sc ; B 62 -13 767 462 ;
+C -1 ; WX 587 ; N ohookabove.sc ; B 60 -13 608 703 ;
+C -1 ; WX 695 ; N ohorn.sc ; B 78 -13 713 532 ;
+C -1 ; WX 695 ; N ohornacute.sc ; B 78 -13 713 677 ;
+C -1 ; WX 695 ; N ohorndotbelow.sc ; B 78 -180 713 532 ;
+C -1 ; WX 695 ; N ohorngrave.sc ; B 78 -13 713 677 ;
+C -1 ; WX 695 ; N ohornhookabove.sc ; B 78 -13 713 703 ;
+C -1 ; WX 695 ; N ohorntilde.sc ; B 78 -13 713 645 ;
+C -1 ; WX 587 ; N oogonek.sc ; B 60 -250 608 462 ;
+C -1 ; WX 587 ; N oogonekacute.sc ; B 60 -250 608 677 ;
+C -1 ; WX 499 ; N rdblgrave.sc ; B 27 -3 492 683 ;
+C -1 ; WX 499 ; N rdotaccent.sc ; B 27 -3 492 642 ;
+C -1 ; WX 404 ; N scaron.sc ; B 36 -13 463 676 ;
+C -1 ; WX 404 ; N sdotbelow.sc ; B 36 -193 424 462 ;
+C -1 ; WX 440 ; N t_uni0303.sc ; B 78 -3 508 645 ;
+C -1 ; WX 440 ; N tcedilla.sc ; B 78 -225 508 451 ;
+C -1 ; WX 440 ; N tdieresis.sc ; B 78 -3 508 642 ;
+C -1 ; WX 440 ; N tdotbelow.sc ; B 78 -193 508 451 ;
+C -1 ; WX 440 ; N tlinebelow.sc ; B 35 -169 508 451 ;
+C -1 ; WX 576 ; N ubrevebelowinverted.sc ; B 95 -207 630 452 ;
+C -1 ; WX 576 ; N ucaron.sc ; B 95 -13 630 676 ;
+C -1 ; WX 576 ; N udblgrave.sc ; B 95 -13 630 683 ;
+C -1 ; WX 576 ; N udieresisacute.sc ; B 95 -13 630 833 ;
+C -1 ; WX 576 ; N udieresiscaron.sc ; B 95 -13 630 832 ;
+C -1 ; WX 576 ; N udieresisgrave.sc ; B 95 -13 630 833 ;
+C -1 ; WX 576 ; N udotbelow.sc ; B 95 -193 630 452 ;
+C -1 ; WX 576 ; N uhookabove.sc ; B 95 -13 630 703 ;
+C -1 ; WX 663 ; N uhorn.sc ; B 110 -13 731 532 ;
+C -1 ; WX 663 ; N uhornacute.sc ; B 110 -13 731 677 ;
+C -1 ; WX 663 ; N uhorndotbelow.sc ; B 110 -180 731 532 ;
+C -1 ; WX 663 ; N uhorngrave.sc ; B 110 -13 731 677 ;
+C -1 ; WX 663 ; N uhornhookabove.sc ; B 110 -13 731 703 ;
+C -1 ; WX 663 ; N uhorntilde.sc ; B 110 -13 731 645 ;
+C -1 ; WX 498 ; N ydotbelow.sc ; B 92 -193 556 460 ;
+C -1 ; WX 498 ; N yhookabove.sc ; B 92 -3 556 703 ;
+C -1 ; WX 498 ; N ytilde.sc ; B 92 -3 556 645 ;
+C -1 ; WX 478 ; N zcaron.sc ; B 5 -2 543 676 ;
+C -1 ; WX 478 ; N zdotbelow.sc ; B 5 -193 543 451 ;
+C -1 ; WX 876 ; N f_k ; B 22 -12 912 728 ;
+C -1 ; WX 333 ; N acute.cap ; B 151 506 414 645 ;
+C -1 ; WX 0 ; N uni0301.cap ; B -177 749 86 888 ;
+C -1 ; WX 333 ; N breve.cap ; B 125 512 432 641 ;
+C -1 ; WX 333 ; N space_uni0306_uni0301.cap ; B 125 512 461 800 ;
+C -1 ; WX 333 ; N space_uni0306_uni0301 ; B 125 512 461 800 ;
+C -1 ; WX 333 ; N space_uni032E ; B -2 -207 305 -78 ;
+C -1 ; WX 305 ; N space_uni032F ; B -22 -207 284 -78 ;
+C -1 ; WX 0 ; N uni0306.cap ; B -234 755 73 884 ;
+C -1 ; WX 333 ; N space_uni0306_uni0300.cap ; B 125 512 432 800 ;
+C -1 ; WX 333 ; N space_uni0306_uni0300 ; B 125 512 432 800 ;
+C -1 ; WX 333 ; N space_uni0306_uni0309.cap ; B 125 512 432 802 ;
+C -1 ; WX 333 ; N space_uni0306_uni0309 ; B 125 512 432 802 ;
+C -1 ; WX 305 ; N space_uni0311.cap ; B 104 512 411 641 ;
+C -1 ; WX 333 ; N space_uni0311 ; B 116 513 402 671 ;
+C -1 ; WX 0 ; N uni0311.cap ; B -255 755 52 884 ;
+C -1 ; WX 333 ; N space_uni0306_uni0303.cap ; B 120 512 468 772 ;
+C -1 ; WX 333 ; N space_uni0306_uni0303 ; B 120 512 468 772 ;
+C -1 ; WX 333 ; N caron.cap ; B 111 509 448 644 ;
+C -1 ; WX 0 ; N uni030C.cap ; B -263 752 74 887 ;
+C -1 ; WX 333 ; N circumflex.cap ; B 88 509 425 644 ;
+C -1 ; WX 333 ; N space_uni0302_uni0301.cap ; B 88 509 425 803 ;
+C -1 ; WX 333 ; N space_uni0302_uni0301 ; B 88 509 425 803 ;
+C -1 ; WX 0 ; N uni0302.cap ; B -287 752 50 887 ;
+C -1 ; WX 333 ; N space_uni0302_uni0300.cap ; B 88 509 425 803 ;
+C -1 ; WX 333 ; N space_uni0302_uni0300 ; B 88 509 425 803 ;
+C -1 ; WX 333 ; N space_uni0302_uni0309.cap ; B 88 509 475 845 ;
+C -1 ; WX 333 ; N space_uni0302_uni0309 ; B 88 509 475 845 ;
+C -1 ; WX 333 ; N space_uni0302_uni0303.cap ; B 88 509 469 779 ;
+C -1 ; WX 333 ; N space_uni0302_uni0303 ; B 88 509 469 779 ;
+C -1 ; WX 333 ; N space_uni0326 ; B 23 -271 195 -77 ;
+C -1 ; WX 333 ; N breve.cyrcap ; B 125 512 432 641 ;
+C -1 ; WX 333 ; N breve.cyr ; B 141 513 426 671 ;
+C -1 ; WX 305 ; N circumflex.cyrcap ; B 104 512 411 641 ;
+C -1 ; WX 333 ; N circumflex.cyr ; B 116 513 402 671 ;
+C -1 ; WX 380 ; N space_uni030F.cap ; B 34 506 417 645 ;
+C -1 ; WX 380 ; N space_uni030F ; B 57 502 396 683 ;
+C -1 ; WX 0 ; N uni030F.cap ; B -363 749 20 888 ;
+C -1 ; WX 333 ; N dieresis.cap ; B 118 526 419 626 ;
+C -1 ; WX 333 ; N space_uni0308_uni0301.cap ; B 118 526 445 822 ;
+C -1 ; WX 333 ; N space_uni0308_uni0301 ; B 120 542 447 833 ;
+C -1 ; WX 333 ; N space_uni0308_uni030C.cap ; B 118 526 479 821 ;
+C -1 ; WX 333 ; N space_uni0308_uni030C ; B 120 542 482 832 ;
+C -1 ; WX 0 ; N uni0308.cap ; B -256 769 45 869 ;
+C -1 ; WX 333 ; N space_uni0308_uni0300.cap ; B 118 526 419 822 ;
+C -1 ; WX 333 ; N space_uni0308_uni0300 ; B 120 542 421 833 ;
+C -1 ; WX 250 ; N dotaccent.cap ; B 176 526 278 626 ;
+C -1 ; WX 0 ; N uni0307.cap ; B -157 769 -55 869 ;
+C -1 ; WX 333 ; N grave.cap ; B 137 506 360 645 ;
+C -1 ; WX 0 ; N uni0300.cap ; B -191 749 32 888 ;
+C -1 ; WX 333 ; N space_uni0309.cap ; B 189 506 366 687 ;
+C -1 ; WX 333 ; N space_uni0309 ; B 192 522 369 703 ;
+C -1 ; WX 0 ; N uni0309.cap ; B -184 749 -7 930 ;
+C -1 ; WX 333 ; N space_uni031B ; B 247 356 426 532 ;
+C -1 ; WX 380 ; N hungarumlaut.cap ; B 141 506 564 645 ;
+C -1 ; WX 0 ; N uni030B.cap ; B -256 749 167 888 ;
+C -1 ; WX 333 ; N space_uni0332 ; B -19 -169 303 -116 ;
+C -1 ; WX 333 ; N macron.cap ; B 108 550 429 603 ;
+C -1 ; WX 333 ; N macron.cap.alt ; B 164 550 373 603 ;
+C -1 ; WX 333 ; N macron.alt ; B 167 566 376 619 ;
+C -1 ; WX 333 ; N space_uni0331 ; B -19 -169 303 -116 ;
+C -1 ; WX 0 ; N uni0304.cap ; B -265 793 56 846 ;
+C -1 ; WX 333 ; N ring.cap ; B 170 496 374 696 ;
+C -1 ; WX 333 ; N space_uni030A_uni0301.cap ; B 170 496 451 855 ;
+C -1 ; WX 333 ; N space_uni030A_uni0301 ; B 170 496 451 855 ;
+C -1 ; WX 0 ; N uni030A.cap ; B -203 739 1 939 ;
+C -1 ; WX 333 ; N tilde.cap ; B 94 524 443 629 ;
+C -1 ; WX 333 ; N space_uni0330 ; B -32 -195 316 -90 ;
+C -1 ; WX 0 ; N uni0303.cap ; B -261 767 88 872 ;
+C -1 ; WX 333 ; N acute.ts1 ; B 167 506 416 677 ;
+C -1 ; WX 778 ; N Aogonekacute ; B 14 -250 761 888 ;
+C -1 ; WX 500 ; N aogonekacute ; B 49 -250 499 677 ;
+C -1 ; WX 747 ; N at.alt ; B 52 -159 776 555 ;
+C -1 ; WX 747 ; N bigcircle ; B 82 -19 781 668 ;
+C -1 ; WX 500 ; N star.alt ; B 69 34 537 480 ;
+C -1 ; WX 333 ; N breve.ts1 ; B 141 513 426 671 ;
+C -1 ; WX 333 ; N caron.ts1 ; B 130 509 442 676 ;
+C -1 ; WX 747 ; N copyleft ; B 82 -19 781 668 ;
+C -1 ; WX 0 ; N cwm ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N cwmascender ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N cwmcapital ; B 0 0 0 0 ;
+C -1 ; WX 380 ; N dblgrave.ts1 ; B 57 502 396 683 ;
+C -1 ; WX 580 ; N died ; B 111 0 628 692 ;
+C -1 ; WX 333 ; N dieresis.ts1 ; B 120 542 421 642 ;
+C -1 ; WX 250 ; N space_uni0323 ; B 49 -193 151 -93 ;
+C -1 ; WX 611 ; N Eogonekacute ; B 33 -250 677 888 ;
+C -1 ; WX 479 ; N eogonekacute ; B 59 -250 501 677 ;
+C -1 ; WX 1102 ; N Germandbls ; B 49 -20 1138 709 ;
+C -1 ; WX 444 ; N gnaborretni ; B 38 -240 392 499 ;
+C -1 ; WX 333 ; N grave.ts1 ; B 143 506 344 677 ;
+C -1 ; WX 763 ; N guarani ; B 75 -83 810 775 ;
+C -1 ; WX 380 ; N hungarumlaut.ts1 ; B 162 502 553 683 ;
+C -1 ; WX 167 ; N hyphen.alt ; B 56 215 362 287 ;
+C -1 ; WX 333 ; N hyphen.prop ; B 76 327 381 399 ;
+C -1 ; WX 333 ; N hyphendbl ; B 41 131 377 371 ;
+C -1 ; WX 167 ; N hyphendbl.alt ; B 41 131 377 371 ;
+C -1 ; WX 337 ; N Iogonekacute ; B 21 -250 459 888 ;
+C -1 ; WX 287 ; N iogonekacute ; B 15 -250 393 677 ;
+C -1 ; WX 333 ; N Jacute ; B -44 -195 455 888 ;
+C -1 ; WX 234 ; N jacute ; B -83 -283 366 677 ;
+C -1 ; WX 1000 ; N leaf ; B 19 -57 1103 749 ;
+C -1 ; WX 333 ; N macron.ts1 ; B 111 566 432 619 ;
+C -1 ; WX 786 ; N Oogonekacute ; B 75 -250 836 888 ;
+C -1 ; WX 546 ; N oogonekacute ; B 65 -250 561 677 ;
+C -1 ; WX 494 ; N paragraph.alt ; B 132 -150 570 695 ;
+C -1 ; WX 361 ; N perthousandzero ; B 31 0 355 321 ;
+C -1 ; WX 371 ; N quotedblbase.ts1 ; B 63 -124 333 116 ;
+C -1 ; WX 208 ; N quotesinglbase.ts1 ; B 72 -124 161 116 ;
+C -1 ; WX 208 ; N quotesingle.ts1 ; B 177 469 265 709 ;
+C -1 ; WX 424 ; N registered.alt ; B 142 424 492 768 ;
+C -1 ; WX 291 ; N suppress ; B 59 305 388 551 ;
+C -1 ; WX 333 ; N tieaccentcapital ; B 251 574 701 692 ;
+C -1 ; WX 500 ; N tieaccentcapital.new ; B 127 574 577 692 ;
+C -1 ; WX 277 ; N tieaccentlowercase ; B 227 594 597 712 ;
+C -1 ; WX 500 ; N tieaccentlowercase.new ; B 171 594 541 712 ;
+C -1 ; WX 606 ; N asciitilde.low ; B 42 -79 564 80 ;
+C -1 ; WX 667 ; N emdash.alt ; B 39 219 716 277 ;
+C -1 ; WX 778 ; N U_uni032F ; B 129 -207 881 692 ;
+C -1 ; WX 603 ; N u_uni032F ; B 89 -207 586 469 ;
+C -1 ; WX 333 ; N J_uni030C.cap ; B -44 -195 600 692 ;
+C -1 ; WX 424 ; N copyright.alt ; B 141 420 491 764 ;
+C -1 ; WX 287 ; N imacron.alt ; B 20 -3 356 619 ;
+C -1 ; WX 337 ; N Imacron.alt ; B 21 -3 437 846 ;
+C -1 ; WX 832 ; N H_uni0303 ; B 21 -3 932 872 ;
+C -1 ; WX 582 ; N h_uni0303 ; B 5 -3 617 906 ;
+C -1 ; WX 611 ; N L_uni0303 ; B 64 -3 616 872 ;
+C -1 ; WX 291 ; N l_uni0303 ; B 20 -3 472 906 ;
+C -1 ; WX 613 ; N T_uni0303 ; B 119 -3 717 872 ;
+C -1 ; WX 326 ; N t_uni0303 ; B 89 -12 451 801 ;
+C -1 ; WX 613 ; N T_uni0308 ; B 119 -3 717 869 ;
+C -1 ; WX 786 ; N Orogate ; B 75 -165 836 854 ;
+C -1 ; WX 546 ; N orogate ; B 65 -165 561 614 ;
+C -1 ; WX 695 ; N orogate.sc ; B 60 -165 609 607 ;
+C -1 ; WX 500 ; N zero.slash ; B 72 -20 544 689 ;
+C -1 ; WX 516 ; N zero.prop ; B 83 -20 555 689 ;
+C -1 ; WX 532 ; N two.prop ; B 39 -3 548 689 ;
+C -1 ; WX 527 ; N three.prop ; B 67 -20 541 689 ;
+C -1 ; WX 510 ; N four.prop ; B 56 -3 534 694 ;
+C -1 ; WX 526 ; N five.prop ; B 64 -20 585 689 ;
+C -1 ; WX 516 ; N six.prop ; B 76 -20 542 689 ;
+C -1 ; WX 493 ; N seven.prop ; B 34 -3 594 689 ;
+C -1 ; WX 514 ; N eight.prop ; B 65 -20 545 689 ;
+C -1 ; WX 517 ; N nine.prop ; B 81 -20 559 689 ;
+C -1 ; WX 500 ; N zero.taboldstyle ; B 57 -20 526 479 ;
+C -1 ; WX 500 ; N one.taboldstyle ; B 95 -3 423 485 ;
+C -1 ; WX 500 ; N two.taboldstyle ; B 20 -3 483 478 ;
+C -1 ; WX 500 ; N three.taboldstyle ; B -7 -238 479 477 ;
+C -1 ; WX 500 ; N four.taboldstyle ; B 6 -225 484 513 ;
+C -1 ; WX 500 ; N five.taboldstyle ; B -7 -238 519 471 ;
+C -1 ; WX 500 ; N six.taboldstyle ; B 68 -20 534 689 ;
+C -1 ; WX 500 ; N seven.taboldstyle ; B 16 -238 577 454 ;
+C -1 ; WX 500 ; N eight.taboldstyle ; B 55 -20 535 689 ;
+C -1 ; WX 500 ; N nine.taboldstyle ; B 24 -230 502 479 ;
+C -1 ; WX 576 ; N abreve.sc ; B 22 -3 553 671 ;
+C -1 ; WX 576 ; N amacron.sc ; B 22 -3 555 619 ;
+C -1 ; WX 576 ; N aogonek.sc ; B 22 -250 553 456 ;
+C -1 ; WX 682 ; N aeacute.sc ; B 4 -3 726 677 ;
+C -1 ; WX 520 ; N cacute.sc ; B 60 -13 567 677 ;
+C -1 ; WX 520 ; N ccaron.sc ; B 60 -13 569 676 ;
+C -1 ; WX 520 ; N ccircumflex.sc ; B 60 -13 567 676 ;
+C -1 ; WX 520 ; N cdotaccent.sc ; B 60 -13 567 642 ;
+C -1 ; WX 576 ; N dcaron.sc ; B 51 -3 598 676 ;
+C -1 ; WX 449 ; N ebreve.sc ; B 35 -3 491 671 ;
+C -1 ; WX 449 ; N ecaron.sc ; B 35 -3 504 676 ;
+C -1 ; WX 449 ; N edotaccent.sc ; B 35 -3 491 642 ;
+C -1 ; WX 449 ; N emacron.sc ; B 35 -3 494 619 ;
+C -1 ; WX 613 ; N eng.sc ; B 23 -252 668 452 ;
+C -1 ; WX 449 ; N eogonek.sc ; B 35 -250 491 452 ;
+C -1 ; WX 558 ; N gbreve.sc ; B 60 -13 587 671 ;
+C -1 ; WX 558 ; N gcircumflex.sc ; B 60 -13 587 676 ;
+C -1 ; WX 558 ; N gcommaaccent.sc ; B 60 -271 587 462 ;
+C -1 ; WX 558 ; N gdotaccent.sc ; B 60 -13 587 642 ;
+C -1 ; WX 614 ; N hbar.sc ; B 12 -3 651 452 ;
+C -1 ; WX 614 ; N hcircumflex.sc ; B 27 -3 666 644 ;
+C -1 ; WX 266 ; N ibreve.sc ; B 27 -3 393 671 ;
+C -1 ; WX 551 ; N ij.sc ; B 39 -124 591 452 ;
+C -1 ; WX 266 ; N imacron.sc ; B 27 -3 399 619 ;
+C -1 ; WX 266 ; N iogonek.sc ; B -7 -250 319 452 ;
+C -1 ; WX 266 ; N itilde.sc ; B 27 -3 413 645 ;
+C -1 ; WX 264 ; N jcircumflex.sc ; B -19 -124 377 676 ;
+C -1 ; WX 539 ; N kcommaaccent.sc ; B 27 -271 583 452 ;
+C -1 ; WX 449 ; N lacute.sc ; B 57 -3 453 677 ;
+C -1 ; WX 449 ; N lcaron.sc ; B 42 -3 483 452 ;
+C -1 ; WX 449 ; N lcommaaccent.sc ; B 57 -271 453 452 ;
+C -1 ; WX 449 ; N ldot.sc ; B 42 -3 442 452 ;
+C -1 ; WX 613 ; N nacute.sc ; B 23 -14 668 677 ;
+C -1 ; WX 613 ; N ncaron.sc ; B 23 -14 668 676 ;
+C -1 ; WX 613 ; N ncommaaccent.sc ; B 23 -271 668 452 ;
+C -1 ; WX 587 ; N obreve.sc ; B 60 -13 608 671 ;
+C -1 ; WX 587 ; N ohungarumlaut.sc ; B 60 -13 663 683 ;
+C -1 ; WX 587 ; N omacron.sc ; B 60 -13 608 619 ;
+C -1 ; WX 617 ; N oslashacute.sc ; B 30 -13 659 692 ;
+C -1 ; WX 499 ; N racute.sc ; B 27 -3 492 677 ;
+C -1 ; WX 499 ; N rcaron.sc ; B 27 -3 511 676 ;
+C -1 ; WX 499 ; N rcommaaccent.sc ; B 27 -271 492 452 ;
+C -1 ; WX 404 ; N sacute.sc ; B 36 -13 437 677 ;
+C -1 ; WX 404 ; N scedilla.sc ; B 36 -225 424 462 ;
+C -1 ; WX 404 ; N scircumflex.sc ; B 36 -13 434 676 ;
+C -1 ; WX 404 ; N uni0219.sc ; B 36 -271 424 462 ;
+C -1 ; WX 440 ; N tcaron.sc ; B 78 -3 508 676 ;
+C -1 ; WX 440 ; N uni021B.sc ; B 77 -271 508 451 ;
+C -1 ; WX 576 ; N ubreve.sc ; B 95 -13 630 671 ;
+C -1 ; WX 576 ; N uhungarumlaut.sc ; B 95 -13 667 683 ;
+C -1 ; WX 576 ; N umacron.sc ; B 95 -13 630 619 ;
+C -1 ; WX 576 ; N uogonek.sc ; B 95 -250 630 452 ;
+C -1 ; WX 576 ; N uring.sc ; B 95 -13 630 692 ;
+C -1 ; WX 576 ; N utilde.sc ; B 95 -13 630 645 ;
+C -1 ; WX 732 ; N wacute.sc ; B 92 -6 788 677 ;
+C -1 ; WX 732 ; N wcircumflex.sc ; B 92 -6 788 676 ;
+C -1 ; WX 732 ; N wdieresis.sc ; B 92 -6 788 642 ;
+C -1 ; WX 732 ; N wgrave.sc ; B 92 -6 788 677 ;
+C -1 ; WX 498 ; N ycircumflex.sc ; B 92 -3 556 676 ;
+C -1 ; WX 498 ; N ygrave.sc ; B 92 -3 556 677 ;
+C -1 ; WX 478 ; N zacute.sc ; B 5 -2 543 677 ;
+C -1 ; WX 478 ; N zdotaccent.sc ; B 5 -2 543 642 ;
+C -1 ; WX 266 ; N idotaccent.sc ; B 27 -3 319 642 ;
+C -1 ; WX 234 ; N dotlessj ; B -83 -283 241 469 ;
+C -1 ; WX 398 ; N one.prop ; B 55 -3 383 694 ;
+C -1 ; WX 750 ; N threequartersemdash ; B 39 219 799 277 ;
+C -1 ; WX 525 ; N dollar.oldstyle ; B 33 -83 579 775 ;
+C -1 ; WX 530 ; N zero.oldstyle ; B 72 -20 541 479 ;
+C -1 ; WX 438 ; N one.oldstyle ; B 75 -3 403 485 ;
+C -1 ; WX 527 ; N two.oldstyle ; B 39 -3 502 478 ;
+C -1 ; WX 519 ; N three.oldstyle ; B 10 -238 496 477 ;
+C -1 ; WX 550 ; N four.oldstyle ; B 44 -225 522 513 ;
+C -1 ; WX 496 ; N five.oldstyle ; B 10 -238 536 471 ;
+C -1 ; WX 516 ; N six.oldstyle ; B 76 -20 542 689 ;
+C -1 ; WX 533 ; N seven.oldstyle ; B 12 -238 573 454 ;
+C -1 ; WX 514 ; N eight.oldstyle ; B 65 -20 545 689 ;
+C -1 ; WX 517 ; N nine.oldstyle ; B 44 -230 522 479 ;
+C -1 ; WX 576 ; N a.sc ; B 22 -3 553 456 ;
+C -1 ; WX 462 ; N b.sc ; B 57 -3 468 452 ;
+C -1 ; WX 520 ; N c.sc ; B 60 -13 567 462 ;
+C -1 ; WX 576 ; N d.sc ; B 51 -3 598 452 ;
+C -1 ; WX 449 ; N e.sc ; B 35 -3 491 452 ;
+C -1 ; WX 410 ; N f.sc ; B 27 -3 477 452 ;
+C -1 ; WX 558 ; N g.sc ; B 60 -13 587 462 ;
+C -1 ; WX 614 ; N h.sc ; B 27 -3 666 452 ;
+C -1 ; WX 266 ; N i.sc ; B 27 -3 319 452 ;
+C -1 ; WX 264 ; N j.sc ; B -19 -124 316 452 ;
+C -1 ; WX 539 ; N k.sc ; B 27 -3 583 452 ;
+C -1 ; WX 449 ; N l.sc ; B 57 -3 453 452 ;
+C -1 ; WX 694 ; N m.sc ; B 23 -6 743 452 ;
+C -1 ; WX 613 ; N n.sc ; B 23 -14 668 452 ;
+C -1 ; WX 587 ; N o.sc ; B 60 -13 608 462 ;
+C -1 ; WX 457 ; N p.sc ; B 27 -3 493 452 ;
+C -1 ; WX 623 ; N q.sc ; B 59 -112 609 462 ;
+C -1 ; WX 499 ; N r.sc ; B 27 -3 492 452 ;
+C -1 ; WX 404 ; N s.sc ; B 36 -13 424 462 ;
+C -1 ; WX 440 ; N t.sc ; B 78 -3 508 451 ;
+C -1 ; WX 576 ; N u.sc ; B 95 -13 630 452 ;
+C -1 ; WX 537 ; N v.sc ; B 92 -6 593 452 ;
+C -1 ; WX 732 ; N w.sc ; B 92 -6 788 456 ;
+C -1 ; WX 498 ; N x.sc ; B 21 -3 545 457 ;
+C -1 ; WX 498 ; N y.sc ; B 92 -3 556 460 ;
+C -1 ; WX 478 ; N z.sc ; B 5 -2 543 451 ;
+C -1 ; WX 444 ; N cent.oldstyle ; B 58 -83 490 532 ;
+C -1 ; WX 576 ; N agrave.sc ; B 22 -3 553 677 ;
+C -1 ; WX 576 ; N aacute.sc ; B 22 -3 553 677 ;
+C -1 ; WX 576 ; N acircumflex.sc ; B 22 -3 553 676 ;
+C -1 ; WX 576 ; N atilde.sc ; B 22 -3 569 645 ;
+C -1 ; WX 576 ; N adieresis.sc ; B 22 -3 553 642 ;
+C -1 ; WX 576 ; N aring.sc ; B 22 -3 553 692 ;
+C -1 ; WX 682 ; N ae.sc ; B 4 -3 726 452 ;
+C -1 ; WX 520 ; N ccedilla.sc ; B 60 -225 567 462 ;
+C -1 ; WX 449 ; N egrave.sc ; B 35 -3 491 677 ;
+C -1 ; WX 449 ; N eacute.sc ; B 35 -3 491 677 ;
+C -1 ; WX 449 ; N ecircumflex.sc ; B 35 -3 491 676 ;
+C -1 ; WX 449 ; N edieresis.sc ; B 35 -3 491 642 ;
+C -1 ; WX 266 ; N igrave.sc ; B 27 -3 319 677 ;
+C -1 ; WX 266 ; N iacute.sc ; B 27 -3 383 677 ;
+C -1 ; WX 266 ; N icircumflex.sc ; B 27 -3 380 676 ;
+C -1 ; WX 266 ; N idieresis.sc ; B 27 -3 388 642 ;
+C -1 ; WX 576 ; N eth.sc ; B 52 -2 598 451 ;
+C -1 ; WX 613 ; N ntilde.sc ; B 23 -14 668 645 ;
+C -1 ; WX 587 ; N ograve.sc ; B 60 -13 608 677 ;
+C -1 ; WX 587 ; N oacute.sc ; B 60 -13 608 677 ;
+C -1 ; WX 587 ; N ocircumflex.sc ; B 60 -13 608 676 ;
+C -1 ; WX 587 ; N otilde.sc ; B 60 -13 608 645 ;
+C -1 ; WX 587 ; N odieresis.sc ; B 60 -13 608 642 ;
+C -1 ; WX 617 ; N oslash.sc ; B 30 -13 659 464 ;
+C -1 ; WX 576 ; N ugrave.sc ; B 95 -13 630 677 ;
+C -1 ; WX 576 ; N uacute.sc ; B 95 -13 630 677 ;
+C -1 ; WX 576 ; N ucircumflex.sc ; B 95 -13 630 676 ;
+C -1 ; WX 576 ; N udieresis.sc ; B 95 -13 630 642 ;
+C -1 ; WX 498 ; N yacute.sc ; B 92 -3 556 677 ;
+C -1 ; WX 457 ; N thorn.sc ; B 34 -3 472 452 ;
+C -1 ; WX 498 ; N ydieresis.sc ; B 92 -3 556 642 ;
+C -1 ; WX 623 ; N ff ; B 22 -3 757 728 ; L l ffl ; L i ffi ;
+C -1 ; WX 605 ; N fi ; B 22 -3 625 728 ;
+C -1 ; WX 608 ; N fl ; B 22 -3 633 728 ;
+C -1 ; WX 897 ; N ffi ; B 22 -3 914 728 ;
+C -1 ; WX 900 ; N ffl ; B 22 -3 923 728 ;
+C -1 ; WX 333 ; N acute.dup ; B 167 506 416 677 ;
+C -1 ; WX 944 ; N AE.dup ; B -11 -3 1013 692 ;
+C -1 ; WX 758 ; N ae.dup ; B 46 -20 785 469 ;
+C -1 ; WX 333 ; N cedilla.dup ; B 59 -225 281 10 ;
+C -1 ; WX 333 ; N circumflex.dup ; B 101 509 413 676 ;
+C -1 ; WX 333 ; N dieresis.dup ; B 120 542 421 642 ;
+C -1 ; WX 379 ; N l.script.dup ; B 69 -20 429 712 ;
+C -1 ; WX 763 ; N Gcedilla ; B 75 -271 810 709 ;
+C -1 ; WX 556 ; N gcedilla ; B 6 -283 618 709 ;
+C -1 ; WX 556 ; N germandbls.dup ; B 22 -9 603 731 ;
+C -1 ; WX 333 ; N hyphen.dup ; B 56 215 362 287 ;
+C -1 ; WX 726 ; N Kcedilla ; B 21 -271 814 692 ;
+C -1 ; WX 556 ; N kcedilla ; B 20 -271 592 726 ;
+C -1 ; WX 611 ; N Lcedilla ; B 64 -271 616 692 ;
+C -1 ; WX 291 ; N lcedilla ; B 3 -271 315 726 ;
+C -1 ; WX 333 ; N macron.dup ; B 111 566 432 619 ;
+C -1 ; WX 831 ; N Ncedilla ; B 16 -271 935 692 ;
+C -1 ; WX 582 ; N ncedilla ; B 5 -271 577 469 ;
+C -1 ; WX 998 ; N OE.dup ; B 75 -20 1067 709 ;
+C -1 ; WX 827 ; N oe.dup ; B 67 -20 853 469 ;
+C -1 ; WX 833 ; N Oslash.dup ; B 32 -20 917 709 ;
+C -1 ; WX 556 ; N oslash.dup ; B 16 -23 609 474 ;
+C -1 ; WX 278 ; N quoteleft.dup ; B 126 446 356 709 ;
+C -1 ; WX 278 ; N quoteright.dup ; B 125 446 356 709 ;
+C -1 ; WX 668 ; N Rcedilla ; B 21 -271 675 692 ;
+C -1 ; WX 395 ; N rcedilla ; B 11 -271 455 469 ;
+C -1 ; WX 333 ; N tilde.dup ; B 97 540 446 645 ;
+C -1 ; WX 614 ; N hdotbelow.sc ; B 27 -193 666 452 ;
+C -1 ; WX 264 ; N jcaron.sc ; B -19 -124 406 676 ;
+C -1 ; WX 449 ; N ldotbelow.sc ; B 57 -193 453 452 ;
+C -1 ; WX 449 ; N ldotbelowmacron.sc ; B 57 -193 453 622 ;
+C -1 ; WX 694 ; N mdotbelow.sc ; B 23 -193 743 452 ;
+C -1 ; WX 613 ; N ndotaccent.sc ; B 23 -14 668 642 ;
+C -1 ; WX 613 ; N ndotbelow.sc ; B 23 -193 668 452 ;
+C -1 ; WX 499 ; N rdotbelow.sc ; B 27 -193 492 452 ;
+C -1 ; WX 499 ; N rdotbelowmacron.sc ; B 27 -193 502 622 ;
+C -1 ; WX 300 ; N zero.superior ; B 92 265 375 690 ;
+C -1 ; WX 300 ; N four.superior ; B 70 270 363 689 ;
+C -1 ; WX 300 ; N five.superior ; B 68 265 383 690 ;
+C -1 ; WX 300 ; N six.superior ; B 89 265 370 690 ;
+C -1 ; WX 300 ; N seven.superior ; B 82 275 420 690 ;
+C -1 ; WX 300 ; N eight.superior ; B 82 265 370 690 ;
+C -1 ; WX 300 ; N nine.superior ; B 86 265 372 690 ;
+C -1 ; WX 193 ; N exclam.superior ; B 103 270 263 683 ;
+C -1 ; WX 261 ; N quotedbl.superior ; B 142 493 348 692 ;
+C -1 ; WX 375 ; N numbersign.superior ; B 72 273 471 679 ;
+C -1 ; WX 354 ; N dollar.superior ; B 70 204 414 707 ;
+C -1 ; WX 570 ; N percent.superior ; B 123 261 617 692 ;
+C -1 ; WX 533 ; N ampersand.superior ; B 90 261 603 680 ;
+C -1 ; WX 144 ; N quoteright.superior ; B 147 493 225 692 ;
+C -1 ; WX 219 ; N parenleft.superior ; B 104 136 320 701 ;
+C -1 ; WX 219 ; N parenright.superior ; B 44 136 265 701 ;
+C -1 ; WX 233 ; N asterisk.superior ; B 112 466 320 680 ;
+C -1 ; WX 376 ; N plus.superior ; B 92 265 431 580 ;
+C -1 ; WX 150 ; N comma.superior ; B 37 147 197 378 ;
+C -1 ; WX 199 ; N hyphen.superior ; B 78 389 266 451 ;
+C -1 ; WX 176 ; N period.superior ; B 95 270 194 367 ;
+C -1 ; WX 399 ; N slash.superior ; B 85 193 472 701 ;
+C -1 ; WX 176 ; N colon.superior ; B 94 270 224 542 ;
+C -1 ; WX 175 ; N semicolon.superior ; B 40 167 242 556 ;
+C -1 ; WX 382 ; N less.superior ; B 111 269 436 571 ;
+C -1 ; WX 363 ; N equal.superior ; B 84 345 427 495 ;
+C -1 ; WX 382 ; N greater.superior ; B 90 277 412 564 ;
+C -1 ; WX 328 ; N question.superior ; B 128 270 406 683 ;
+C -1 ; WX 493 ; N at.superior ; B 94 261 575 683 ;
+C -1 ; WX 526 ; N A.superior ; B 56 271 567 687 ;
+C -1 ; WX 414 ; N B.superior ; B 86 271 478 682 ;
+C -1 ; WX 462 ; N C.superior ; B 93 261 551 692 ;
+C -1 ; WX 490 ; N D.superior ; B 82 271 570 682 ;
+C -1 ; WX 418 ; N E.superior ; B 68 271 504 682 ;
+C -1 ; WX 379 ; N F.superior ; B 61 271 489 682 ;
+C -1 ; WX 502 ; N G.superior ; B 94 261 576 692 ;
+C -1 ; WX 542 ; N H.superior ; B 61 271 650 682 ;
+C -1 ; WX 223 ; N I.superior ; B 61 271 331 682 ;
+C -1 ; WX 220 ; N J.superior ; B 19 145 328 682 ;
+C -1 ; WX 493 ; N K.superior ; B 61 271 565 682 ;
+C -1 ; WX 387 ; N L.superior ; B 86 271 442 682 ;
+C -1 ; WX 658 ; N M.superior ; B 57 265 763 682 ;
+C -1 ; WX 575 ; N N.superior ; B 58 269 686 682 ;
+C -1 ; WX 521 ; N O.superior ; B 93 261 599 692 ;
+C -1 ; WX 406 ; N P.superior ; B 61 271 498 682 ;
+C -1 ; WX 521 ; N Q.superior ; B 91 152 598 692 ;
+C -1 ; WX 470 ; N R.superior ; B 61 271 525 682 ;
+C -1 ; WX 355 ; N S.superior ; B 72 261 426 692 ;
+C -1 ; WX 414 ; N T.superior ; B 115 271 524 683 ;
+C -1 ; WX 506 ; N U.superior ; B 122 261 616 682 ;
+C -1 ; WX 483 ; N V.superior ; B 119 268 594 682 ;
+C -1 ; WX 697 ; N W.superior ; B 119 268 808 687 ;
+C -1 ; WX 443 ; N X.superior ; B 66 271 553 687 ;
+C -1 ; WX 456 ; N Y.superior ; B 117 270 564 695 ;
+C -1 ; WX 493 ; N Z.superior ; B 56 271 592 682 ;
+C -1 ; WX 218 ; N bracketleft.superior ; B 78 157 315 707 ;
+C -1 ; WX 406 ; N backslash.superior ; B 172 273 399 701 ;
+C -1 ; WX 219 ; N bracketright.superior ; B 55 155 295 709 ;
+C -1 ; WX 423 ; N asciicircum.superior ; B 106 431 470 680 ;
+C -1 ; WX 299 ; N underscore.superior ; B 33 191 341 235 ;
+C -1 ; WX 199 ; N quoteleft.superior ; B 133 550 251 693 ;
+C -1 ; WX 338 ; N a.superior ; B 76 266 375 550 ;
+C -1 ; WX 370 ; N b.superior ; B 83 266 423 701 ;
+C -1 ; WX 297 ; N c.superior ; B 82 261 372 550 ;
+C -1 ; WX 399 ; N d.superior ; B 90 266 462 709 ;
+C -1 ; WX 329 ; N e.superior ; B 82 261 390 550 ;
+C -1 ; WX 219 ; N f.superior ; B 61 271 347 702 ;
+C -1 ; WX 406 ; N g.superior ; B 52 106 490 550 ;
+C -1 ; WX 388 ; N h.superior ; B 51 271 436 701 ;
+C -1 ; WX 198 ; N i.superior ; B 60 271 251 652 ;
+C -1 ; WX 163 ; N j.superior ; B -5 92 234 664 ;
+C -1 ; WX 384 ; N k.superior ; B 60 266 447 706 ;
+C -1 ; WX 194 ; N l.superior ; B 60 271 255 701 ;
+C -1 ; WX 587 ; N m.superior ; B 57 271 633 550 ;
+C -1 ; WX 388 ; N n.superior ; B 51 271 436 550 ;
+C -1 ; WX 369 ; N o.superior ; B 87 261 427 550 ;
+C -1 ; WX 399 ; N p.superior ; B 23 107 446 550 ;
+C -1 ; WX 374 ; N q.superior ; B 86 107 434 550 ;
+C -1 ; WX 256 ; N r.superior ; B 60 271 340 550 ;
+C -1 ; WX 287 ; N s.superior ; B 67 261 335 550 ;
+C -1 ; WX 215 ; N t.superior ; B 99 266 307 645 ;
+C -1 ; WX 393 ; N u.superior ; B 102 266 440 566 ;
+C -1 ; WX 387 ; N v.superior ; B 94 269 468 544 ;
+C -1 ; WX 587 ; N w.superior ; B 93 269 668 550 ;
+C -1 ; WX 357 ; N x.superior ; B 66 270 423 549 ;
+C -1 ; WX 377 ; N y.superior ; B 39 106 467 544 ;
+C -1 ; WX 373 ; N z.superior ; B 60 270 450 547 ;
+C -1 ; WX 216 ; N braceleft.superior ; B 110 169 318 701 ;
+C -1 ; WX 376 ; N bar.superior ; B 191 155 336 701 ;
+C -1 ; WX 216 ; N braceright.superior ; B 52 169 261 701 ;
+C -1 ; WX 397 ; N asciitilde.superior ; B 100 373 450 490 ;
+C -1 ; WX 193 ; N exclamdown.superior ; B 70 113 235 555 ;
+C -1 ; WX 329 ; N eacute.superior ; B 82 261 390 673 ;
+C -1 ; WX 329 ; N egrave.superior ; B 82 261 390 673 ;
+C -1 ; WX 1116 ; N T_h ; B 119 -3 1111 726 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 12430
+KPX comma quotedblright -25
+KPX comma quoteright -20
+KPX hyphen ydieresis.sc -95
+KPX hyphen ae.sc -35
+KPX hyphen aring.sc -40
+KPX hyphen adieresis.sc -40
+KPX hyphen y.sc -95
+KPX hyphen w.sc -35
+KPX hyphen v.sc -65
+KPX hyphen t.sc -80
+KPX hyphen a.sc -40
+KPX hyphen ycircumflex.sc -95
+KPX hyphen wgrave.sc -35
+KPX hyphen wdieresis.sc -35
+KPX hyphen wcircumflex.sc -35
+KPX hyphen wacute.sc -35
+KPX hyphen uni021B.sc -80
+KPX hyphen tcaron.sc -80
+KPX hyphen aeacute.sc -35
+KPX hyphen aogonek.sc -40
+KPX hyphen amacron.sc -40
+KPX hyphen Wdieresis -35
+KPX hyphen Wacute -35
+KPX hyphen Wgrave -35
+KPX hyphen uni021A -80
+KPX hyphen AEacute -35
+KPX hyphen Ydieresis -95
+KPX hyphen Ycircumflex -95
+KPX hyphen Wcircumflex -35
+KPX hyphen Tcaron -80
+KPX hyphen Aogonek -40
+KPX hyphen Amacron -40
+KPX hyphen AE -35
+KPX hyphen Aring -40
+KPX hyphen Adieresis -40
+KPX hyphen Y -95
+KPX hyphen W -35
+KPX hyphen V -65
+KPX hyphen T -80
+KPX hyphen A -40
+KPX hyphen T_h -80
+KPX period quotedblright -45
+KPX period quoteright -40
+KPX A ydieresis.sc -75
+KPX A udieresis.sc -60
+KPX A ucircumflex.sc -60
+KPX A oslash.sc -60
+KPX A odieresis.sc -60
+KPX A ograve.sc -60
+KPX A ccedilla.sc -60
+KPX A y.sc -75
+KPX A w.sc -85
+KPX A v.sc -115
+KPX A u.sc -60
+KPX A t.sc -60
+KPX A q.sc -55
+KPX A o.sc -60
+KPX A g.sc -60
+KPX A c.sc -60
+KPX A ycircumflex.sc -75
+KPX A wgrave.sc -85
+KPX A wdieresis.sc -85
+KPX A wcircumflex.sc -85
+KPX A wacute.sc -85
+KPX A uring.sc -60
+KPX A uogonek.sc -60
+KPX A umacron.sc -60
+KPX A uhungarumlaut.sc -60
+KPX A ubreve.sc -60
+KPX A uni021B.sc -60
+KPX A tcaron.sc -60
+KPX A omacron.sc -60
+KPX A ohungarumlaut.sc -60
+KPX A obreve.sc -60
+KPX A gdotaccent.sc -60
+KPX A gcommaaccent.sc -60
+KPX A gcircumflex.sc -60
+KPX A gbreve.sc -60
+KPX A cdotaccent.sc -60
+KPX A ccircumflex.sc -60
+KPX A ccaron.sc -60
+KPX A cacute.sc -60
+KPX A oogonek.sc -60
+KPX A gcaron.sc -60
+KPX A gacute.sc -60
+KPX A guilsinglleft -90
+KPX A quotedblright -125
+KPX A quoteright -120
+KPX A wdieresis -80
+KPX A Wdieresis -100
+KPX A wacute -80
+KPX A Wacute -100
+KPX A wgrave -80
+KPX A Wgrave -100
+KPX A ringhalfleft -130
+KPX A ringhalfright -130
+KPX A uni021B -40
+KPX A uni021A -70
+KPX A gacute -25
+KPX A Gacute -70
+KPX A oogonek -35
+KPX A Oogonek -70
+KPX A gcaron -25
+KPX A Gcaron -70
+KPX A Ydieresis -90
+KPX A ycircumflex -90
+KPX A Ycircumflex -90
+KPX A wcircumflex -80
+KPX A Wcircumflex -100
+KPX A uogonek -45
+KPX A Uogonek -75
+KPX A uhungarumlaut -45
+KPX A Uhungarumlaut -75
+KPX A uring -45
+KPX A Uring -75
+KPX A ubreve -45
+KPX A Ubreve -75
+KPX A umacron -45
+KPX A Umacron -75
+KPX A tcaron -40
+KPX A Tcaron -70
+KPX A ohungarumlaut -35
+KPX A Ohungarumlaut -70
+KPX A obreve -35
+KPX A Obreve -70
+KPX A omacron -35
+KPX A Omacron -70
+KPX A gcommaaccent -25
+KPX A Gcommaaccent -70
+KPX A gdotaccent -25
+KPX A Gdotaccent -70
+KPX A gbreve -25
+KPX A Gbreve -70
+KPX A gcircumflex -25
+KPX A Gcircumflex -70
+KPX A ecaron -30
+KPX A eogonek -30
+KPX A edotaccent -30
+KPX A ebreve -30
+KPX A emacron -30
+KPX A dcaron -35
+KPX A ccaron -35
+KPX A Ccaron -70
+KPX A cdotaccent -35
+KPX A Cdotaccent -70
+KPX A ccircumflex -35
+KPX A Ccircumflex -70
+KPX A cacute -35
+KPX A Cacute -70
+KPX A ydieresis -90
+KPX A udieresis -45
+KPX A ucircumflex -45
+KPX A oslash -35
+KPX A odieresis -35
+KPX A ograve -35
+KPX A edieresis -30
+KPX A ccedilla -35
+KPX A Udieresis -75
+KPX A Ucircumflex -75
+KPX A Oslash -70
+KPX A Odieresis -70
+KPX A Ograve -70
+KPX A Ccedilla -70
+KPX A guillemotleft -85
+KPX A y -90
+KPX A w -80
+KPX A v -85
+KPX A u -45
+KPX A t -40
+KPX A q -35
+KPX A o -35
+KPX A g -25
+KPX A e -30
+KPX A d -35
+KPX A c -35
+KPX A b -15
+KPX A Y -90
+KPX A W -100
+KPX A V -140
+KPX A U -75
+KPX A T -70
+KPX A Q -65
+KPX A O -70
+KPX A G -70
+KPX A C -70
+KPX A period -25
+KPX A hyphen -35
+KPX A comma -35
+KPX A T_h -70
+KPX B ydieresis.sc -30
+KPX B ae.sc -35
+KPX B aring.sc -40
+KPX B adieresis.sc -40
+KPX B atilde.sc -40
+KPX B acircumflex.sc -40
+KPX B aacute.sc -40
+KPX B agrave.sc -40
+KPX B y.sc -30
+KPX B w.sc -30
+KPX B v.sc -30
+KPX B a.sc -40
+KPX B ycircumflex.sc -30
+KPX B wgrave.sc -30
+KPX B wdieresis.sc -30
+KPX B wcircumflex.sc -30
+KPX B wacute.sc -30
+KPX B aeacute.sc -35
+KPX B aogonek.sc -40
+KPX B amacron.sc -40
+KPX B abreve.sc -40
+KPX B ahookabove.sc -40
+KPX B adotbelow.sc -40
+KPX B acircumflextilde.sc -40
+KPX B acircumflexhookabove.sc -40
+KPX B acircumflexgrave.sc -40
+KPX B acircumflexdotbelow.sc -40
+KPX B acircumflexacute.sc -40
+KPX B abrevetilde.sc -40
+KPX B abrevehookabove.sc -40
+KPX B abrevegrave.sc -40
+KPX B abrevedotbelow.sc -40
+KPX B abreveacute.sc -40
+KPX B Abrevedotbelow -50
+KPX B Abrevetilde -50
+KPX B Abrevehookabove -50
+KPX B Abrevegrave -50
+KPX B Abreveacute -50
+KPX B Acircumflexdotbelow -50
+KPX B Acircumflextilde -50
+KPX B Acircumflexhookabove -50
+KPX B Acircumflexgrave -50
+KPX B Acircumflexacute -50
+KPX B Ahookabove -50
+KPX B Adotbelow -50
+KPX B Wdieresis -35
+KPX B Wacute -35
+KPX B Wgrave -35
+KPX B AEacute -40
+KPX B Ydieresis -35
+KPX B Ycircumflex -35
+KPX B Wcircumflex -35
+KPX B Aogonek -50
+KPX B Abreve -50
+KPX B Amacron -50
+KPX B AE -40
+KPX B Aring -50
+KPX B Adieresis -50
+KPX B Atilde -50
+KPX B Acircumflex -50
+KPX B Aacute -50
+KPX B Agrave -50
+KPX B Y -35
+KPX B W -35
+KPX B V -35
+KPX B A -50
+KPX C oslash.sc -35
+KPX C odieresis.sc -35
+KPX C otilde.sc -35
+KPX C ocircumflex.sc -35
+KPX C oacute.sc -35
+KPX C ograve.sc -35
+KPX C aring.sc -10
+KPX C adieresis.sc -10
+KPX C atilde.sc -10
+KPX C acircumflex.sc -10
+KPX C aacute.sc -10
+KPX C agrave.sc -10
+KPX C o.sc -35
+KPX C k.sc -10
+KPX C h.sc -10
+KPX C a.sc -10
+KPX C omacron.sc -35
+KPX C ohungarumlaut.sc -35
+KPX C obreve.sc -35
+KPX C kcommaaccent.sc -10
+KPX C hcircumflex.sc -10
+KPX C aogonek.sc -10
+KPX C amacron.sc -10
+KPX C abreve.sc -10
+KPX C oogonek.sc -35
+KPX C ohorntilde.sc -35
+KPX C ohornhookabove.sc -35
+KPX C ohorngrave.sc -35
+KPX C ohorndotbelow.sc -35
+KPX C ohornacute.sc -35
+KPX C ohookabove.sc -35
+KPX C odotbelow.sc -35
+KPX C ocircumflextilde.sc -35
+KPX C ocircumflexhookabove.sc -35
+KPX C ocircumflexgrave.sc -35
+KPX C ocircumflexdotbelow.sc -35
+KPX C ocircumflexacute.sc -35
+KPX C ahookabove.sc -10
+KPX C adotbelow.sc -10
+KPX C acircumflextilde.sc -10
+KPX C acircumflexhookabove.sc -10
+KPX C acircumflexgrave.sc -10
+KPX C acircumflexdotbelow.sc -10
+KPX C acircumflexacute.sc -10
+KPX C abrevetilde.sc -10
+KPX C abrevehookabove.sc -10
+KPX C abrevegrave.sc -10
+KPX C abrevedotbelow.sc -10
+KPX C abreveacute.sc -10
+KPX C Ohorndotbelow -40
+KPX C Ohorntilde -40
+KPX C Ohornhookabove -40
+KPX C Ohorngrave -40
+KPX C Ohornacute -40
+KPX C Ocircumflexdotbelow -40
+KPX C Ocircumflextilde -40
+KPX C Ocircumflexhookabove -40
+KPX C Ocircumflexgrave -40
+KPX C Ocircumflexacute -40
+KPX C Ohookabove -40
+KPX C Odotbelow -40
+KPX C Abrevedotbelow -15
+KPX C Abrevetilde -15
+KPX C Abrevehookabove -15
+KPX C Abrevegrave -15
+KPX C Abreveacute -15
+KPX C Acircumflexdotbelow -15
+KPX C Acircumflextilde -15
+KPX C Acircumflexhookabove -15
+KPX C Acircumflexgrave -15
+KPX C Acircumflexacute -15
+KPX C Ahookabove -15
+KPX C Adotbelow -15
+KPX C Oogonek -40
+KPX C Ohungarumlaut -40
+KPX C Obreve -40
+KPX C Omacron -40
+KPX C Kcommaaccent -10
+KPX C Hcircumflex -10
+KPX C Aogonek -15
+KPX C Abreve -15
+KPX C Amacron -15
+KPX C Oslash -40
+KPX C Odieresis -40
+KPX C Otilde -40
+KPX C Ocircumflex -40
+KPX C Oacute -40
+KPX C Ograve -40
+KPX C Aring -15
+KPX C Adieresis -15
+KPX C Atilde -15
+KPX C Acircumflex -15
+KPX C Aacute -15
+KPX C Agrave -15
+KPX C O -40
+KPX C K -10
+KPX C H -10
+KPX C A -15
+KPX D ydieresis.sc -45
+KPX D aring.sc -65
+KPX D adieresis.sc -65
+KPX D atilde.sc -65
+KPX D acircumflex.sc -65
+KPX D aacute.sc -65
+KPX D agrave.sc -65
+KPX D y.sc -45
+KPX D x.sc -50
+KPX D w.sc -35
+KPX D v.sc -50
+KPX D t.sc -10
+KPX D j.sc -25
+KPX D a.sc -65
+KPX D ycircumflex.sc -45
+KPX D wgrave.sc -35
+KPX D wdieresis.sc -35
+KPX D wcircumflex.sc -35
+KPX D wacute.sc -35
+KPX D uni021B.sc -10
+KPX D tcaron.sc -10
+KPX D jcircumflex.sc -25
+KPX D aogonek.sc -65
+KPX D amacron.sc -65
+KPX D abreve.sc -65
+KPX D Jacute -30
+KPX D jacute.sc -25
+KPX D ahookabove.sc -65
+KPX D adotbelow.sc -65
+KPX D acircumflextilde.sc -65
+KPX D acircumflexhookabove.sc -65
+KPX D acircumflexgrave.sc -65
+KPX D acircumflexdotbelow.sc -65
+KPX D acircumflexacute.sc -65
+KPX D abrevehookabove.sc -65
+KPX D abrevegrave.sc -65
+KPX D abrevedotbelow.sc -65
+KPX D abreveacute.sc -65
+KPX D Abrevedotbelow -80
+KPX D Abrevehookabove -80
+KPX D Abrevegrave -80
+KPX D Abreveacute -80
+KPX D Acircumflexdotbelow -80
+KPX D Acircumflextilde -80
+KPX D Acircumflexhookabove -80
+KPX D Acircumflexgrave -80
+KPX D Acircumflexacute -80
+KPX D Ahookabove -80
+KPX D Adotbelow -80
+KPX D Wdieresis -45
+KPX D Wacute -45
+KPX D Wgrave -45
+KPX D uni021A -15
+KPX D Ydieresis -55
+KPX D Ycircumflex -55
+KPX D Wcircumflex -45
+KPX D Tcaron -15
+KPX D Jcircumflex -30
+KPX D Aogonek -80
+KPX D Abreve -80
+KPX D Amacron -80
+KPX D Aring -80
+KPX D Adieresis -80
+KPX D Atilde -80
+KPX D Acircumflex -80
+KPX D Aacute -80
+KPX D Agrave -80
+KPX D Y -55
+KPX D X -60
+KPX D W -45
+KPX D V -60
+KPX D T -15
+KPX D J -30
+KPX D A -80
+KPX D T_h -15
+KPX F oslash.sc -15
+KPX F odieresis.sc -10
+KPX F otilde.sc -10
+KPX F ocircumflex.sc -10
+KPX F oacute.sc -10
+KPX F ograve.sc -10
+KPX F ae.sc -30
+KPX F aring.sc -40
+KPX F adieresis.sc -40
+KPX F atilde.sc -40
+KPX F acircumflex.sc -40
+KPX F aacute.sc -60
+KPX F agrave.sc -40
+KPX F o.sc -15
+KPX F a.sc -80
+KPX F omacron.sc -10
+KPX F ohungarumlaut.sc -10
+KPX F obreve.sc -10
+KPX F aeacute.sc -30
+KPX F aogonek.sc -80
+KPX F amacron.sc -40
+KPX F abreve.sc -40
+KPX F oogonek.sc -15
+KPX F ohorntilde.sc -10
+KPX F ohornhookabove.sc -10
+KPX F ohorngrave.sc -10
+KPX F ohorndotbelow.sc -10
+KPX F ohornacute.sc -10
+KPX F ohookabove.sc -10
+KPX F oe.sc -20
+KPX F ocircumflexdotbelow.sc -10
+KPX F ahookabove.sc -40
+KPX F acircumflexdotbelow.sc -40
+KPX F abrevedotbelow.sc -40
+KPX F uhorndotbelow -10
+KPX F uhorntilde -10
+KPX F uhornhookabove -10
+KPX F uhorngrave -10
+KPX F uhornacute -10
+KPX F uhookabove -10
+KPX F ohorndotbelow -15
+KPX F ohorntilde -15
+KPX F ohornhookabove -15
+KPX F ohorngrave -15
+KPX F ohornacute -15
+KPX F ocircumflexdotbelow -15
+KPX F ohookabove -15
+KPX F ihookabove -10
+KPX F ecircumflexdotbelow -15
+KPX F etilde -15
+KPX F ehookabove -15
+KPX F abrevedotbelow -20
+KPX F acircumflexdotbelow -20
+KPX F ahookabove -20
+KPX F rdotaccent -10
+KPX F aeacute -40
+KPX F AEacute -40
+KPX F oogonek -25
+KPX F Oogonek -20
+KPX F uogonek -20
+KPX F uhungarumlaut -10
+KPX F uring -10
+KPX F ubreve -10
+KPX F umacron -10
+KPX F utilde -10
+KPX F rcaron -10
+KPX F rcommaaccent -20
+KPX F racute -15
+KPX F oe -25
+KPX F OE -25
+KPX F ohungarumlaut -15
+KPX F Ohungarumlaut -20
+KPX F obreve -15
+KPX F Obreve -20
+KPX F omacron -15
+KPX F Omacron -20
+KPX F iogonek -20
+KPX F ibreve -10
+KPX F imacron -10
+KPX F itilde -10
+KPX F ecaron -15
+KPX F eogonek -25
+KPX F edotaccent -15
+KPX F ebreve -15
+KPX F emacron -15
+KPX F aogonek -40
+KPX F Aogonek -95
+KPX F abreve -20
+KPX F amacron -20
+KPX F Amacron -95
+KPX F udieresis -10
+KPX F ucircumflex -10
+KPX F uacute -15
+KPX F ugrave -10
+KPX F oslash -25
+KPX F odieresis -15
+KPX F otilde -15
+KPX F ocircumflex -15
+KPX F oacute -20
+KPX F ograve -15
+KPX F idieresis -10
+KPX F icircumflex -10
+KPX F iacute -15
+KPX F igrave -10
+KPX F edieresis -15
+KPX F ecircumflex -15
+KPX F eacute -20
+KPX F egrave -15
+KPX F ae -40
+KPX F aring -20
+KPX F adieresis -20
+KPX F atilde -20
+KPX F acircumflex -20
+KPX F aacute -30
+KPX F agrave -20
+KPX F Oslash -20
+KPX F Odieresis -20
+KPX F AE -40
+KPX F Aring -95
+KPX F Adieresis -95
+KPX F u -20
+KPX F r -20
+KPX F o -25
+KPX F i -20
+KPX F e -25
+KPX F a -40
+KPX F O -20
+KPX F A -95
+KPX F period -65
+KPX F comma -80
+KPX G ydieresis.sc -15
+KPX G aring.sc -20
+KPX G adieresis.sc -20
+KPX G atilde.sc -20
+KPX G acircumflex.sc -20
+KPX G aacute.sc -20
+KPX G agrave.sc -20
+KPX G y.sc -15
+KPX G w.sc -10
+KPX G v.sc -10
+KPX G t.sc -20
+KPX G a.sc -20
+KPX G ycircumflex.sc -15
+KPX G wgrave.sc -10
+KPX G wdieresis.sc -10
+KPX G wcircumflex.sc -10
+KPX G wacute.sc -10
+KPX G uni021B.sc -20
+KPX G tcaron.sc -20
+KPX G aogonek.sc -20
+KPX G amacron.sc -20
+KPX G abreve.sc -20
+KPX G ahookabove.sc -20
+KPX G adotbelow.sc -20
+KPX G acircumflextilde.sc -20
+KPX G acircumflexhookabove.sc -20
+KPX G acircumflexgrave.sc -20
+KPX G acircumflexdotbelow.sc -20
+KPX G acircumflexacute.sc -20
+KPX G abrevetilde.sc -20
+KPX G abrevehookabove.sc -20
+KPX G abrevegrave.sc -20
+KPX G abrevedotbelow.sc -20
+KPX G abreveacute.sc -20
+KPX G Abrevedotbelow -25
+KPX G Abrevetilde -25
+KPX G Abrevehookabove -25
+KPX G Abrevegrave -25
+KPX G Abreveacute -25
+KPX G Acircumflexdotbelow -25
+KPX G Acircumflextilde -25
+KPX G Acircumflexhookabove -25
+KPX G Acircumflexgrave -25
+KPX G Acircumflexacute -25
+KPX G Ahookabove -25
+KPX G Adotbelow -25
+KPX G Wdieresis -15
+KPX G Wacute -15
+KPX G Wgrave -15
+KPX G uni021A -25
+KPX G Ydieresis -20
+KPX G Ycircumflex -20
+KPX G Wcircumflex -15
+KPX G Tcaron -25
+KPX G Aogonek -25
+KPX G Abreve -25
+KPX G Amacron -25
+KPX G Aring -25
+KPX G Adieresis -25
+KPX G Atilde -25
+KPX G Acircumflex -25
+KPX G Aacute -25
+KPX G Agrave -25
+KPX G Y -20
+KPX G W -15
+KPX G V -15
+KPX G T -25
+KPX G A -25
+KPX G T_h -25
+KPX J ae.sc -30
+KPX J aring.sc -40
+KPX J adieresis.sc -40
+KPX J a.sc -40
+KPX J aeacute.sc -30
+KPX J aogonek.sc -40
+KPX J amacron.sc -40
+KPX J AEacute -35
+KPX J Aogonek -50
+KPX J Amacron -50
+KPX J AE -35
+KPX J Aring -50
+KPX J Adieresis -50
+KPX J A -50
+KPX K oslash.sc -50
+KPX K odieresis.sc -50
+KPX K ccedilla.sc -55
+KPX K o.sc -50
+KPX K g.sc -55
+KPX K c.sc -55
+KPX K omacron.sc -50
+KPX K ohungarumlaut.sc -50
+KPX K obreve.sc -50
+KPX K gdotaccent.sc -55
+KPX K gcommaaccent.sc -55
+KPX K gcircumflex.sc -55
+KPX K gbreve.sc -55
+KPX K cdotaccent.sc -55
+KPX K ccircumflex.sc -55
+KPX K ccaron.sc -55
+KPX K cacute.sc -55
+KPX K oogonek.sc -50
+KPX K oe.sc -50
+KPX K gcaron.sc -55
+KPX K gacute.sc -55
+KPX K ytilde -90
+KPX K ydotbelow -90
+KPX K ygrave -90
+KPX K ecircumflexdotbelow -20
+KPX K ecircumflexhookabove -20
+KPX K ecircumflexgrave -20
+KPX K ecircumflexacute -20
+KPX K etilde -20
+KPX K ehookabove -20
+KPX K edotbelow -20
+KPX K Gacute -65
+KPX K oogonek -30
+KPX K Oogonek -60
+KPX K Gcaron -65
+KPX K ycircumflex -90
+KPX K uogonek -35
+KPX K uhungarumlaut -35
+KPX K uring -35
+KPX K ubreve -35
+KPX K umacron -35
+KPX K OE -60
+KPX K ohungarumlaut -30
+KPX K Ohungarumlaut -60
+KPX K obreve -30
+KPX K Obreve -60
+KPX K omacron -30
+KPX K Omacron -60
+KPX K Gcommaaccent -65
+KPX K Gdotaccent -65
+KPX K Gbreve -65
+KPX K Gcircumflex -65
+KPX K ecaron -20
+KPX K eogonek -20
+KPX K edotaccent -20
+KPX K ebreve -20
+KPX K emacron -20
+KPX K Ccaron -65
+KPX K Cdotaccent -65
+KPX K Ccircumflex -65
+KPX K Cacute -65
+KPX K ydieresis -90
+KPX K yacute -90
+KPX K udieresis -35
+KPX K ucircumflex -35
+KPX K oslash -30
+KPX K odieresis -30
+KPX K edieresis -20
+KPX K ecircumflex -20
+KPX K eacute -20
+KPX K egrave -20
+KPX K Oslash -60
+KPX K Odieresis -60
+KPX K Ccedilla -65
+KPX K y -90
+KPX K u -35
+KPX K o -30
+KPX K e -20
+KPX K O -60
+KPX K G -65
+KPX K C -65
+KPX K hyphen -75
+KPX L ydieresis.sc -85
+KPX L yacute.sc -85
+KPX L udieresis.sc -35
+KPX L ucircumflex.sc -35
+KPX L uacute.sc -35
+KPX L ugrave.sc -35
+KPX L oslash.sc -15
+KPX L odieresis.sc -15
+KPX L otilde.sc -15
+KPX L ocircumflex.sc -15
+KPX L oacute.sc -15
+KPX L ograve.sc -15
+KPX L ccedilla.sc -15
+KPX L y.sc -85
+KPX L w.sc -70
+KPX L v.sc -105
+KPX L u.sc -35
+KPX L t.sc -65
+KPX L o.sc -15
+KPX L g.sc -15
+KPX L c.sc -15
+KPX L ycircumflex.sc -85
+KPX L wgrave.sc -70
+KPX L wdieresis.sc -70
+KPX L wcircumflex.sc -70
+KPX L wacute.sc -70
+KPX L utilde.sc -35
+KPX L uring.sc -35
+KPX L uogonek.sc -35
+KPX L umacron.sc -35
+KPX L uhungarumlaut.sc -35
+KPX L ubreve.sc -35
+KPX L uni021B.sc -65
+KPX L tcaron.sc -65
+KPX L omacron.sc -15
+KPX L ohungarumlaut.sc -15
+KPX L obreve.sc -15
+KPX L gdotaccent.sc -15
+KPX L gcommaaccent.sc -15
+KPX L gcircumflex.sc -15
+KPX L gbreve.sc -15
+KPX L cdotaccent.sc -15
+KPX L ccircumflex.sc -15
+KPX L ccaron.sc -15
+KPX L cacute.sc -15
+KPX L uhorntilde.sc -35
+KPX L uhornhookabove.sc -35
+KPX L uhorngrave.sc -35
+KPX L uhorndotbelow.sc -35
+KPX L uhornacute.sc -35
+KPX L uhookabove.sc -35
+KPX L udotbelow.sc -35
+KPX L oogonek.sc -15
+KPX L ohorntilde.sc -15
+KPX L ohornhookabove.sc -15
+KPX L ohorngrave.sc -15
+KPX L ohorndotbelow.sc -15
+KPX L ohornacute.sc -15
+KPX L ohookabove.sc -15
+KPX L odotbelow.sc -15
+KPX L ocircumflextilde.sc -15
+KPX L ocircumflexhookabove.sc -15
+KPX L ocircumflexgrave.sc -15
+KPX L ocircumflexdotbelow.sc -15
+KPX L ocircumflexacute.sc -15
+KPX L gcaron.sc -15
+KPX L gacute.sc -15
+KPX L quotedblright -130
+KPX L quoteright -125
+KPX L uhorndotbelow -35
+KPX L Uhorndotbelow -45
+KPX L uhorntilde -35
+KPX L Uhorntilde -45
+KPX L uhornhookabove -35
+KPX L Uhornhookabove -45
+KPX L uhorngrave -35
+KPX L Uhorngrave -45
+KPX L uhornacute -35
+KPX L Uhornacute -45
+KPX L uhookabove -35
+KPX L Uhookabove -45
+KPX L udotbelow -35
+KPX L Udotbelow -45
+KPX L Ohorndotbelow -20
+KPX L Ohorntilde -20
+KPX L Ohornhookabove -20
+KPX L Ohorngrave -20
+KPX L Ohornacute -20
+KPX L Ocircumflexdotbelow -20
+KPX L Ocircumflextilde -20
+KPX L Ocircumflexhookabove -20
+KPX L Ocircumflexgrave -20
+KPX L Ocircumflexacute -20
+KPX L Ohookabove -20
+KPX L Odotbelow -20
+KPX L Wdieresis -85
+KPX L Wacute -85
+KPX L Wgrave -85
+KPX L uni021A -80
+KPX L Gacute -20
+KPX L Oogonek -20
+KPX L Gcaron -20
+KPX L Ydieresis -100
+KPX L ycircumflex -60
+KPX L Ycircumflex -100
+KPX L Wcircumflex -85
+KPX L uogonek -35
+KPX L Uogonek -45
+KPX L uhungarumlaut -35
+KPX L Uhungarumlaut -45
+KPX L uring -35
+KPX L Uring -45
+KPX L ubreve -35
+KPX L Ubreve -45
+KPX L umacron -35
+KPX L Umacron -45
+KPX L utilde -35
+KPX L Utilde -45
+KPX L Tcaron -80
+KPX L Ohungarumlaut -20
+KPX L Obreve -20
+KPX L Omacron -20
+KPX L Gcommaaccent -20
+KPX L Gdotaccent -20
+KPX L Gbreve -20
+KPX L Gcircumflex -20
+KPX L Ccaron -20
+KPX L Cdotaccent -20
+KPX L Ccircumflex -20
+KPX L Cacute -20
+KPX L ydieresis -60
+KPX L yacute -60
+KPX L udieresis -35
+KPX L ucircumflex -35
+KPX L uacute -35
+KPX L ugrave -35
+KPX L Yacute -100
+KPX L Udieresis -45
+KPX L Ucircumflex -45
+KPX L Uacute -45
+KPX L Ugrave -45
+KPX L Oslash -20
+KPX L Odieresis -20
+KPX L Otilde -20
+KPX L Ocircumflex -20
+KPX L Oacute -20
+KPX L Ograve -20
+KPX L Ccedilla -20
+KPX L y -60
+KPX L u -35
+KPX L Y -100
+KPX L W -85
+KPX L V -125
+KPX L U -45
+KPX L T -80
+KPX L O -20
+KPX L G -20
+KPX L C -20
+KPX L T_h -80
+KPX N oslash.sc -20
+KPX N odieresis.sc -20
+KPX N otilde.sc -20
+KPX N ocircumflex.sc -20
+KPX N oacute.sc -20
+KPX N ograve.sc -20
+KPX N ccedilla.sc -25
+KPX N ae.sc -25
+KPX N aring.sc -35
+KPX N adieresis.sc -35
+KPX N atilde.sc -35
+KPX N acircumflex.sc -35
+KPX N aacute.sc -35
+KPX N agrave.sc -35
+KPX N o.sc -20
+KPX N g.sc -25
+KPX N c.sc -25
+KPX N a.sc -35
+KPX N omacron.sc -20
+KPX N ohungarumlaut.sc -20
+KPX N obreve.sc -20
+KPX N gdotaccent.sc -25
+KPX N gcommaaccent.sc -25
+KPX N gcircumflex.sc -25
+KPX N gbreve.sc -25
+KPX N cdotaccent.sc -25
+KPX N ccircumflex.sc -25
+KPX N ccaron.sc -25
+KPX N cacute.sc -25
+KPX N aeacute.sc -25
+KPX N aogonek.sc -35
+KPX N amacron.sc -35
+KPX N abreve.sc -35
+KPX N oogonek.sc -20
+KPX N ohorntilde.sc -20
+KPX N ohornhookabove.sc -20
+KPX N ohorngrave.sc -20
+KPX N ohorndotbelow.sc -20
+KPX N ohornacute.sc -20
+KPX N ohookabove.sc -20
+KPX N odotbelow.sc -20
+KPX N ocircumflextilde.sc -20
+KPX N ocircumflexhookabove.sc -20
+KPX N ocircumflexgrave.sc -20
+KPX N ocircumflexdotbelow.sc -20
+KPX N ocircumflexacute.sc -20
+KPX N gcaron.sc -25
+KPX N gacute.sc -25
+KPX N ahookabove.sc -35
+KPX N adotbelow.sc -35
+KPX N acircumflextilde.sc -35
+KPX N acircumflexhookabove.sc -35
+KPX N acircumflexgrave.sc -35
+KPX N acircumflexdotbelow.sc -35
+KPX N acircumflexacute.sc -35
+KPX N abrevegrave.sc -35
+KPX N abrevedotbelow.sc -35
+KPX N abreveacute.sc -35
+KPX N uhorndotbelow -40
+KPX N uhorntilde -40
+KPX N uhornhookabove -40
+KPX N uhorngrave -40
+KPX N uhornacute -40
+KPX N uhookabove -40
+KPX N udotbelow -40
+KPX N ohorndotbelow -30
+KPX N Ohorndotbelow -25
+KPX N ohorntilde -30
+KPX N Ohorntilde -25
+KPX N ohornhookabove -30
+KPX N Ohornhookabove -25
+KPX N ohorngrave -30
+KPX N Ohorngrave -25
+KPX N ohornacute -30
+KPX N Ohornacute -25
+KPX N ocircumflexdotbelow -30
+KPX N Ocircumflexdotbelow -25
+KPX N ocircumflextilde -30
+KPX N Ocircumflextilde -25
+KPX N ocircumflexhookabove -30
+KPX N Ocircumflexhookabove -25
+KPX N ocircumflexgrave -30
+KPX N Ocircumflexgrave -25
+KPX N ocircumflexacute -30
+KPX N Ocircumflexacute -25
+KPX N ohookabove -30
+KPX N Ohookabove -25
+KPX N odotbelow -30
+KPX N Odotbelow -25
+KPX N ecircumflexdotbelow -25
+KPX N ecircumflexhookabove -25
+KPX N ecircumflexgrave -25
+KPX N ecircumflexacute -25
+KPX N ehookabove -25
+KPX N edotbelow -25
+KPX N abrevedotbelow -30
+KPX N Abrevedotbelow -40
+KPX N abrevegrave -30
+KPX N Abrevegrave -40
+KPX N abreveacute -30
+KPX N Abreveacute -40
+KPX N acircumflexdotbelow -30
+KPX N Acircumflexdotbelow -40
+KPX N acircumflextilde -30
+KPX N Acircumflextilde -40
+KPX N acircumflexhookabove -30
+KPX N Acircumflexhookabove -40
+KPX N acircumflexgrave -30
+KPX N Acircumflexgrave -40
+KPX N acircumflexacute -30
+KPX N Acircumflexacute -40
+KPX N ahookabove -30
+KPX N Ahookabove -40
+KPX N adotbelow -30
+KPX N Adotbelow -40
+KPX N aeacute -35
+KPX N AEacute -30
+KPX N Gacute -30
+KPX N oogonek -30
+KPX N Oogonek -25
+KPX N Gcaron -30
+KPX N uogonek -40
+KPX N uhungarumlaut -40
+KPX N uring -40
+KPX N ubreve -40
+KPX N umacron -40
+KPX N utilde -40
+KPX N ohungarumlaut -30
+KPX N Ohungarumlaut -25
+KPX N obreve -30
+KPX N Obreve -25
+KPX N omacron -30
+KPX N Omacron -25
+KPX N Gcommaaccent -30
+KPX N Gdotaccent -30
+KPX N Gbreve -30
+KPX N Gcircumflex -30
+KPX N ecaron -25
+KPX N eogonek -25
+KPX N edotaccent -25
+KPX N ebreve -25
+KPX N emacron -25
+KPX N Ccaron -30
+KPX N Cdotaccent -30
+KPX N Ccircumflex -30
+KPX N Cacute -30
+KPX N aogonek -30
+KPX N Aogonek -40
+KPX N abreve -30
+KPX N Abreve -40
+KPX N amacron -30
+KPX N Amacron -40
+KPX N udieresis -40
+KPX N ucircumflex -40
+KPX N uacute -40
+KPX N ugrave -40
+KPX N oslash -30
+KPX N odieresis -30
+KPX N otilde -30
+KPX N ocircumflex -30
+KPX N oacute -30
+KPX N ograve -30
+KPX N edieresis -25
+KPX N ecircumflex -25
+KPX N eacute -25
+KPX N egrave -25
+KPX N ae -35
+KPX N aring -30
+KPX N adieresis -30
+KPX N atilde -30
+KPX N acircumflex -30
+KPX N aacute -30
+KPX N agrave -30
+KPX N Oslash -25
+KPX N Odieresis -25
+KPX N Otilde -25
+KPX N Ocircumflex -25
+KPX N Oacute -25
+KPX N Ograve -25
+KPX N Ccedilla -30
+KPX N AE -30
+KPX N Aring -40
+KPX N Adieresis -40
+KPX N Atilde -40
+KPX N Acircumflex -40
+KPX N Aacute -40
+KPX N Agrave -40
+KPX N u -40
+KPX N o -30
+KPX N e -25
+KPX N a -30
+KPX N O -25
+KPX N G -30
+KPX N C -30
+KPX N A -40
+KPX N period -30
+KPX N comma -45
+KPX O ydieresis.sc -45
+KPX O ae.sc -55
+KPX O aring.sc -60
+KPX O adieresis.sc -60
+KPX O atilde.sc -60
+KPX O aacute.sc -60
+KPX O agrave.sc -60
+KPX O y.sc -45
+KPX O x.sc -50
+KPX O w.sc -35
+KPX O v.sc -45
+KPX O t.sc -10
+KPX O a.sc -60
+KPX O ycircumflex.sc -45
+KPX O wgrave.sc -35
+KPX O wdieresis.sc -35
+KPX O wcircumflex.sc -35
+KPX O wacute.sc -35
+KPX O uni021B.sc -10
+KPX O tcaron.sc -10
+KPX O aeacute.sc -55
+KPX O aogonek.sc -60
+KPX O amacron.sc -60
+KPX O abreve.sc -60
+KPX O ahookabove.sc -60
+KPX O adotbelow.sc -60
+KPX O abrevetilde.sc -60
+KPX O abrevehookabove.sc -60
+KPX O abrevegrave.sc -60
+KPX O abrevedotbelow.sc -60
+KPX O abreveacute.sc -60
+KPX O Abrevedotbelow -75
+KPX O Abrevetilde -75
+KPX O Abrevehookabove -75
+KPX O Abrevegrave -75
+KPX O Abreveacute -75
+KPX O Ahookabove -75
+KPX O Adotbelow -75
+KPX O Wdieresis -45
+KPX O Wacute -45
+KPX O Wgrave -45
+KPX O uni021A -15
+KPX O AEacute -65
+KPX O Ydieresis -55
+KPX O Ycircumflex -55
+KPX O Wcircumflex -45
+KPX O Tcaron -15
+KPX O Aogonek -75
+KPX O Abreve -75
+KPX O Amacron -75
+KPX O AE -65
+KPX O Aring -75
+KPX O Adieresis -75
+KPX O Atilde -75
+KPX O Aacute -75
+KPX O Agrave -75
+KPX O Y -55
+KPX O X -60
+KPX O W -45
+KPX O V -55
+KPX O T -15
+KPX O A -75
+KPX O T_h -15
+KPX P ae.sc -95
+KPX P aring.sc -105
+KPX P adieresis.sc -105
+KPX P aacute.sc -105
+KPX P j.sc -25
+KPX P a.sc -105
+KPX P jcircumflex.sc -25
+KPX P aeacute.sc -95
+KPX P aogonek.sc -105
+KPX P amacron.sc -105
+KPX P Jacute -30
+KPX P jacute.sc -25
+KPX P aeacute -40
+KPX P AEacute -115
+KPX P oogonek -55
+KPX P oe -50
+KPX P ohungarumlaut -55
+KPX P obreve -55
+KPX P omacron -55
+KPX P Jcircumflex -30
+KPX P ecaron -50
+KPX P eogonek -50
+KPX P edotaccent -50
+KPX P ebreve -50
+KPX P emacron -50
+KPX P aogonek -40
+KPX P Aogonek -125
+KPX P amacron -40
+KPX P Amacron -125
+KPX P oslash -55
+KPX P odieresis -55
+KPX P ocircumflex -55
+KPX P edieresis -50
+KPX P ecircumflex -50
+KPX P egrave -50
+KPX P ae -40
+KPX P aring -40
+KPX P adieresis -40
+KPX P aacute -40
+KPX P AE -115
+KPX P Aring -125
+KPX P Adieresis -125
+KPX P Aacute -125
+KPX P o -55
+KPX P e -50
+KPX P a -40
+KPX P J -30
+KPX P A -125
+KPX P period -130
+KPX P hyphen -50
+KPX P comma -140
+KPX R ydieresis.sc -40
+KPX R udieresis.sc -45
+KPX R ucircumflex.sc -45
+KPX R uacute.sc -45
+KPX R ugrave.sc -45
+KPX R oslash.sc -35
+KPX R odieresis.sc -35
+KPX R otilde.sc -35
+KPX R ocircumflex.sc -35
+KPX R oacute.sc -35
+KPX R ograve.sc -35
+KPX R ccedilla.sc -35
+KPX R y.sc -40
+KPX R w.sc -45
+KPX R v.sc -45
+KPX R u.sc -45
+KPX R t.sc -30
+KPX R o.sc -35
+KPX R g.sc -35
+KPX R c.sc -35
+KPX R ycircumflex.sc -40
+KPX R wgrave.sc -45
+KPX R wdieresis.sc -45
+KPX R wcircumflex.sc -45
+KPX R wacute.sc -45
+KPX R utilde.sc -45
+KPX R uring.sc -45
+KPX R uogonek.sc -45
+KPX R umacron.sc -45
+KPX R uhungarumlaut.sc -45
+KPX R ubreve.sc -45
+KPX R uni021B.sc -30
+KPX R tcaron.sc -30
+KPX R omacron.sc -35
+KPX R ohungarumlaut.sc -35
+KPX R obreve.sc -35
+KPX R gdotaccent.sc -35
+KPX R gcommaaccent.sc -35
+KPX R gcircumflex.sc -35
+KPX R gbreve.sc -35
+KPX R cdotaccent.sc -35
+KPX R ccircumflex.sc -35
+KPX R ccaron.sc -35
+KPX R cacute.sc -35
+KPX R uhorntilde.sc -45
+KPX R uhornhookabove.sc -45
+KPX R uhorngrave.sc -45
+KPX R uhorndotbelow.sc -45
+KPX R uhornacute.sc -45
+KPX R uhookabove.sc -45
+KPX R udotbelow.sc -45
+KPX R oogonek.sc -35
+KPX R ohorntilde.sc -35
+KPX R ohornhookabove.sc -35
+KPX R ohorngrave.sc -35
+KPX R ohorndotbelow.sc -35
+KPX R ohornacute.sc -35
+KPX R ohookabove.sc -35
+KPX R oe.sc -35
+KPX R odotbelow.sc -35
+KPX R ocircumflextilde.sc -35
+KPX R ocircumflexhookabove.sc -35
+KPX R ocircumflexgrave.sc -35
+KPX R ocircumflexdotbelow.sc -35
+KPX R ocircumflexacute.sc -35
+KPX R gcaron.sc -35
+KPX R gacute.sc -35
+KPX R uhorndotbelow -35
+KPX R Uhorndotbelow -55
+KPX R uhorntilde -35
+KPX R Uhorntilde -55
+KPX R uhornhookabove -35
+KPX R Uhornhookabove -55
+KPX R uhorngrave -35
+KPX R Uhorngrave -55
+KPX R uhornacute -35
+KPX R Uhornacute -55
+KPX R uhookabove -35
+KPX R Uhookabove -55
+KPX R udotbelow -35
+KPX R Udotbelow -55
+KPX R ohorndotbelow -25
+KPX R Ohorndotbelow -40
+KPX R ohorntilde -25
+KPX R Ohorntilde -40
+KPX R ohornhookabove -25
+KPX R Ohornhookabove -40
+KPX R ohorngrave -25
+KPX R Ohorngrave -40
+KPX R ohornacute -25
+KPX R Ohornacute -40
+KPX R ocircumflexdotbelow -25
+KPX R Ocircumflexdotbelow -40
+KPX R ocircumflextilde -25
+KPX R Ocircumflextilde -40
+KPX R ocircumflexhookabove -25
+KPX R Ocircumflexhookabove -40
+KPX R ocircumflexgrave -25
+KPX R Ocircumflexgrave -40
+KPX R ocircumflexacute -25
+KPX R Ocircumflexacute -40
+KPX R ohookabove -25
+KPX R Ohookabove -40
+KPX R odotbelow -25
+KPX R Odotbelow -40
+KPX R ecircumflexdotbelow -20
+KPX R ecircumflextilde -20
+KPX R ecircumflexhookabove -20
+KPX R ecircumflexgrave -20
+KPX R ecircumflexacute -20
+KPX R etilde -20
+KPX R ehookabove -20
+KPX R edotbelow -20
+KPX R Wdieresis -55
+KPX R Wacute -55
+KPX R Wgrave -55
+KPX R uni021A -35
+KPX R Gacute -40
+KPX R oogonek -25
+KPX R Oogonek -40
+KPX R Gcaron -40
+KPX R Ydieresis -50
+KPX R ycircumflex -35
+KPX R Ycircumflex -50
+KPX R Wcircumflex -55
+KPX R uogonek -35
+KPX R Uogonek -55
+KPX R uhungarumlaut -35
+KPX R Uhungarumlaut -55
+KPX R uring -35
+KPX R Uring -55
+KPX R ubreve -35
+KPX R Ubreve -55
+KPX R umacron -35
+KPX R Umacron -55
+KPX R utilde -35
+KPX R Utilde -55
+KPX R Tcaron -35
+KPX R oe -25
+KPX R OE -40
+KPX R ohungarumlaut -25
+KPX R Ohungarumlaut -40
+KPX R obreve -25
+KPX R Obreve -40
+KPX R omacron -25
+KPX R Omacron -40
+KPX R Gcommaaccent -40
+KPX R Gdotaccent -40
+KPX R Gbreve -40
+KPX R Gcircumflex -40
+KPX R ecaron -20
+KPX R eogonek -20
+KPX R edotaccent -20
+KPX R ebreve -20
+KPX R emacron -20
+KPX R Ccaron -40
+KPX R Cdotaccent -40
+KPX R Ccircumflex -40
+KPX R Cacute -40
+KPX R ydieresis -35
+KPX R udieresis -35
+KPX R ucircumflex -35
+KPX R uacute -35
+KPX R ugrave -35
+KPX R oslash -25
+KPX R odieresis -25
+KPX R otilde -25
+KPX R ocircumflex -25
+KPX R oacute -25
+KPX R ograve -25
+KPX R edieresis -20
+KPX R ecircumflex -20
+KPX R eacute -20
+KPX R egrave -20
+KPX R Udieresis -55
+KPX R Ucircumflex -55
+KPX R Uacute -55
+KPX R Ugrave -55
+KPX R Oslash -40
+KPX R Odieresis -40
+KPX R Otilde -40
+KPX R Ocircumflex -40
+KPX R Oacute -40
+KPX R Ograve -40
+KPX R Ccedilla -40
+KPX R y -35
+KPX R u -35
+KPX R o -25
+KPX R e -20
+KPX R Y -50
+KPX R W -55
+KPX R V -55
+KPX R U -55
+KPX R T -35
+KPX R O -40
+KPX R G -40
+KPX R C -40
+KPX R hyphen -50
+KPX R T_h -35
+KPX S ydieresis.sc -10
+KPX S ae.sc -25
+KPX S aring.sc -35
+KPX S adieresis.sc -35
+KPX S atilde.sc -35
+KPX S acircumflex.sc -35
+KPX S aacute.sc -35
+KPX S agrave.sc -35
+KPX S y.sc -10
+KPX S w.sc -10
+KPX S v.sc -10
+KPX S t.sc -15
+KPX S a.sc -35
+KPX S ycircumflex.sc -10
+KPX S wgrave.sc -10
+KPX S wdieresis.sc -10
+KPX S wcircumflex.sc -10
+KPX S wacute.sc -10
+KPX S uni021B.sc -15
+KPX S tcaron.sc -15
+KPX S aeacute.sc -25
+KPX S aogonek.sc -35
+KPX S amacron.sc -35
+KPX S abreve.sc -35
+KPX S ahookabove.sc -35
+KPX S adotbelow.sc -35
+KPX S acircumflextilde.sc -35
+KPX S acircumflexhookabove.sc -35
+KPX S acircumflexgrave.sc -35
+KPX S acircumflexdotbelow.sc -35
+KPX S acircumflexacute.sc -35
+KPX S abrevetilde.sc -35
+KPX S abrevegrave.sc -35
+KPX S abrevedotbelow.sc -35
+KPX S abreveacute.sc -35
+KPX S Abrevedotbelow -40
+KPX S Abrevetilde -40
+KPX S Abrevegrave -40
+KPX S Abreveacute -40
+KPX S Acircumflexdotbelow -40
+KPX S Acircumflextilde -40
+KPX S Acircumflexhookabove -40
+KPX S Acircumflexgrave -40
+KPX S Acircumflexacute -40
+KPX S Ahookabove -40
+KPX S Adotbelow -40
+KPX S Wdieresis -15
+KPX S Wacute -15
+KPX S Wgrave -15
+KPX S uni021B -20
+KPX S uni021A -20
+KPX S AEacute -30
+KPX S Ydieresis -15
+KPX S Ycircumflex -15
+KPX S Wcircumflex -15
+KPX S tcaron -20
+KPX S Tcaron -20
+KPX S Aogonek -40
+KPX S Abreve -40
+KPX S Amacron -40
+KPX S AE -30
+KPX S Aring -40
+KPX S Adieresis -40
+KPX S Atilde -40
+KPX S Acircumflex -40
+KPX S Aacute -40
+KPX S Agrave -40
+KPX S t -20
+KPX S Y -15
+KPX S W -15
+KPX S V -15
+KPX S T -20
+KPX S A -40
+KPX S T_h -20
+KPX T oslash.sc -15
+KPX T odieresis.sc -10
+KPX T otilde.sc -10
+KPX T ocircumflex.sc -10
+KPX T oacute.sc -10
+KPX T ograve.sc -10
+KPX T ccedilla.sc -20
+KPX T ae.sc -80
+KPX T aring.sc -25
+KPX T adieresis.sc -25
+KPX T atilde.sc -25
+KPX T acircumflex.sc -25
+KPX T aacute.sc -40
+KPX T agrave.sc -25
+KPX T o.sc -15
+KPX T g.sc -20
+KPX T c.sc -20
+KPX T a.sc -55
+KPX T omacron.sc -10
+KPX T ohungarumlaut.sc -10
+KPX T obreve.sc -10
+KPX T gdotaccent.sc -10
+KPX T gcommaaccent.sc -20
+KPX T gcircumflex.sc -10
+KPX T gbreve.sc -10
+KPX T cdotaccent.sc -10
+KPX T ccircumflex.sc -10
+KPX T ccaron.sc -10
+KPX T cacute.sc -15
+KPX T aeacute.sc -80
+KPX T aogonek.sc -55
+KPX T amacron.sc -25
+KPX T abreve.sc -25
+KPX T jacute -10
+KPX T oogonek.sc -15
+KPX T ohorntilde.sc -10
+KPX T ohornhookabove.sc -10
+KPX T ohorngrave.sc -10
+KPX T ohorndotbelow.sc -10
+KPX T ohornacute.sc -10
+KPX T ohookabove.sc -10
+KPX T oe.sc -40
+KPX T odotbelow.sc -15
+KPX T ocircumflexdotbelow.sc -10
+KPX T gcaron.sc -10
+KPX T gacute.sc -15
+KPX T ahookabove.sc -25
+KPX T adotbelow.sc -55
+KPX T acircumflexdotbelow.sc -25
+KPX T abrevedotbelow.sc -25
+KPX T guilsinglleft -135
+KPX T ytilde -55
+KPX T yhookabove -55
+KPX T ygrave -55
+KPX T uhorndotbelow -55
+KPX T uhorntilde -55
+KPX T uhornhookabove -55
+KPX T uhorngrave -55
+KPX T uhornacute -55
+KPX T uhookabove -55
+KPX T udotbelow -110
+KPX T ohorndotbelow -50
+KPX T Ohorndotbelow -20
+KPX T ohorntilde -50
+KPX T ohornhookabove -50
+KPX T Ohornhookabove -20
+KPX T ohorngrave -50
+KPX T Ohorngrave -20
+KPX T ohornacute -50
+KPX T Ohornacute -20
+KPX T ocircumflexdotbelow -50
+KPX T Ocircumflexdotbelow -20
+KPX T Ocircumflexhookabove -20
+KPX T Ocircumflexgrave -20
+KPX T Ocircumflexacute -20
+KPX T ohookabove -50
+KPX T Ohookabove -20
+KPX T odotbelow -100
+KPX T Odotbelow -20
+KPX T idotbelow -25
+KPX T ihookabove -15
+KPX T ecircumflexdotbelow -50
+KPX T etilde -50
+KPX T ehookabove -50
+KPX T edotbelow -95
+KPX T abrevedotbelow -40
+KPX T Abrevedotbelow -65
+KPX T Abrevehookabove -65
+KPX T Abrevegrave -65
+KPX T Abreveacute -65
+KPX T acircumflexdotbelow -40
+KPX T Acircumflexdotbelow -65
+KPX T Acircumflexhookabove -65
+KPX T Acircumflexgrave -65
+KPX T Acircumflexacute -65
+KPX T ahookabove -40
+KPX T Ahookabove -65
+KPX T adotbelow -80
+KPX T Adotbelow -65
+KPX T wdieresis -55
+KPX T wacute -80
+KPX T wgrave -55
+KPX T rdotaccent -35
+KPX T uni0219 -70
+KPX T aeacute -75
+KPX T AEacute -115
+KPX T gacute -70
+KPX T Gacute -25
+KPX T oogonek -100
+KPX T Oogonek -20
+KPX T gcaron -50
+KPX T Gcaron -25
+KPX T ycircumflex -55
+KPX T wcircumflex -55
+KPX T uogonek -110
+KPX T uhungarumlaut -55
+KPX T uring -55
+KPX T ubreve -55
+KPX T umacron -55
+KPX T utilde -55
+KPX T scaron -35
+KPX T scedilla -70
+KPX T scircumflex -35
+KPX T sacute -55
+KPX T rcaron -35
+KPX T rcommaaccent -65
+KPX T racute -50
+KPX T oe -70
+KPX T OE -55
+KPX T ohungarumlaut -50
+KPX T Ohungarumlaut -20
+KPX T obreve -50
+KPX T Obreve -20
+KPX T omacron -50
+KPX T Omacron -20
+KPX T jcircumflex -5
+KPX T iogonek -25
+KPX T ibreve -15
+KPX T imacron -15
+KPX T itilde -15
+KPX T gcommaaccent -95
+KPX T Gcommaaccent -25
+KPX T gdotaccent -50
+KPX T Gdotaccent -25
+KPX T gbreve -50
+KPX T Gbreve -25
+KPX T gcircumflex -50
+KPX T Gcircumflex -25
+KPX T ecaron -50
+KPX T eogonek -95
+KPX T edotaccent -50
+KPX T ebreve -50
+KPX T emacron -50
+KPX T ccaron -50
+KPX T Ccaron -25
+KPX T cdotaccent -50
+KPX T Cdotaccent -25
+KPX T ccircumflex -50
+KPX T Ccircumflex -25
+KPX T cacute -70
+KPX T Cacute -25
+KPX T aogonek -80
+KPX T Aogonek -65
+KPX T abreve -40
+KPX T Abreve -65
+KPX T amacron -40
+KPX T Amacron -65
+KPX T ydieresis -55
+KPX T yacute -85
+KPX T udieresis -55
+KPX T ucircumflex -55
+KPX T uacute -85
+KPX T ugrave -55
+KPX T oslash -100
+KPX T odieresis -50
+KPX T otilde -50
+KPX T ocircumflex -50
+KPX T oacute -75
+KPX T ograve -50
+KPX T idieresis -15
+KPX T icircumflex -15
+KPX T iacute -20
+KPX T igrave -15
+KPX T edieresis -50
+KPX T ecircumflex -50
+KPX T eacute -70
+KPX T egrave -50
+KPX T ccedilla -95
+KPX T ae -75
+KPX T aring -40
+KPX T adieresis -40
+KPX T atilde -40
+KPX T acircumflex -40
+KPX T aacute -60
+KPX T agrave -40
+KPX T Oslash -20
+KPX T Odieresis -20
+KPX T Otilde -20
+KPX T Ocircumflex -20
+KPX T Oacute -20
+KPX T Ograve -20
+KPX T Ccedilla -25
+KPX T AE -115
+KPX T Aring -65
+KPX T Adieresis -65
+KPX T Atilde -65
+KPX T Acircumflex -65
+KPX T Aacute -65
+KPX T Agrave -65
+KPX T guillemotleft -125
+KPX T y -110
+KPX T w -105
+KPX T v -105
+KPX T u -110
+KPX T s -70
+KPX T r -65
+KPX T o -100
+KPX T j -10
+KPX T i -25
+KPX T g -95
+KPX T e -95
+KPX T c -95
+KPX T a -80
+KPX T O -20
+KPX T G -25
+KPX T C -25
+KPX T A -65
+KPX T semicolon -100
+KPX T colon -95
+KPX T period -90
+KPX T hyphen -75
+KPX T comma -100
+KPX U ae.sc -60
+KPX U aring.sc -35
+KPX U adieresis.sc -35
+KPX U atilde.sc -35
+KPX U acircumflex.sc -35
+KPX U aacute.sc -50
+KPX U agrave.sc -35
+KPX U a.sc -65
+KPX U aeacute.sc -60
+KPX U aogonek.sc -65
+KPX U amacron.sc -35
+KPX U abreve.sc -35
+KPX U ahookabove.sc -35
+KPX U adotbelow.sc -65
+KPX U acircumflexdotbelow.sc -35
+KPX U abrevedotbelow.sc -35
+KPX U Abrevedotbelow -80
+KPX U Abrevehookabove -80
+KPX U Abrevegrave -80
+KPX U Abreveacute -80
+KPX U Acircumflexdotbelow -80
+KPX U Acircumflextilde -80
+KPX U Acircumflexhookabove -80
+KPX U Acircumflexgrave -80
+KPX U Acircumflexacute -80
+KPX U Ahookabove -80
+KPX U Adotbelow -80
+KPX U rdotaccent -20
+KPX U AEacute -70
+KPX U rcaron -20
+KPX U rcommaaccent -40
+KPX U racute -30
+KPX U ncaron -20
+KPX U ncommaaccent -35
+KPX U nacute -25
+KPX U Aogonek -80
+KPX U Abreve -80
+KPX U Amacron -80
+KPX U ntilde -20
+KPX U AE -70
+KPX U Aring -80
+KPX U Adieresis -80
+KPX U Atilde -80
+KPX U Acircumflex -80
+KPX U Aacute -80
+KPX U Agrave -80
+KPX U r -40
+KPX U p -35
+KPX U n -35
+KPX U m -40
+KPX U A -80
+KPX U period -50
+KPX U comma -65
+KPX V zdotaccent -67
+KPX V zcaron -67
+KPX V zacute -67
+KPX V z -67
+KPX V scircumflex -66
+KPX V scedilla -66
+KPX V scaron -66
+KPX V sacute -66
+KPX V s -66
+KPX V cdotaccent -67
+KPX V ccircumflex -67
+KPX V ccedilla -67
+KPX V ccaron -67
+KPX V cacute -67
+KPX V c -67
+KPX V oslash.sc -60
+KPX V odieresis.sc -30
+KPX V otilde.sc -30
+KPX V ocircumflex.sc -30
+KPX V oacute.sc -45
+KPX V ograve.sc -30
+KPX V ccedilla.sc -60
+KPX V ae.sc -80
+KPX V aring.sc -60
+KPX V adieresis.sc -60
+KPX V atilde.sc -60
+KPX V acircumflex.sc -60
+KPX V aacute.sc -85
+KPX V agrave.sc -60
+KPX V s.sc -30
+KPX V o.sc -60
+KPX V g.sc -60
+KPX V c.sc -60
+KPX V a.sc -115
+KPX V uni0219.sc -30
+KPX V scircumflex.sc -15
+KPX V scedilla.sc -30
+KPX V sacute.sc -20
+KPX V omacron.sc -30
+KPX V ohungarumlaut.sc -30
+KPX V obreve.sc -30
+KPX V gdotaccent.sc -30
+KPX V gcommaaccent.sc -60
+KPX V gcircumflex.sc -30
+KPX V gbreve.sc -30
+KPX V cdotaccent.sc -30
+KPX V ccircumflex.sc -30
+KPX V ccaron.sc -30
+KPX V cacute.sc -45
+KPX V aeacute.sc -80
+KPX V aogonek.sc -115
+KPX V amacron.sc -60
+KPX V abreve.sc -60
+KPX V scaron.sc -15
+KPX V oogonek.sc -60
+KPX V ohorntilde.sc -30
+KPX V ohornhookabove.sc -30
+KPX V ohorngrave.sc -30
+KPX V ohorndotbelow.sc -30
+KPX V ohornacute.sc -30
+KPX V ohookabove.sc -30
+KPX V oe.sc -40
+KPX V odotbelow.sc -60
+KPX V ocircumflexdotbelow.sc -30
+KPX V gcaron.sc -30
+KPX V gacute.sc -45
+KPX V ahookabove.sc -60
+KPX V adotbelow.sc -115
+KPX V acircumflexdotbelow.sc -60
+KPX V abrevedotbelow.sc -60
+KPX V guilsinglleft -125
+KPX V ytilde -30
+KPX V yhookabove -30
+KPX V ygrave -30
+KPX V uhorndotbelow -35
+KPX V uhorntilde -35
+KPX V uhornhookabove -35
+KPX V uhorngrave -35
+KPX V uhornacute -35
+KPX V uhookabove -35
+KPX V udotbelow -65
+KPX V ohorndotbelow -45
+KPX V Ohorndotbelow -70
+KPX V ohorntilde -45
+KPX V Ohorntilde -70
+KPX V ohornhookabove -45
+KPX V Ohornhookabove -70
+KPX V ohorngrave -45
+KPX V Ohorngrave -70
+KPX V ohornacute -45
+KPX V Ohornacute -70
+KPX V ocircumflexdotbelow -45
+KPX V Ocircumflexdotbelow -70
+KPX V Ocircumflextilde -70
+KPX V Ocircumflexhookabove -70
+KPX V Ocircumflexgrave -70
+KPX V Ocircumflexacute -70
+KPX V ohookabove -45
+KPX V Ohookabove -70
+KPX V odotbelow -90
+KPX V Odotbelow -70
+KPX V idotbelow -25
+KPX V ecircumflexdotbelow -45
+KPX V etilde -45
+KPX V ehookabove -45
+KPX V edotbelow -90
+KPX V abrevedotbelow -50
+KPX V Abrevedotbelow -140
+KPX V Abrevehookabove -140
+KPX V Abrevegrave -140
+KPX V Abreveacute -140
+KPX V acircumflexdotbelow -50
+KPX V Acircumflexdotbelow -140
+KPX V Acircumflextilde -140
+KPX V Acircumflexhookabove -140
+KPX V Acircumflexgrave -140
+KPX V Acircumflexacute -140
+KPX V ahookabove -50
+KPX V Ahookabove -140
+KPX V adotbelow -95
+KPX V Adotbelow -140
+KPX V rdotaccent -35
+KPX V uni0218 -35
+KPX V aeacute -75
+KPX V AEacute -115
+KPX V gacute -75
+KPX V Gacute -70
+KPX V oogonek -90
+KPX V Oogonek -70
+KPX V gcaron -50
+KPX V Gcaron -70
+KPX V ycircumflex -30
+KPX V uogonek -65
+KPX V uhungarumlaut -35
+KPX V uring -35
+KPX V ubreve -35
+KPX V umacron -35
+KPX V utilde -35
+KPX V Scaron -35
+KPX V Scedilla -35
+KPX V Scircumflex -35
+KPX V Sacute -35
+KPX V rcaron -35
+KPX V rcommaaccent -65
+KPX V racute -50
+KPX V oe -70
+KPX V OE -55
+KPX V ohungarumlaut -45
+KPX V Ohungarumlaut -70
+KPX V obreve -45
+KPX V Obreve -70
+KPX V omacron -45
+KPX V Omacron -70
+KPX V iogonek -25
+KPX V gcommaaccent -100
+KPX V Gcommaaccent -70
+KPX V gdotaccent -50
+KPX V Gdotaccent -70
+KPX V gbreve -50
+KPX V Gbreve -70
+KPX V gcircumflex -50
+KPX V Gcircumflex -70
+KPX V ecaron -45
+KPX V eogonek -90
+KPX V edotaccent -45
+KPX V ebreve -45
+KPX V emacron -45
+KPX V Ccaron -70
+KPX V Cdotaccent -70
+KPX V Ccircumflex -70
+KPX V Cacute -70
+KPX V aogonek -95
+KPX V Aogonek -140
+KPX V abreve -50
+KPX V Abreve -140
+KPX V amacron -50
+KPX V Amacron -140
+KPX V ydieresis -30
+KPX V yacute -40
+KPX V udieresis -35
+KPX V ucircumflex -35
+KPX V uacute -50
+KPX V ugrave -35
+KPX V oslash -90
+KPX V odieresis -45
+KPX V otilde -45
+KPX V ocircumflex -45
+KPX V oacute -70
+KPX V ograve -45
+KPX V iacute -10
+KPX V edieresis -45
+KPX V ecircumflex -45
+KPX V eacute -70
+KPX V egrave -45
+KPX V ae -75
+KPX V aring -50
+KPX V adieresis -50
+KPX V atilde -50
+KPX V acircumflex -50
+KPX V aacute -70
+KPX V agrave -50
+KPX V Oslash -70
+KPX V Odieresis -70
+KPX V Otilde -70
+KPX V Ocircumflex -70
+KPX V Oacute -70
+KPX V Ograve -70
+KPX V Ccedilla -70
+KPX V AE -115
+KPX V Aring -140
+KPX V Adieresis -140
+KPX V Atilde -140
+KPX V Acircumflex -140
+KPX V Aacute -140
+KPX V Agrave -140
+KPX V guillemotleft -115
+KPX V y -55
+KPX V u -65
+KPX V r -65
+KPX V o -90
+KPX V i -25
+KPX V g -100
+KPX V e -90
+KPX V a -95
+KPX V S -35
+KPX V O -70
+KPX V G -70
+KPX V C -70
+KPX V A -140
+KPX V semicolon -110
+KPX V colon -90
+KPX V period -120
+KPX V hyphen -65
+KPX V comma -135
+KPX W zdotaccent -53
+KPX W zcaron -53
+KPX W zacute -53
+KPX W z -53
+KPX W scircumflex -60
+KPX W scedilla -60
+KPX W scaron -60
+KPX W sacute -60
+KPX W s -60
+KPX W cdotaccent -53
+KPX W ccircumflex -53
+KPX W ccedilla -53
+KPX W ccaron -53
+KPX W cacute -53
+KPX W c -53
+KPX W oslash.sc -45
+KPX W odieresis.sc -25
+KPX W otilde.sc -25
+KPX W ocircumflex.sc -25
+KPX W oacute.sc -35
+KPX W ograve.sc -25
+KPX W ccedilla.sc -45
+KPX W ae.sc -80
+KPX W aring.sc -50
+KPX W adieresis.sc -50
+KPX W atilde.sc -50
+KPX W acircumflex.sc -50
+KPX W aacute.sc -70
+KPX W agrave.sc -50
+KPX W s.sc -30
+KPX W o.sc -45
+KPX W g.sc -45
+KPX W c.sc -45
+KPX W a.sc -95
+KPX W uni0219.sc -30
+KPX W scircumflex.sc -15
+KPX W scedilla.sc -30
+KPX W sacute.sc -20
+KPX W omacron.sc -25
+KPX W ohungarumlaut.sc -25
+KPX W obreve.sc -25
+KPX W gdotaccent.sc -25
+KPX W gcommaaccent.sc -45
+KPX W gcircumflex.sc -25
+KPX W gbreve.sc -25
+KPX W cdotaccent.sc -25
+KPX W ccircumflex.sc -25
+KPX W ccaron.sc -25
+KPX W cacute.sc -35
+KPX W aeacute.sc -80
+KPX W aogonek.sc -95
+KPX W amacron.sc -50
+KPX W abreve.sc -50
+KPX W scaron.sc -15
+KPX W oogonek.sc -45
+KPX W ohorntilde.sc -25
+KPX W ohornhookabove.sc -25
+KPX W ohorngrave.sc -25
+KPX W ohorndotbelow.sc -25
+KPX W ohornacute.sc -25
+KPX W ohookabove.sc -25
+KPX W oe.sc -40
+KPX W ocircumflexdotbelow.sc -25
+KPX W gcaron.sc -25
+KPX W gacute.sc -35
+KPX W ahookabove.sc -50
+KPX W acircumflexdotbelow.sc -50
+KPX W abrevedotbelow.sc -50
+KPX W guilsinglleft -100
+KPX W ytilde -25
+KPX W yhookabove -25
+KPX W ygrave -25
+KPX W uhorndotbelow -25
+KPX W uhorntilde -25
+KPX W uhornhookabove -25
+KPX W uhorngrave -25
+KPX W uhornacute -25
+KPX W uhookabove -25
+KPX W ohorndotbelow -35
+KPX W ohorntilde -35
+KPX W ohornhookabove -35
+KPX W ohorngrave -35
+KPX W ohornacute -35
+KPX W ocircumflexdotbelow -35
+KPX W ohookabove -35
+KPX W ecircumflexdotbelow -35
+KPX W etilde -35
+KPX W ehookabove -35
+KPX W abrevedotbelow -40
+KPX W acircumflexdotbelow -40
+KPX W ahookabove -40
+KPX W rdotaccent -30
+KPX W uni0218 -35
+KPX W aeacute -75
+KPX W AEacute -115
+KPX W gacute -60
+KPX W Gacute -55
+KPX W oogonek -70
+KPX W Oogonek -55
+KPX W gcaron -40
+KPX W Gcaron -55
+KPX W ycircumflex -25
+KPX W uogonek -50
+KPX W uhungarumlaut -25
+KPX W uring -25
+KPX W ubreve -25
+KPX W umacron -25
+KPX W utilde -25
+KPX W Scaron -35
+KPX W Scedilla -35
+KPX W Scircumflex -35
+KPX W Sacute -35
+KPX W rcaron -30
+KPX W rcommaaccent -55
+KPX W racute -40
+KPX W oe -70
+KPX W OE -55
+KPX W ohungarumlaut -35
+KPX W Ohungarumlaut -55
+KPX W obreve -35
+KPX W Obreve -55
+KPX W omacron -35
+KPX W Omacron -55
+KPX W iogonek -25
+KPX W gcommaaccent -80
+KPX W Gcommaaccent -55
+KPX W gdotaccent -40
+KPX W Gdotaccent -55
+KPX W gbreve -40
+KPX W Gbreve -55
+KPX W gcircumflex -40
+KPX W Gcircumflex -55
+KPX W ecaron -35
+KPX W eogonek -65
+KPX W edotaccent -35
+KPX W ebreve -35
+KPX W emacron -35
+KPX W Ccaron -55
+KPX W Cdotaccent -55
+KPX W Ccircumflex -55
+KPX W Cacute -55
+KPX W aogonek -75
+KPX W Aogonek -115
+KPX W abreve -40
+KPX W amacron -40
+KPX W Amacron -115
+KPX W ydieresis -25
+KPX W yacute -35
+KPX W udieresis -25
+KPX W ucircumflex -25
+KPX W uacute -40
+KPX W ugrave -25
+KPX W oslash -70
+KPX W odieresis -35
+KPX W otilde -35
+KPX W ocircumflex -35
+KPX W oacute -55
+KPX W ograve -35
+KPX W iacute -10
+KPX W edieresis -35
+KPX W ecircumflex -35
+KPX W eacute -50
+KPX W egrave -35
+KPX W ae -75
+KPX W aring -40
+KPX W adieresis -40
+KPX W atilde -40
+KPX W acircumflex -40
+KPX W aacute -55
+KPX W agrave -40
+KPX W Oslash -55
+KPX W Odieresis -55
+KPX W Ccedilla -55
+KPX W AE -115
+KPX W Aring -115
+KPX W Adieresis -115
+KPX W guillemotleft -95
+KPX W y -45
+KPX W u -50
+KPX W r -55
+KPX W o -70
+KPX W i -25
+KPX W g -80
+KPX W e -65
+KPX W a -75
+KPX W S -35
+KPX W O -55
+KPX W G -55
+KPX W C -55
+KPX W A -115
+KPX W semicolon -95
+KPX W colon -80
+KPX W period -90
+KPX W hyphen -45
+KPX W comma -105
+KPX X oslash.sc -45
+KPX X odieresis.sc -45
+KPX X otilde.sc -45
+KPX X ocircumflex.sc -45
+KPX X oacute.sc -45
+KPX X ograve.sc -45
+KPX X ccedilla.sc -50
+KPX X q.sc -45
+KPX X o.sc -45
+KPX X c.sc -50
+KPX X omacron.sc -45
+KPX X ohungarumlaut.sc -45
+KPX X obreve.sc -45
+KPX X cdotaccent.sc -50
+KPX X ccircumflex.sc -50
+KPX X ccaron.sc -50
+KPX X cacute.sc -50
+KPX X oogonek.sc -45
+KPX X ohorntilde.sc -45
+KPX X ohornhookabove.sc -45
+KPX X ohorngrave.sc -45
+KPX X ohorndotbelow.sc -45
+KPX X ohornacute.sc -45
+KPX X ohookabove.sc -45
+KPX X odotbelow.sc -45
+KPX X ocircumflexhookabove.sc -45
+KPX X ocircumflexgrave.sc -45
+KPX X ocircumflexdotbelow.sc -45
+KPX X ocircumflexacute.sc -45
+KPX X uhorndotbelow -45
+KPX X uhornhookabove -45
+KPX X uhorngrave -45
+KPX X uhornacute -45
+KPX X uhookabove -45
+KPX X udotbelow -45
+KPX X ohorndotbelow -35
+KPX X Ohorndotbelow -55
+KPX X ohorntilde -35
+KPX X Ohorntilde -55
+KPX X ohornhookabove -35
+KPX X Ohornhookabove -55
+KPX X ohorngrave -35
+KPX X Ohorngrave -55
+KPX X ohornacute -35
+KPX X Ohornacute -55
+KPX X ocircumflexdotbelow -35
+KPX X Ocircumflexdotbelow -55
+KPX X ocircumflexhookabove -35
+KPX X Ocircumflexhookabove -55
+KPX X ocircumflexgrave -35
+KPX X Ocircumflexgrave -55
+KPX X ocircumflexacute -35
+KPX X Ocircumflexacute -55
+KPX X ohookabove -35
+KPX X Ohookabove -55
+KPX X odotbelow -35
+KPX X Odotbelow -55
+KPX X ecircumflexdotbelow -30
+KPX X ecircumflexhookabove -30
+KPX X ecircumflexgrave -30
+KPX X ecircumflexacute -30
+KPX X etilde -30
+KPX X ehookabove -30
+KPX X edotbelow -30
+KPX X oogonek -35
+KPX X Oogonek -55
+KPX X ycircumflex -95
+KPX X uogonek -45
+KPX X uhungarumlaut -45
+KPX X uring -45
+KPX X ubreve -45
+KPX X umacron -45
+KPX X utilde -45
+KPX X ohungarumlaut -35
+KPX X Ohungarumlaut -55
+KPX X obreve -35
+KPX X Obreve -55
+KPX X omacron -35
+KPX X Omacron -55
+KPX X ecaron -30
+KPX X eogonek -30
+KPX X edotaccent -30
+KPX X ebreve -30
+KPX X emacron -30
+KPX X Ccaron -60
+KPX X Cdotaccent -60
+KPX X Ccircumflex -60
+KPX X Cacute -60
+KPX X ydieresis -95
+KPX X udieresis -45
+KPX X ucircumflex -45
+KPX X uacute -45
+KPX X ugrave -45
+KPX X oslash -35
+KPX X odieresis -35
+KPX X otilde -35
+KPX X ocircumflex -35
+KPX X oacute -35
+KPX X ograve -35
+KPX X edieresis -30
+KPX X ecircumflex -30
+KPX X eacute -30
+KPX X egrave -30
+KPX X Oslash -55
+KPX X Odieresis -55
+KPX X Otilde -55
+KPX X Ocircumflex -55
+KPX X Oacute -55
+KPX X Ograve -55
+KPX X Ccedilla -60
+KPX X y -95
+KPX X u -45
+KPX X o -35
+KPX X e -30
+KPX X Q -55
+KPX X O -55
+KPX X C -60
+KPX X hyphen -50
+KPX Y zdotaccent -67
+KPX Y zcaron -67
+KPX Y zacute -67
+KPX Y z -67
+KPX Y scircumflex -67
+KPX Y scedilla -67
+KPX Y scaron -67
+KPX Y sacute -67
+KPX Y s -67
+KPX Y cdotaccent -67
+KPX Y ccircumflex -67
+KPX Y ccedilla -67
+KPX Y ccaron -67
+KPX Y cacute -67
+KPX Y c -67
+KPX Y oslash.sc -60
+KPX Y odieresis.sc -30
+KPX Y otilde.sc -30
+KPX Y ocircumflex.sc -30
+KPX Y oacute.sc -45
+KPX Y ograve.sc -30
+KPX Y ccedilla.sc -60
+KPX Y ae.sc -80
+KPX Y aring.sc -30
+KPX Y adieresis.sc -30
+KPX Y atilde.sc -30
+KPX Y acircumflex.sc -30
+KPX Y aacute.sc -45
+KPX Y agrave.sc -30
+KPX Y s.sc -30
+KPX Y o.sc -60
+KPX Y g.sc -60
+KPX Y c.sc -60
+KPX Y a.sc -60
+KPX Y uni0219.sc -30
+KPX Y scircumflex.sc -15
+KPX Y scedilla.sc -30
+KPX Y sacute.sc -20
+KPX Y omacron.sc -30
+KPX Y ohungarumlaut.sc -30
+KPX Y obreve.sc -30
+KPX Y gdotaccent.sc -30
+KPX Y gcommaaccent.sc -60
+KPX Y gcircumflex.sc -30
+KPX Y gbreve.sc -30
+KPX Y cdotaccent.sc -30
+KPX Y ccircumflex.sc -30
+KPX Y ccaron.sc -30
+KPX Y cacute.sc -45
+KPX Y aeacute.sc -80
+KPX Y aogonek.sc -60
+KPX Y amacron.sc -30
+KPX Y abreve.sc -30
+KPX Y scaron.sc -15
+KPX Y oogonek.sc -60
+KPX Y ohorntilde.sc -30
+KPX Y ohornhookabove.sc -30
+KPX Y ohorngrave.sc -30
+KPX Y ohorndotbelow.sc -30
+KPX Y ohornacute.sc -30
+KPX Y ohookabove.sc -30
+KPX Y oe.sc -40
+KPX Y ocircumflexdotbelow.sc -30
+KPX Y gcaron.sc -30
+KPX Y gacute.sc -45
+KPX Y ahookabove.sc -30
+KPX Y acircumflexdotbelow.sc -30
+KPX Y abrevedotbelow.sc -30
+KPX Y guilsinglleft -135
+KPX Y uhorndotbelow -40
+KPX Y uhorntilde -40
+KPX Y uhornhookabove -40
+KPX Y uhorngrave -40
+KPX Y uhornacute -40
+KPX Y uhookabove -40
+KPX Y ohorndotbelow -50
+KPX Y ohorntilde -50
+KPX Y ohornhookabove -50
+KPX Y ohorngrave -50
+KPX Y ohornacute -50
+KPX Y ocircumflexdotbelow -50
+KPX Y ohookabove -50
+KPX Y ecircumflexdotbelow -45
+KPX Y etilde -45
+KPX Y ehookabove -45
+KPX Y abrevedotbelow -45
+KPX Y acircumflexdotbelow -45
+KPX Y ahookabove -45
+KPX Y uni0218 -35
+KPX Y aeacute -75
+KPX Y AEacute -115
+KPX Y gacute -75
+KPX Y Gacute -70
+KPX Y oogonek -95
+KPX Y Oogonek -70
+KPX Y gcaron -50
+KPX Y Gcaron -70
+KPX Y uogonek -80
+KPX Y uhungarumlaut -40
+KPX Y uring -40
+KPX Y ubreve -40
+KPX Y umacron -40
+KPX Y utilde -40
+KPX Y Scaron -35
+KPX Y Scedilla -35
+KPX Y Scircumflex -35
+KPX Y Sacute -35
+KPX Y oe -70
+KPX Y OE -55
+KPX Y ohungarumlaut -50
+KPX Y Ohungarumlaut -70
+KPX Y obreve -50
+KPX Y Obreve -70
+KPX Y omacron -50
+KPX Y Omacron -70
+KPX Y iogonek -25
+KPX Y gcommaaccent -100
+KPX Y Gcommaaccent -70
+KPX Y gdotaccent -50
+KPX Y Gdotaccent -70
+KPX Y gbreve -50
+KPX Y Gbreve -70
+KPX Y gcircumflex -50
+KPX Y Gcircumflex -70
+KPX Y ecaron -45
+KPX Y eogonek -90
+KPX Y edotaccent -45
+KPX Y ebreve -45
+KPX Y emacron -45
+KPX Y Ccaron -70
+KPX Y Cdotaccent -70
+KPX Y Ccircumflex -70
+KPX Y Cacute -70
+KPX Y aogonek -85
+KPX Y Aogonek -70
+KPX Y abreve -45
+KPX Y amacron -45
+KPX Y Amacron -70
+KPX Y udieresis -40
+KPX Y ucircumflex -40
+KPX Y uacute -60
+KPX Y ugrave -40
+KPX Y oslash -95
+KPX Y odieresis -50
+KPX Y otilde -50
+KPX Y ocircumflex -50
+KPX Y oacute -70
+KPX Y ograve -50
+KPX Y iacute -10
+KPX Y edieresis -45
+KPX Y ecircumflex -45
+KPX Y eacute -70
+KPX Y egrave -45
+KPX Y ae -75
+KPX Y aring -45
+KPX Y adieresis -45
+KPX Y atilde -45
+KPX Y acircumflex -45
+KPX Y aacute -65
+KPX Y agrave -45
+KPX Y Oslash -70
+KPX Y Odieresis -70
+KPX Y Ccedilla -70
+KPX Y AE -115
+KPX Y Aring -70
+KPX Y Adieresis -70
+KPX Y guillemotleft -125
+KPX Y v -70
+KPX Y u -80
+KPX Y p -75
+KPX Y o -95
+KPX Y i -25
+KPX Y g -100
+KPX Y e -90
+KPX Y a -85
+KPX Y S -35
+KPX Y O -70
+KPX Y G -70
+KPX Y C -70
+KPX Y A -70
+KPX Y semicolon -110
+KPX Y colon -100
+KPX Y period -100
+KPX Y hyphen -80
+KPX Y comma -110
+KPX Z ycircumflex -60
+KPX Z ydieresis -60
+KPX Z y -60
+KPX Z v -60
+KPX a jacute -20
+KPX a quoteright -35
+KPX a wdieresis -35
+KPX a wacute -35
+KPX a wgrave -35
+KPX a ycircumflex -40
+KPX a wcircumflex -35
+KPX a jcircumflex -20
+KPX a ydieresis -40
+KPX a y -40
+KPX a w -35
+KPX a v -35
+KPX a j -20
+KPX b wdieresis -30
+KPX b wacute -30
+KPX b wgrave -30
+KPX b ycircumflex -30
+KPX b wcircumflex -30
+KPX b ydieresis -30
+KPX b y -30
+KPX b w -30
+KPX b v -30
+KPX e wdieresis -10
+KPX e wacute -10
+KPX e wgrave -10
+KPX e ycircumflex -15
+KPX e wcircumflex -10
+KPX e ydieresis -15
+KPX e y -15
+KPX e w -10
+KPX e v -10
+KPX e V -90
+KPX f jacute 25
+KPX f ohorndotbelow -10
+KPX f ohorntilde -10
+KPX f ohornhookabove -10
+KPX f ohorngrave -10
+KPX f ohornacute -10
+KPX f ocircumflexdotbelow -10
+KPX f ohookabove -10
+KPX f ihookabove 10
+KPX f ecircumflexdotbelow -10
+KPX f etilde -10
+KPX f ehookabove -10
+KPX f abrevedotbelow -5
+KPX f acircumflexdotbelow -5
+KPX f ahookabove -5
+KPX f uni021B 10
+KPX f oogonek -15
+KPX f tcaron 5
+KPX f oe -15
+KPX f ohungarumlaut -10
+KPX f obreve -10
+KPX f omacron -10
+KPX f lslash 25
+KPX f lcaron 15
+KPX f lcommaaccent 25
+KPX f lacute 20
+KPX f jcircumflex 15
+KPX f iogonek 15
+KPX f ibreve 10
+KPX f imacron 10
+KPX f itilde 10
+KPX f ecaron -10
+KPX f eogonek -15
+KPX f edotaccent -10
+KPX f ebreve -10
+KPX f emacron -10
+KPX f aogonek -10
+KPX f abreve -5
+KPX f amacron -5
+KPX f oslash -15
+KPX f odieresis -10
+KPX f otilde -10
+KPX f ocircumflex -10
+KPX f oacute -10
+KPX f ograve -10
+KPX f idieresis 10
+KPX f icircumflex 10
+KPX f iacute 10
+KPX f igrave 10
+KPX f edieresis -10
+KPX f ecircumflex -10
+KPX f eacute -10
+KPX f egrave -10
+KPX f aring -5
+KPX f adieresis -5
+KPX f atilde -5
+KPX f acircumflex -5
+KPX f aacute -10
+KPX f agrave -5
+KPX f t 10
+KPX f o -15
+KPX f l 25
+KPX f j 30
+KPX f i 15
+KPX f e -15
+KPX f a -10
+KPX g abrevedotbelow -15
+KPX g abrevetilde -15
+KPX g abrevehookabove -15
+KPX g abrevegrave -15
+KPX g abreveacute -15
+KPX g acircumflexdotbelow -15
+KPX g acircumflextilde -15
+KPX g acircumflexhookabove -15
+KPX g acircumflexgrave -15
+KPX g acircumflexacute -15
+KPX g ahookabove -15
+KPX g adotbelow -15
+KPX g rdotaccent 15
+KPX g aeacute -15
+KPX g rcaron 15
+KPX g rcommaaccent 15
+KPX g racute 15
+KPX g ecaron -20
+KPX g eogonek -20
+KPX g edotaccent -20
+KPX g ebreve -20
+KPX g emacron -20
+KPX g aogonek -15
+KPX g abreve -15
+KPX g amacron -15
+KPX g edieresis -20
+KPX g egrave -20
+KPX g ae -15
+KPX g aring -15
+KPX g adieresis -15
+KPX g atilde -15
+KPX g acircumflex -15
+KPX g aacute -15
+KPX g agrave -15
+KPX g r 15
+KPX g e -20
+KPX g a -15
+KPX h quoteright -35
+KPX h ycircumflex -35
+KPX h ydieresis -35
+KPX h y -35
+KPX i jacute -15
+KPX i uni021A -30
+KPX i Tcaron -30
+KPX i jcircumflex -15
+KPX i j -15
+KPX i T -30
+KPX i T_h -30
+KPX k ecircumflexdotbelow -10
+KPX k ecircumflexhookabove -10
+KPX k ecircumflexgrave -10
+KPX k ecircumflexacute -10
+KPX k etilde -10
+KPX k ehookabove -10
+KPX k edotbelow -10
+KPX k uni0219 10
+KPX k gacute -10
+KPX k oogonek -20
+KPX k gcaron -10
+KPX k scaron 10
+KPX k scedilla 10
+KPX k scircumflex 10
+KPX k sacute 10
+KPX k ohungarumlaut -20
+KPX k obreve -20
+KPX k omacron -20
+KPX k gcommaaccent -10
+KPX k gdotaccent -10
+KPX k gbreve -10
+KPX k gcircumflex -10
+KPX k ecaron -10
+KPX k eogonek -10
+KPX k edotaccent -10
+KPX k ebreve -10
+KPX k emacron -10
+KPX k oslash -20
+KPX k odieresis -20
+KPX k edieresis -10
+KPX k ecircumflex -10
+KPX k eacute -10
+KPX k egrave -10
+KPX k s 10
+KPX k o -20
+KPX k g -10
+KPX k e -10
+KPX k W -35
+KPX k V -45
+KPX k hyphen -65
+KPX k comma -20
+KPX l ycircumflex -25
+KPX l ydieresis -25
+KPX l yacute -25
+KPX l y -25
+KPX l v -20
+KPX m ytilde -40
+KPX m wdieresis -40
+KPX m wacute -40
+KPX m wgrave -40
+KPX m ycircumflex -40
+KPX m wcircumflex -40
+KPX m ydieresis -40
+KPX m y -40
+KPX m w -40
+KPX m v -40
+KPX m p -20
+KPX n quoteright -30
+KPX n wdieresis -35
+KPX n wacute -35
+KPX n wgrave -35
+KPX n uni021A -60
+KPX n ycircumflex -35
+KPX n wcircumflex -35
+KPX n Tcaron -60
+KPX n ydieresis -35
+KPX n y -35
+KPX n w -35
+KPX n v -35
+KPX n p -20
+KPX n T -60
+KPX n T_h -60
+KPX o quoteright -20
+KPX o wdieresis -25
+KPX o wacute -25
+KPX o wgrave -25
+KPX o uni021B -15
+KPX o uni021A -100
+KPX o ycircumflex -30
+KPX o wcircumflex -25
+KPX o tcaron -15
+KPX o Tcaron -100
+KPX o ydieresis -30
+KPX o y -30
+KPX o x -30
+KPX o w -25
+KPX o v -25
+KPX o t -15
+KPX o T -100
+KPX o T_h -100
+KPX p uni021B -20
+KPX p ycircumflex -40
+KPX p tcaron -20
+KPX p ydieresis -40
+KPX p y -40
+KPX p t -20
+KPX r jacute 25
+KPX r uhorndotbelow 10
+KPX r uhorntilde 10
+KPX r uhornhookabove 10
+KPX r uhorngrave 10
+KPX r uhornacute 10
+KPX r uhookabove 10
+KPX r udotbelow 10
+KPX r abrevedotbelow -15
+KPX r abrevegrave -15
+KPX r abreveacute -15
+KPX r acircumflexdotbelow -15
+KPX r acircumflextilde -15
+KPX r acircumflexhookabove -15
+KPX r acircumflexgrave -15
+KPX r acircumflexacute -15
+KPX r ahookabove -15
+KPX r adotbelow -15
+KPX r wdieresis 20
+KPX r wacute 20
+KPX r wgrave 20
+KPX r aeacute -15
+KPX r gacute -10
+KPX r gcaron -10
+KPX r zcaron -10
+KPX r zdotaccent -10
+KPX r zacute -10
+KPX r ycircumflex 15
+KPX r wcircumflex 20
+KPX r uogonek 10
+KPX r uhungarumlaut 10
+KPX r uring 10
+KPX r ubreve 10
+KPX r umacron 10
+KPX r utilde 10
+KPX r ncaron 15
+KPX r ncommaaccent 15
+KPX r nacute 15
+KPX r lslash -30
+KPX r lcaron -30
+KPX r lcommaaccent -30
+KPX r lacute -30
+KPX r kcommaaccent -30
+KPX r jcircumflex 25
+KPX r hcircumflex -20
+KPX r gcommaaccent -10
+KPX r gdotaccent -10
+KPX r gbreve -10
+KPX r gcircumflex -10
+KPX r dcaron -15
+KPX r aogonek -15
+KPX r abreve -15
+KPX r amacron -15
+KPX r ydieresis 15
+KPX r udieresis 10
+KPX r ucircumflex 10
+KPX r uacute 10
+KPX r ugrave 10
+KPX r ntilde 15
+KPX r ae -15
+KPX r aring -15
+KPX r adieresis -15
+KPX r atilde -15
+KPX r acircumflex -15
+KPX r aacute -15
+KPX r agrave -15
+KPX r z -10
+KPX r y 15
+KPX r x 10
+KPX r w 20
+KPX r v 20
+KPX r u 10
+KPX r q -15
+KPX r p 15
+KPX r n 15
+KPX r m 10
+KPX r l -30
+KPX r k -30
+KPX r j 25
+KPX r h -20
+KPX r g -10
+KPX r d -15
+KPX r a -15
+KPX r semicolon -30
+KPX r colon -20
+KPX r period -60
+KPX r hyphen -30
+KPX r comma -70
+KPX s quoteright -15
+KPX s uni021B -15
+KPX s tcaron -15
+KPX s t -15
+KPX t ohorndotbelow -10
+KPX t ohornhookabove -10
+KPX t ohorngrave -10
+KPX t ohornacute -10
+KPX t ocircumflexdotbelow -10
+KPX t ocircumflexhookabove -10
+KPX t ocircumflexgrave -10
+KPX t ocircumflexacute -10
+KPX t ohookabove -10
+KPX t odotbelow -10
+KPX t oogonek -10
+KPX t ohungarumlaut -10
+KPX t obreve -10
+KPX t omacron -10
+KPX t hcircumflex 15
+KPX t oslash -10
+KPX t odieresis -10
+KPX t otilde -10
+KPX t ocircumflex -10
+KPX t oacute -10
+KPX t ograve -10
+KPX t o -10
+KPX t h 15
+KPX t semicolon -25
+KPX u quoteright -20
+KPX v ohorndotbelow -40
+KPX v ohorntilde -40
+KPX v ohornhookabove -40
+KPX v ohorngrave -40
+KPX v ohornacute -40
+KPX v ocircumflexdotbelow -40
+KPX v ocircumflextilde -40
+KPX v ocircumflexhookabove -40
+KPX v ocircumflexgrave -40
+KPX v ocircumflexacute -40
+KPX v ohookabove -40
+KPX v odotbelow -40
+KPX v ecircumflexdotbelow -40
+KPX v ecircumflexhookabove -40
+KPX v ecircumflexgrave -40
+KPX v ecircumflexacute -40
+KPX v etilde -40
+KPX v ehookabove -40
+KPX v edotbelow -40
+KPX v abrevedotbelow -30
+KPX v abrevehookabove -30
+KPX v abrevegrave -30
+KPX v abreveacute -30
+KPX v acircumflexdotbelow -30
+KPX v acircumflextilde -30
+KPX v acircumflexhookabove -30
+KPX v acircumflexgrave -30
+KPX v acircumflexacute -30
+KPX v ahookabove -30
+KPX v adotbelow -30
+KPX v uni0219 -15
+KPX v aeacute -30
+KPX v gacute -40
+KPX v oogonek -40
+KPX v gcaron -40
+KPX v scaron -15
+KPX v scedilla -15
+KPX v scircumflex -15
+KPX v sacute -15
+KPX v oe -40
+KPX v ohungarumlaut -40
+KPX v obreve -40
+KPX v omacron -40
+KPX v lslash -35
+KPX v lcaron -35
+KPX v lcommaaccent -35
+KPX v lacute -35
+KPX v gcommaaccent -40
+KPX v gdotaccent -40
+KPX v gbreve -40
+KPX v gcircumflex -40
+KPX v ecaron -40
+KPX v eogonek -40
+KPX v edotaccent -40
+KPX v ebreve -40
+KPX v emacron -40
+KPX v ccaron -50
+KPX v cdotaccent -50
+KPX v ccircumflex -50
+KPX v cacute -50
+KPX v aogonek -30
+KPX v abreve -30
+KPX v amacron -30
+KPX v oslash -40
+KPX v odieresis -40
+KPX v otilde -40
+KPX v ocircumflex -40
+KPX v oacute -40
+KPX v ograve -40
+KPX v edieresis -40
+KPX v ecircumflex -40
+KPX v eacute -40
+KPX v egrave -40
+KPX v ccedilla -50
+KPX v ae -30
+KPX v aring -30
+KPX v adieresis -30
+KPX v atilde -30
+KPX v acircumflex -30
+KPX v aacute -30
+KPX v agrave -30
+KPX v s -15
+KPX v o -40
+KPX v l -35
+KPX v g -40
+KPX v e -40
+KPX v c -50
+KPX v a -30
+KPX v semicolon -35
+KPX v colon -20
+KPX v period -95
+KPX v hyphen -35
+KPX v comma -110
+KPX w uni0219 -15
+KPX w aeacute -30
+KPX w gacute -40
+KPX w oogonek -40
+KPX w gcaron -40
+KPX w scaron -15
+KPX w scedilla -15
+KPX w scircumflex -15
+KPX w sacute -15
+KPX w oe -40
+KPX w ohungarumlaut -40
+KPX w obreve -40
+KPX w omacron -40
+KPX w lslash -35
+KPX w lcaron -35
+KPX w lcommaaccent -35
+KPX w lacute -35
+KPX w gcommaaccent -40
+KPX w gdotaccent -40
+KPX w gbreve -40
+KPX w gcircumflex -40
+KPX w ecaron -40
+KPX w eogonek -40
+KPX w edotaccent -40
+KPX w ebreve -40
+KPX w emacron -40
+KPX w ccaron -50
+KPX w cdotaccent -50
+KPX w ccircumflex -50
+KPX w cacute -50
+KPX w aogonek -30
+KPX w amacron -30
+KPX w oslash -40
+KPX w odieresis -40
+KPX w edieresis -40
+KPX w ccedilla -50
+KPX w ae -30
+KPX w aring -30
+KPX w adieresis -30
+KPX w s -15
+KPX w o -40
+KPX w l -35
+KPX w g -40
+KPX w e -40
+KPX w c -50
+KPX w a -30
+KPX w semicolon -35
+KPX w colon -20
+KPX w period -90
+KPX w hyphen -30
+KPX w comma -105
+KPX x ohorndotbelow -30
+KPX x ohorntilde -30
+KPX x ohornhookabove -30
+KPX x ohorngrave -30
+KPX x ohornacute -30
+KPX x ocircumflexdotbelow -30
+KPX x ocircumflexhookabove -30
+KPX x ocircumflexgrave -30
+KPX x ocircumflexacute -30
+KPX x ohookabove -30
+KPX x odotbelow -30
+KPX x ecircumflexdotbelow -25
+KPX x ecircumflexhookabove -25
+KPX x ecircumflexgrave -25
+KPX x ecircumflexacute -25
+KPX x etilde -25
+KPX x ehookabove -25
+KPX x edotbelow -25
+KPX x oogonek -30
+KPX x ohungarumlaut -30
+KPX x obreve -30
+KPX x omacron -30
+KPX x ecaron -25
+KPX x eogonek -25
+KPX x edotaccent -25
+KPX x ebreve -25
+KPX x emacron -25
+KPX x ccaron -25
+KPX x cdotaccent -25
+KPX x ccircumflex -25
+KPX x cacute -25
+KPX x oslash -30
+KPX x odieresis -30
+KPX x otilde -30
+KPX x ocircumflex -30
+KPX x oacute -30
+KPX x ograve -30
+KPX x edieresis -25
+KPX x ecircumflex -25
+KPX x eacute -25
+KPX x egrave -25
+KPX x ccedilla -25
+KPX x q -30
+KPX x o -30
+KPX x e -25
+KPX x c -25
+KPX y ecircumflexdotbelow -35
+KPX y ecircumflextilde -35
+KPX y ecircumflexhookabove -35
+KPX y ecircumflexgrave -35
+KPX y ecircumflexacute -35
+KPX y aeacute -30
+KPX y gacute -35
+KPX y oogonek -35
+KPX y gcaron -35
+KPX y oe -40
+KPX y ohungarumlaut -35
+KPX y obreve -35
+KPX y omacron -35
+KPX y lslash -25
+KPX y lcaron -25
+KPX y lcommaaccent -25
+KPX y lacute -25
+KPX y gcommaaccent -35
+KPX y gdotaccent -35
+KPX y gbreve -35
+KPX y gcircumflex -35
+KPX y ecaron -35
+KPX y eogonek -35
+KPX y edotaccent -35
+KPX y ebreve -35
+KPX y emacron -35
+KPX y ccaron -45
+KPX y cdotaccent -45
+KPX y ccircumflex -45
+KPX y cacute -45
+KPX y aogonek -25
+KPX y amacron -25
+KPX y oslash -35
+KPX y odieresis -35
+KPX y edieresis -35
+KPX y ecircumflex -35
+KPX y ccedilla -45
+KPX y ae -30
+KPX y aring -25
+KPX y adieresis -25
+KPX y o -35
+KPX y l -25
+KPX y g -35
+KPX y e -35
+KPX y c -45
+KPX y a -25
+KPX y semicolon -30
+KPX y colon -15
+KPX y period -90
+KPX y hyphen -25
+KPX y comma -105
+KPX guillemotright Wdieresis -80
+KPX guillemotright Wacute -80
+KPX guillemotright Wgrave -80
+KPX guillemotright uni021A -125
+KPX guillemotright AEacute -80
+KPX guillemotright Ydieresis -140
+KPX guillemotright Ycircumflex -140
+KPX guillemotright Wcircumflex -80
+KPX guillemotright Tcaron -125
+KPX guillemotright Aogonek -85
+KPX guillemotright Amacron -85
+KPX guillemotright AE -80
+KPX guillemotright Aring -85
+KPX guillemotright Adieresis -85
+KPX guillemotright Y -140
+KPX guillemotright W -80
+KPX guillemotright V -115
+KPX guillemotright T -125
+KPX guillemotright A -85
+KPX guillemotright T_h -125
+KPX Agrave y.sc -75
+KPX Agrave u.sc -60
+KPX Agrave o.sc -60
+KPX Agrave y -90
+KPX Agrave u -45
+KPX Agrave o -35
+KPX Agrave Y -90
+KPX Agrave U -75
+KPX Agrave O -70
+KPX Aacute y.sc -75
+KPX Aacute u.sc -60
+KPX Aacute t.sc -60
+KPX Aacute o.sc -60
+KPX Aacute c.sc -60
+KPX Aacute y -90
+KPX Aacute u -45
+KPX Aacute t -40
+KPX Aacute o -35
+KPX Aacute c -35
+KPX Aacute Y -90
+KPX Aacute U -75
+KPX Aacute T -70
+KPX Aacute O -70
+KPX Aacute C -70
+KPX Aacute T_h -70
+KPX Acircumflex y.sc -75
+KPX Acircumflex u.sc -60
+KPX Acircumflex y -90
+KPX Acircumflex u -45
+KPX Acircumflex Y -90
+KPX Acircumflex U -75
+KPX Atilde y.sc -75
+KPX Atilde o.sc -60
+KPX Atilde y -90
+KPX Atilde o -35
+KPX Atilde Y -90
+KPX Atilde O -70
+KPX Adieresis ydieresis.sc -75
+KPX Adieresis udieresis.sc -60
+KPX Adieresis ucircumflex.sc -60
+KPX Adieresis oslash.sc -60
+KPX Adieresis odieresis.sc -60
+KPX Adieresis ccedilla.sc -60
+KPX Adieresis y.sc -75
+KPX Adieresis w.sc -85
+KPX Adieresis v.sc -115
+KPX Adieresis u.sc -60
+KPX Adieresis t.sc -60
+KPX Adieresis q.sc -55
+KPX Adieresis o.sc -60
+KPX Adieresis g.sc -60
+KPX Adieresis c.sc -60
+KPX Adieresis ycircumflex.sc -75
+KPX Adieresis wgrave.sc -85
+KPX Adieresis wdieresis.sc -85
+KPX Adieresis wcircumflex.sc -85
+KPX Adieresis wacute.sc -85
+KPX Adieresis uring.sc -60
+KPX Adieresis uogonek.sc -60
+KPX Adieresis umacron.sc -60
+KPX Adieresis uhungarumlaut.sc -60
+KPX Adieresis ubreve.sc -60
+KPX Adieresis uni021B.sc -60
+KPX Adieresis tcaron.sc -60
+KPX Adieresis omacron.sc -60
+KPX Adieresis ohungarumlaut.sc -60
+KPX Adieresis obreve.sc -60
+KPX Adieresis gdotaccent.sc -60
+KPX Adieresis gcommaaccent.sc -60
+KPX Adieresis gcircumflex.sc -60
+KPX Adieresis gbreve.sc -60
+KPX Adieresis cdotaccent.sc -60
+KPX Adieresis ccircumflex.sc -60
+KPX Adieresis ccaron.sc -60
+KPX Adieresis cacute.sc -60
+KPX Adieresis oogonek.sc -60
+KPX Adieresis gcaron.sc -60
+KPX Adieresis gacute.sc -60
+KPX Adieresis guilsinglleft -90
+KPX Adieresis quotedblright -125
+KPX Adieresis quoteright -120
+KPX Adieresis wdieresis -80
+KPX Adieresis Wdieresis -100
+KPX Adieresis wacute -80
+KPX Adieresis Wacute -100
+KPX Adieresis wgrave -80
+KPX Adieresis Wgrave -100
+KPX Adieresis uni021B -40
+KPX Adieresis uni021A -70
+KPX Adieresis gacute -25
+KPX Adieresis Gacute -70
+KPX Adieresis oogonek -35
+KPX Adieresis Oogonek -70
+KPX Adieresis gcaron -25
+KPX Adieresis Gcaron -70
+KPX Adieresis Ydieresis -90
+KPX Adieresis ycircumflex -90
+KPX Adieresis Ycircumflex -90
+KPX Adieresis wcircumflex -80
+KPX Adieresis Wcircumflex -100
+KPX Adieresis uogonek -45
+KPX Adieresis Uogonek -75
+KPX Adieresis uhungarumlaut -45
+KPX Adieresis Uhungarumlaut -75
+KPX Adieresis uring -45
+KPX Adieresis Uring -75
+KPX Adieresis ubreve -45
+KPX Adieresis Ubreve -75
+KPX Adieresis umacron -45
+KPX Adieresis Umacron -75
+KPX Adieresis tcaron -40
+KPX Adieresis Tcaron -70
+KPX Adieresis ohungarumlaut -35
+KPX Adieresis Ohungarumlaut -70
+KPX Adieresis obreve -35
+KPX Adieresis Obreve -70
+KPX Adieresis omacron -35
+KPX Adieresis Omacron -70
+KPX Adieresis gcommaaccent -25
+KPX Adieresis Gcommaaccent -70
+KPX Adieresis gdotaccent -25
+KPX Adieresis Gdotaccent -70
+KPX Adieresis gbreve -25
+KPX Adieresis Gbreve -70
+KPX Adieresis gcircumflex -25
+KPX Adieresis Gcircumflex -70
+KPX Adieresis ecaron -30
+KPX Adieresis eogonek -30
+KPX Adieresis edotaccent -30
+KPX Adieresis ebreve -30
+KPX Adieresis emacron -30
+KPX Adieresis dcaron -35
+KPX Adieresis ccaron -35
+KPX Adieresis Ccaron -70
+KPX Adieresis cdotaccent -35
+KPX Adieresis Cdotaccent -70
+KPX Adieresis ccircumflex -35
+KPX Adieresis Ccircumflex -70
+KPX Adieresis cacute -35
+KPX Adieresis Cacute -70
+KPX Adieresis ydieresis -90
+KPX Adieresis udieresis -45
+KPX Adieresis ucircumflex -45
+KPX Adieresis oslash -35
+KPX Adieresis odieresis -35
+KPX Adieresis edieresis -30
+KPX Adieresis ccedilla -35
+KPX Adieresis Udieresis -75
+KPX Adieresis Ucircumflex -75
+KPX Adieresis Oslash -70
+KPX Adieresis Odieresis -70
+KPX Adieresis Ccedilla -70
+KPX Adieresis guillemotleft -85
+KPX Adieresis y -90
+KPX Adieresis w -80
+KPX Adieresis v -85
+KPX Adieresis u -45
+KPX Adieresis t -40
+KPX Adieresis q -35
+KPX Adieresis o -35
+KPX Adieresis g -25
+KPX Adieresis e -30
+KPX Adieresis d -35
+KPX Adieresis c -35
+KPX Adieresis b -15
+KPX Adieresis Y -90
+KPX Adieresis W -100
+KPX Adieresis V -140
+KPX Adieresis U -75
+KPX Adieresis T -70
+KPX Adieresis Q -65
+KPX Adieresis O -70
+KPX Adieresis G -70
+KPX Adieresis C -70
+KPX Adieresis period -25
+KPX Adieresis hyphen -35
+KPX Adieresis comma -35
+KPX Adieresis T_h -70
+KPX Aring ydieresis.sc -75
+KPX Aring udieresis.sc -60
+KPX Aring ucircumflex.sc -60
+KPX Aring oslash.sc -60
+KPX Aring odieresis.sc -60
+KPX Aring ccedilla.sc -60
+KPX Aring y.sc -75
+KPX Aring w.sc -85
+KPX Aring v.sc -115
+KPX Aring u.sc -60
+KPX Aring t.sc -60
+KPX Aring q.sc -55
+KPX Aring o.sc -60
+KPX Aring g.sc -60
+KPX Aring c.sc -60
+KPX Aring ycircumflex.sc -75
+KPX Aring wgrave.sc -85
+KPX Aring wdieresis.sc -85
+KPX Aring wcircumflex.sc -85
+KPX Aring wacute.sc -85
+KPX Aring uring.sc -60
+KPX Aring uogonek.sc -60
+KPX Aring umacron.sc -60
+KPX Aring uhungarumlaut.sc -60
+KPX Aring ubreve.sc -60
+KPX Aring uni021B.sc -60
+KPX Aring tcaron.sc -60
+KPX Aring omacron.sc -60
+KPX Aring ohungarumlaut.sc -60
+KPX Aring obreve.sc -60
+KPX Aring gdotaccent.sc -60
+KPX Aring gcommaaccent.sc -60
+KPX Aring gcircumflex.sc -60
+KPX Aring gbreve.sc -60
+KPX Aring cdotaccent.sc -60
+KPX Aring ccircumflex.sc -60
+KPX Aring ccaron.sc -60
+KPX Aring cacute.sc -60
+KPX Aring oogonek.sc -60
+KPX Aring gcaron.sc -60
+KPX Aring gacute.sc -60
+KPX Aring guilsinglleft -90
+KPX Aring quotedblright -125
+KPX Aring quoteright -120
+KPX Aring wdieresis -80
+KPX Aring Wdieresis -100
+KPX Aring wacute -80
+KPX Aring Wacute -100
+KPX Aring wgrave -80
+KPX Aring Wgrave -100
+KPX Aring uni021B -40
+KPX Aring uni021A -70
+KPX Aring gacute -25
+KPX Aring Gacute -70
+KPX Aring oogonek -35
+KPX Aring Oogonek -70
+KPX Aring gcaron -25
+KPX Aring Gcaron -70
+KPX Aring Ydieresis -90
+KPX Aring ycircumflex -90
+KPX Aring Ycircumflex -90
+KPX Aring wcircumflex -80
+KPX Aring Wcircumflex -100
+KPX Aring uogonek -45
+KPX Aring Uogonek -75
+KPX Aring uhungarumlaut -45
+KPX Aring Uhungarumlaut -75
+KPX Aring uring -45
+KPX Aring Uring -75
+KPX Aring ubreve -45
+KPX Aring Ubreve -75
+KPX Aring umacron -45
+KPX Aring Umacron -75
+KPX Aring tcaron -40
+KPX Aring Tcaron -70
+KPX Aring ohungarumlaut -35
+KPX Aring Ohungarumlaut -70
+KPX Aring obreve -35
+KPX Aring Obreve -70
+KPX Aring omacron -35
+KPX Aring Omacron -70
+KPX Aring gcommaaccent -25
+KPX Aring Gcommaaccent -70
+KPX Aring gdotaccent -25
+KPX Aring Gdotaccent -70
+KPX Aring gbreve -25
+KPX Aring Gbreve -70
+KPX Aring gcircumflex -25
+KPX Aring Gcircumflex -70
+KPX Aring ecaron -30
+KPX Aring eogonek -30
+KPX Aring edotaccent -30
+KPX Aring ebreve -30
+KPX Aring emacron -30
+KPX Aring dcaron -35
+KPX Aring ccaron -35
+KPX Aring Ccaron -70
+KPX Aring cdotaccent -35
+KPX Aring Cdotaccent -70
+KPX Aring ccircumflex -35
+KPX Aring Ccircumflex -70
+KPX Aring cacute -35
+KPX Aring Cacute -70
+KPX Aring ydieresis -90
+KPX Aring udieresis -45
+KPX Aring ucircumflex -45
+KPX Aring oslash -35
+KPX Aring odieresis -35
+KPX Aring edieresis -30
+KPX Aring ccedilla -35
+KPX Aring Udieresis -75
+KPX Aring Ucircumflex -75
+KPX Aring Oslash -70
+KPX Aring Odieresis -70
+KPX Aring Ccedilla -70
+KPX Aring guillemotleft -85
+KPX Aring y -90
+KPX Aring w -80
+KPX Aring v -85
+KPX Aring u -45
+KPX Aring t -40
+KPX Aring q -35
+KPX Aring o -35
+KPX Aring g -25
+KPX Aring e -30
+KPX Aring d -35
+KPX Aring c -35
+KPX Aring b -15
+KPX Aring Y -90
+KPX Aring W -100
+KPX Aring V -140
+KPX Aring U -75
+KPX Aring T -70
+KPX Aring Q -65
+KPX Aring O -70
+KPX Aring G -70
+KPX Aring C -70
+KPX Aring period -25
+KPX Aring hyphen -35
+KPX Aring comma -35
+KPX Aring T_h -70
+KPX Ccedilla oslash.sc -35
+KPX Ccedilla odieresis.sc -35
+KPX Ccedilla aring.sc -10
+KPX Ccedilla adieresis.sc -10
+KPX Ccedilla o.sc -35
+KPX Ccedilla k.sc -10
+KPX Ccedilla h.sc -10
+KPX Ccedilla a.sc -10
+KPX Ccedilla omacron.sc -35
+KPX Ccedilla ohungarumlaut.sc -35
+KPX Ccedilla obreve.sc -35
+KPX Ccedilla kcommaaccent.sc -10
+KPX Ccedilla hcircumflex.sc -10
+KPX Ccedilla aogonek.sc -10
+KPX Ccedilla amacron.sc -10
+KPX Ccedilla oogonek.sc -35
+KPX Ccedilla Oogonek -40
+KPX Ccedilla Ohungarumlaut -40
+KPX Ccedilla Obreve -40
+KPX Ccedilla Omacron -40
+KPX Ccedilla Kcommaaccent -10
+KPX Ccedilla Hcircumflex -10
+KPX Ccedilla Aogonek -15
+KPX Ccedilla Amacron -15
+KPX Ccedilla Oslash -40
+KPX Ccedilla Odieresis -40
+KPX Ccedilla Aring -15
+KPX Ccedilla Adieresis -15
+KPX Ccedilla O -40
+KPX Ccedilla K -10
+KPX Ccedilla H -10
+KPX Ccedilla A -15
+KPX Ntilde oslash.sc -20
+KPX Ntilde odieresis.sc -20
+KPX Ntilde ccedilla.sc -25
+KPX Ntilde ae.sc -25
+KPX Ntilde aring.sc -35
+KPX Ntilde adieresis.sc -35
+KPX Ntilde o.sc -20
+KPX Ntilde g.sc -25
+KPX Ntilde c.sc -25
+KPX Ntilde a.sc -35
+KPX Ntilde omacron.sc -20
+KPX Ntilde ohungarumlaut.sc -20
+KPX Ntilde obreve.sc -20
+KPX Ntilde gdotaccent.sc -25
+KPX Ntilde gcommaaccent.sc -25
+KPX Ntilde gcircumflex.sc -25
+KPX Ntilde gbreve.sc -25
+KPX Ntilde cdotaccent.sc -25
+KPX Ntilde ccircumflex.sc -25
+KPX Ntilde ccaron.sc -25
+KPX Ntilde cacute.sc -25
+KPX Ntilde aeacute.sc -25
+KPX Ntilde aogonek.sc -35
+KPX Ntilde amacron.sc -35
+KPX Ntilde oogonek.sc -20
+KPX Ntilde gcaron.sc -25
+KPX Ntilde gacute.sc -25
+KPX Ntilde aeacute -35
+KPX Ntilde AEacute -30
+KPX Ntilde Gacute -30
+KPX Ntilde oogonek -30
+KPX Ntilde Oogonek -25
+KPX Ntilde Gcaron -30
+KPX Ntilde uogonek -40
+KPX Ntilde uhungarumlaut -40
+KPX Ntilde uring -40
+KPX Ntilde ubreve -40
+KPX Ntilde umacron -40
+KPX Ntilde ohungarumlaut -30
+KPX Ntilde Ohungarumlaut -25
+KPX Ntilde obreve -30
+KPX Ntilde Obreve -25
+KPX Ntilde omacron -30
+KPX Ntilde Omacron -25
+KPX Ntilde Gcommaaccent -30
+KPX Ntilde Gdotaccent -30
+KPX Ntilde Gbreve -30
+KPX Ntilde Gcircumflex -30
+KPX Ntilde ecaron -25
+KPX Ntilde eogonek -25
+KPX Ntilde edotaccent -25
+KPX Ntilde ebreve -25
+KPX Ntilde emacron -25
+KPX Ntilde Ccaron -30
+KPX Ntilde Cdotaccent -30
+KPX Ntilde Ccircumflex -30
+KPX Ntilde Cacute -30
+KPX Ntilde aogonek -30
+KPX Ntilde Aogonek -40
+KPX Ntilde amacron -30
+KPX Ntilde Amacron -40
+KPX Ntilde udieresis -40
+KPX Ntilde ucircumflex -40
+KPX Ntilde oslash -30
+KPX Ntilde odieresis -30
+KPX Ntilde edieresis -25
+KPX Ntilde ae -35
+KPX Ntilde aring -30
+KPX Ntilde adieresis -30
+KPX Ntilde Oslash -25
+KPX Ntilde Odieresis -25
+KPX Ntilde Ccedilla -30
+KPX Ntilde AE -30
+KPX Ntilde Aring -40
+KPX Ntilde Adieresis -40
+KPX Ntilde u -40
+KPX Ntilde o -30
+KPX Ntilde e -25
+KPX Ntilde a -30
+KPX Ntilde O -25
+KPX Ntilde G -30
+KPX Ntilde C -30
+KPX Ntilde A -40
+KPX Ntilde period -30
+KPX Ntilde comma -45
+KPX Ograve a.sc -60
+KPX Ograve A -75
+KPX Oacute t.sc -10
+KPX Oacute a.sc -60
+KPX Oacute T -15
+KPX Oacute A -75
+KPX Oacute T_h -15
+KPX Odieresis ydieresis.sc -45
+KPX Odieresis ae.sc -55
+KPX Odieresis aring.sc -60
+KPX Odieresis adieresis.sc -60
+KPX Odieresis y.sc -45
+KPX Odieresis x.sc -50
+KPX Odieresis w.sc -35
+KPX Odieresis v.sc -45
+KPX Odieresis t.sc -10
+KPX Odieresis a.sc -60
+KPX Odieresis ycircumflex.sc -45
+KPX Odieresis wgrave.sc -35
+KPX Odieresis wdieresis.sc -35
+KPX Odieresis wcircumflex.sc -35
+KPX Odieresis wacute.sc -35
+KPX Odieresis uni021B.sc -10
+KPX Odieresis tcaron.sc -10
+KPX Odieresis aeacute.sc -55
+KPX Odieresis aogonek.sc -60
+KPX Odieresis amacron.sc -60
+KPX Odieresis Wdieresis -45
+KPX Odieresis Wacute -45
+KPX Odieresis Wgrave -45
+KPX Odieresis uni021A -15
+KPX Odieresis AEacute -65
+KPX Odieresis Ydieresis -55
+KPX Odieresis Ycircumflex -55
+KPX Odieresis Wcircumflex -45
+KPX Odieresis Tcaron -15
+KPX Odieresis Aogonek -75
+KPX Odieresis Amacron -75
+KPX Odieresis AE -65
+KPX Odieresis Aring -75
+KPX Odieresis Adieresis -75
+KPX Odieresis Y -55
+KPX Odieresis X -60
+KPX Odieresis W -45
+KPX Odieresis V -55
+KPX Odieresis T -15
+KPX Odieresis A -75
+KPX Odieresis T_h -15
+KPX Oslash ydieresis.sc -45
+KPX Oslash ae.sc -55
+KPX Oslash aring.sc -60
+KPX Oslash adieresis.sc -60
+KPX Oslash y.sc -45
+KPX Oslash x.sc -50
+KPX Oslash w.sc -35
+KPX Oslash v.sc -45
+KPX Oslash t.sc -10
+KPX Oslash a.sc -60
+KPX Oslash ycircumflex.sc -45
+KPX Oslash wgrave.sc -35
+KPX Oslash wdieresis.sc -35
+KPX Oslash wcircumflex.sc -35
+KPX Oslash wacute.sc -35
+KPX Oslash uni021B.sc -10
+KPX Oslash tcaron.sc -10
+KPX Oslash aeacute.sc -55
+KPX Oslash aogonek.sc -60
+KPX Oslash amacron.sc -60
+KPX Oslash Wdieresis -45
+KPX Oslash Wacute -45
+KPX Oslash Wgrave -45
+KPX Oslash uni021A -15
+KPX Oslash AEacute -65
+KPX Oslash Ydieresis -55
+KPX Oslash Ycircumflex -55
+KPX Oslash Wcircumflex -45
+KPX Oslash Tcaron -15
+KPX Oslash Aogonek -75
+KPX Oslash Amacron -75
+KPX Oslash AE -65
+KPX Oslash Aring -75
+KPX Oslash Adieresis -75
+KPX Oslash Y -55
+KPX Oslash X -60
+KPX Oslash W -45
+KPX Oslash V -55
+KPX Oslash T -15
+KPX Oslash A -75
+KPX Oslash T_h -15
+KPX Ugrave aring.sc -35
+KPX Ugrave adieresis.sc -35
+KPX Ugrave atilde.sc -35
+KPX Ugrave acircumflex.sc -35
+KPX Ugrave aacute.sc -50
+KPX Ugrave agrave.sc -35
+KPX Ugrave a.sc -65
+KPX Ugrave amacron.sc -35
+KPX Ugrave abreve.sc -35
+KPX Ugrave ahookabove.sc -35
+KPX Ugrave acircumflexdotbelow.sc -35
+KPX Ugrave abrevedotbelow.sc -35
+KPX Ugrave rdotaccent -20
+KPX Ugrave rcaron -20
+KPX Ugrave racute -30
+KPX Ugrave ncaron -20
+KPX Ugrave nacute -25
+KPX Ugrave ntilde -20
+KPX Ugrave n -35
+KPX Ugrave m -40
+KPX Ugrave A -80
+KPX Uacute aring.sc -35
+KPX Uacute adieresis.sc -35
+KPX Uacute atilde.sc -35
+KPX Uacute acircumflex.sc -35
+KPX Uacute aacute.sc -50
+KPX Uacute agrave.sc -35
+KPX Uacute a.sc -65
+KPX Uacute amacron.sc -35
+KPX Uacute abreve.sc -35
+KPX Uacute ahookabove.sc -35
+KPX Uacute acircumflexdotbelow.sc -35
+KPX Uacute abrevedotbelow.sc -35
+KPX Uacute rdotaccent -20
+KPX Uacute rcaron -20
+KPX Uacute racute -30
+KPX Uacute ncaron -20
+KPX Uacute nacute -25
+KPX Uacute ntilde -20
+KPX Uacute p -35
+KPX Uacute n -35
+KPX Uacute m -40
+KPX Uacute A -80
+KPX Ucircumflex ae.sc -60
+KPX Ucircumflex aring.sc -35
+KPX Ucircumflex adieresis.sc -35
+KPX Ucircumflex atilde.sc -35
+KPX Ucircumflex acircumflex.sc -35
+KPX Ucircumflex aacute.sc -50
+KPX Ucircumflex agrave.sc -35
+KPX Ucircumflex a.sc -65
+KPX Ucircumflex aeacute.sc -60
+KPX Ucircumflex aogonek.sc -65
+KPX Ucircumflex amacron.sc -35
+KPX Ucircumflex abreve.sc -35
+KPX Ucircumflex ahookabove.sc -35
+KPX Ucircumflex acircumflexdotbelow.sc -35
+KPX Ucircumflex abrevedotbelow.sc -35
+KPX Ucircumflex rdotaccent -20
+KPX Ucircumflex AEacute -70
+KPX Ucircumflex rcaron -20
+KPX Ucircumflex rcommaaccent -40
+KPX Ucircumflex racute -30
+KPX Ucircumflex ncaron -20
+KPX Ucircumflex ncommaaccent -35
+KPX Ucircumflex nacute -25
+KPX Ucircumflex Aogonek -80
+KPX Ucircumflex Amacron -80
+KPX Ucircumflex ntilde -20
+KPX Ucircumflex AE -70
+KPX Ucircumflex Aring -80
+KPX Ucircumflex Adieresis -80
+KPX Ucircumflex r -40
+KPX Ucircumflex p -35
+KPX Ucircumflex n -35
+KPX Ucircumflex m -40
+KPX Ucircumflex A -80
+KPX Ucircumflex period -50
+KPX Ucircumflex comma -65
+KPX Udieresis ae.sc -60
+KPX Udieresis aring.sc -35
+KPX Udieresis adieresis.sc -35
+KPX Udieresis atilde.sc -35
+KPX Udieresis acircumflex.sc -35
+KPX Udieresis aacute.sc -50
+KPX Udieresis agrave.sc -35
+KPX Udieresis a.sc -65
+KPX Udieresis aeacute.sc -60
+KPX Udieresis aogonek.sc -65
+KPX Udieresis amacron.sc -35
+KPX Udieresis abreve.sc -35
+KPX Udieresis ahookabove.sc -35
+KPX Udieresis acircumflexdotbelow.sc -35
+KPX Udieresis abrevedotbelow.sc -35
+KPX Udieresis rdotaccent -20
+KPX Udieresis AEacute -70
+KPX Udieresis rcaron -20
+KPX Udieresis rcommaaccent -40
+KPX Udieresis racute -30
+KPX Udieresis ncaron -20
+KPX Udieresis ncommaaccent -35
+KPX Udieresis nacute -25
+KPX Udieresis Aogonek -80
+KPX Udieresis Amacron -80
+KPX Udieresis ntilde -20
+KPX Udieresis AE -70
+KPX Udieresis Aring -80
+KPX Udieresis Adieresis -80
+KPX Udieresis r -40
+KPX Udieresis p -35
+KPX Udieresis n -35
+KPX Udieresis m -40
+KPX Udieresis A -80
+KPX Udieresis period -50
+KPX Udieresis comma -65
+KPX Yacute zdotaccent -67
+KPX Yacute zcaron -67
+KPX Yacute zacute -67
+KPX Yacute z -67
+KPX Yacute scircumflex -67
+KPX Yacute scedilla -67
+KPX Yacute scaron -67
+KPX Yacute sacute -67
+KPX Yacute s -67
+KPX Yacute cdotaccent -67
+KPX Yacute ccircumflex -67
+KPX Yacute ccedilla -67
+KPX Yacute ccaron -67
+KPX Yacute cacute -67
+KPX Yacute c -67
+KPX Yacute odieresis.sc -30
+KPX Yacute otilde.sc -30
+KPX Yacute ocircumflex.sc -30
+KPX Yacute oacute.sc -45
+KPX Yacute ograve.sc -30
+KPX Yacute ae.sc -80
+KPX Yacute aring.sc -30
+KPX Yacute adieresis.sc -30
+KPX Yacute atilde.sc -30
+KPX Yacute acircumflex.sc -30
+KPX Yacute aacute.sc -45
+KPX Yacute agrave.sc -30
+KPX Yacute c.sc -60
+KPX Yacute scircumflex.sc -15
+KPX Yacute sacute.sc -20
+KPX Yacute omacron.sc -30
+KPX Yacute ohungarumlaut.sc -30
+KPX Yacute obreve.sc -30
+KPX Yacute gdotaccent.sc -30
+KPX Yacute gcircumflex.sc -30
+KPX Yacute gbreve.sc -30
+KPX Yacute cdotaccent.sc -30
+KPX Yacute ccircumflex.sc -30
+KPX Yacute ccaron.sc -30
+KPX Yacute cacute.sc -45
+KPX Yacute aeacute.sc -80
+KPX Yacute amacron.sc -30
+KPX Yacute abreve.sc -30
+KPX Yacute scaron.sc -15
+KPX Yacute ohorntilde.sc -30
+KPX Yacute ohornhookabove.sc -30
+KPX Yacute ohorngrave.sc -30
+KPX Yacute ohorndotbelow.sc -30
+KPX Yacute ohornacute.sc -30
+KPX Yacute ohookabove.sc -30
+KPX Yacute oe.sc -40
+KPX Yacute ocircumflexdotbelow.sc -30
+KPX Yacute gcaron.sc -30
+KPX Yacute gacute.sc -45
+KPX Yacute ahookabove.sc -30
+KPX Yacute acircumflexdotbelow.sc -30
+KPX Yacute abrevedotbelow.sc -30
+KPX Yacute uhorndotbelow -40
+KPX Yacute uhorntilde -40
+KPX Yacute uhornhookabove -40
+KPX Yacute uhorngrave -40
+KPX Yacute uhornacute -40
+KPX Yacute uhookabove -40
+KPX Yacute ohorndotbelow -50
+KPX Yacute ohorntilde -50
+KPX Yacute ohornhookabove -50
+KPX Yacute ohorngrave -50
+KPX Yacute ohornacute -50
+KPX Yacute ocircumflexdotbelow -50
+KPX Yacute ohookabove -50
+KPX Yacute ecircumflexdotbelow -45
+KPX Yacute etilde -45
+KPX Yacute ehookabove -45
+KPX Yacute abrevedotbelow -45
+KPX Yacute acircumflexdotbelow -45
+KPX Yacute ahookabove -45
+KPX Yacute aeacute -75
+KPX Yacute AEacute -115
+KPX Yacute gacute -75
+KPX Yacute gcaron -50
+KPX Yacute uhungarumlaut -40
+KPX Yacute uring -40
+KPX Yacute ubreve -40
+KPX Yacute umacron -40
+KPX Yacute utilde -40
+KPX Yacute oe -70
+KPX Yacute OE -55
+KPX Yacute ohungarumlaut -50
+KPX Yacute obreve -50
+KPX Yacute omacron -50
+KPX Yacute gdotaccent -50
+KPX Yacute gbreve -50
+KPX Yacute gcircumflex -50
+KPX Yacute ecaron -45
+KPX Yacute edotaccent -45
+KPX Yacute ebreve -45
+KPX Yacute emacron -45
+KPX Yacute abreve -45
+KPX Yacute amacron -45
+KPX Yacute udieresis -40
+KPX Yacute ucircumflex -40
+KPX Yacute uacute -60
+KPX Yacute ugrave -40
+KPX Yacute odieresis -50
+KPX Yacute otilde -50
+KPX Yacute ocircumflex -50
+KPX Yacute oacute -70
+KPX Yacute ograve -50
+KPX Yacute iacute -10
+KPX Yacute edieresis -45
+KPX Yacute ecircumflex -45
+KPX Yacute eacute -70
+KPX Yacute egrave -45
+KPX Yacute ae -75
+KPX Yacute aring -45
+KPX Yacute adieresis -45
+KPX Yacute atilde -45
+KPX Yacute acircumflex -45
+KPX Yacute aacute -65
+KPX Yacute agrave -45
+KPX Yacute AE -115
+KPX Yacute i -25
+KPX Yacute C -70
+KPX agrave y -40
+KPX aacute y -40
+KPX acircumflex y -40
+KPX atilde y -40
+KPX adieresis jacute -20
+KPX adieresis quoteright -35
+KPX adieresis wdieresis -35
+KPX adieresis wacute -35
+KPX adieresis wgrave -35
+KPX adieresis ycircumflex -40
+KPX adieresis wcircumflex -35
+KPX adieresis jcircumflex -20
+KPX adieresis ydieresis -40
+KPX adieresis y -40
+KPX adieresis w -35
+KPX adieresis v -35
+KPX adieresis j -20
+KPX aring jacute -20
+KPX aring quoteright -35
+KPX aring wdieresis -35
+KPX aring wacute -35
+KPX aring wgrave -35
+KPX aring ycircumflex -40
+KPX aring wcircumflex -35
+KPX aring jcircumflex -20
+KPX aring ydieresis -40
+KPX aring y -40
+KPX aring w -35
+KPX aring v -35
+KPX aring j -20
+KPX ae ycircumflex -15
+KPX ae ydieresis -15
+KPX ae y -15
+KPX edieresis wdieresis -10
+KPX edieresis wacute -10
+KPX edieresis wgrave -10
+KPX edieresis ycircumflex -15
+KPX edieresis wcircumflex -10
+KPX edieresis ydieresis -15
+KPX edieresis y -15
+KPX edieresis w -10
+KPX edieresis v -10
+KPX iacute T -30
+KPX iacute T_h -30
+KPX icircumflex jacute -15
+KPX icircumflex uni021A -30
+KPX icircumflex Tcaron -30
+KPX icircumflex jcircumflex -15
+KPX icircumflex j -15
+KPX icircumflex T -30
+KPX icircumflex T_h -30
+KPX idieresis jacute -15
+KPX idieresis uni021A -30
+KPX idieresis Tcaron -30
+KPX idieresis jcircumflex -15
+KPX idieresis j -15
+KPX idieresis T -30
+KPX idieresis T_h -30
+KPX ntilde quoteright -30
+KPX ntilde wdieresis -35
+KPX ntilde wacute -35
+KPX ntilde wgrave -35
+KPX ntilde uni021A -60
+KPX ntilde ycircumflex -35
+KPX ntilde wcircumflex -35
+KPX ntilde Tcaron -60
+KPX ntilde ydieresis -35
+KPX ntilde y -35
+KPX ntilde w -35
+KPX ntilde v -35
+KPX ntilde p -20
+KPX ntilde T -60
+KPX ntilde T_h -60
+KPX oacute t -15
+KPX oacute T -100
+KPX oacute T_h -100
+KPX odieresis quoteright -20
+KPX odieresis wdieresis -25
+KPX odieresis wacute -25
+KPX odieresis wgrave -25
+KPX odieresis uni021B -15
+KPX odieresis uni021A -100
+KPX odieresis ycircumflex -30
+KPX odieresis wcircumflex -25
+KPX odieresis tcaron -15
+KPX odieresis Tcaron -100
+KPX odieresis ydieresis -30
+KPX odieresis y -30
+KPX odieresis x -30
+KPX odieresis w -25
+KPX odieresis v -25
+KPX odieresis t -15
+KPX odieresis T -100
+KPX odieresis T_h -100
+KPX oslash quoteright -20
+KPX oslash wdieresis -25
+KPX oslash wacute -25
+KPX oslash wgrave -25
+KPX oslash uni021B -15
+KPX oslash uni021A -100
+KPX oslash ycircumflex -30
+KPX oslash wcircumflex -25
+KPX oslash tcaron -15
+KPX oslash Tcaron -100
+KPX oslash ydieresis -30
+KPX oslash y -30
+KPX oslash x -30
+KPX oslash w -25
+KPX oslash v -25
+KPX oslash t -15
+KPX oslash T -100
+KPX oslash T_h -100
+KPX ucircumflex quoteright -20
+KPX udieresis quoteright -20
+KPX yacute aeacute -30
+KPX yacute oe -40
+KPX yacute ae -30
+KPX yacute c -45
+KPX ydieresis aeacute -30
+KPX ydieresis gacute -35
+KPX ydieresis oogonek -35
+KPX ydieresis gcaron -35
+KPX ydieresis oe -40
+KPX ydieresis ohungarumlaut -35
+KPX ydieresis obreve -35
+KPX ydieresis omacron -35
+KPX ydieresis lslash -25
+KPX ydieresis lcaron -25
+KPX ydieresis lcommaaccent -25
+KPX ydieresis lacute -25
+KPX ydieresis gcommaaccent -35
+KPX ydieresis gdotaccent -35
+KPX ydieresis gbreve -35
+KPX ydieresis gcircumflex -35
+KPX ydieresis ecaron -35
+KPX ydieresis eogonek -35
+KPX ydieresis edotaccent -35
+KPX ydieresis ebreve -35
+KPX ydieresis emacron -35
+KPX ydieresis ccaron -45
+KPX ydieresis cdotaccent -45
+KPX ydieresis ccircumflex -45
+KPX ydieresis cacute -45
+KPX ydieresis aogonek -25
+KPX ydieresis amacron -25
+KPX ydieresis oslash -35
+KPX ydieresis odieresis -35
+KPX ydieresis edieresis -35
+KPX ydieresis ccedilla -45
+KPX ydieresis ae -30
+KPX ydieresis aring -25
+KPX ydieresis adieresis -25
+KPX ydieresis o -35
+KPX ydieresis l -25
+KPX ydieresis g -35
+KPX ydieresis e -35
+KPX ydieresis c -45
+KPX ydieresis a -25
+KPX ydieresis semicolon -30
+KPX ydieresis colon -15
+KPX ydieresis period -90
+KPX ydieresis hyphen -25
+KPX ydieresis comma -105
+KPX Amacron ydieresis.sc -75
+KPX Amacron udieresis.sc -60
+KPX Amacron ucircumflex.sc -60
+KPX Amacron oslash.sc -60
+KPX Amacron odieresis.sc -60
+KPX Amacron ccedilla.sc -60
+KPX Amacron y.sc -75
+KPX Amacron w.sc -85
+KPX Amacron v.sc -115
+KPX Amacron u.sc -60
+KPX Amacron t.sc -60
+KPX Amacron q.sc -55
+KPX Amacron o.sc -60
+KPX Amacron g.sc -60
+KPX Amacron c.sc -60
+KPX Amacron ycircumflex.sc -75
+KPX Amacron wgrave.sc -85
+KPX Amacron wdieresis.sc -85
+KPX Amacron wcircumflex.sc -85
+KPX Amacron wacute.sc -85
+KPX Amacron uring.sc -60
+KPX Amacron uogonek.sc -60
+KPX Amacron umacron.sc -60
+KPX Amacron uhungarumlaut.sc -60
+KPX Amacron ubreve.sc -60
+KPX Amacron uni021B.sc -60
+KPX Amacron tcaron.sc -60
+KPX Amacron omacron.sc -60
+KPX Amacron ohungarumlaut.sc -60
+KPX Amacron obreve.sc -60
+KPX Amacron gdotaccent.sc -60
+KPX Amacron gcommaaccent.sc -60
+KPX Amacron gcircumflex.sc -60
+KPX Amacron gbreve.sc -60
+KPX Amacron cdotaccent.sc -60
+KPX Amacron ccircumflex.sc -60
+KPX Amacron ccaron.sc -60
+KPX Amacron cacute.sc -60
+KPX Amacron oogonek.sc -60
+KPX Amacron gcaron.sc -60
+KPX Amacron gacute.sc -60
+KPX Amacron guilsinglleft -90
+KPX Amacron quotedblright -125
+KPX Amacron quoteright -120
+KPX Amacron wdieresis -80
+KPX Amacron Wdieresis -100
+KPX Amacron wacute -80
+KPX Amacron Wacute -100
+KPX Amacron wgrave -80
+KPX Amacron Wgrave -100
+KPX Amacron uni021B -40
+KPX Amacron uni021A -70
+KPX Amacron gacute -25
+KPX Amacron Gacute -70
+KPX Amacron oogonek -35
+KPX Amacron Oogonek -70
+KPX Amacron gcaron -25
+KPX Amacron Gcaron -70
+KPX Amacron Ydieresis -90
+KPX Amacron ycircumflex -90
+KPX Amacron Ycircumflex -90
+KPX Amacron wcircumflex -80
+KPX Amacron Wcircumflex -100
+KPX Amacron uogonek -45
+KPX Amacron Uogonek -75
+KPX Amacron uhungarumlaut -45
+KPX Amacron Uhungarumlaut -75
+KPX Amacron uring -45
+KPX Amacron Uring -75
+KPX Amacron ubreve -45
+KPX Amacron Ubreve -75
+KPX Amacron umacron -45
+KPX Amacron Umacron -75
+KPX Amacron tcaron -40
+KPX Amacron Tcaron -70
+KPX Amacron ohungarumlaut -35
+KPX Amacron Ohungarumlaut -70
+KPX Amacron obreve -35
+KPX Amacron Obreve -70
+KPX Amacron omacron -35
+KPX Amacron Omacron -70
+KPX Amacron gcommaaccent -25
+KPX Amacron Gcommaaccent -70
+KPX Amacron gdotaccent -25
+KPX Amacron Gdotaccent -70
+KPX Amacron gbreve -25
+KPX Amacron Gbreve -70
+KPX Amacron gcircumflex -25
+KPX Amacron Gcircumflex -70
+KPX Amacron ecaron -30
+KPX Amacron eogonek -30
+KPX Amacron edotaccent -30
+KPX Amacron ebreve -30
+KPX Amacron emacron -30
+KPX Amacron dcaron -35
+KPX Amacron ccaron -35
+KPX Amacron Ccaron -70
+KPX Amacron cdotaccent -35
+KPX Amacron Cdotaccent -70
+KPX Amacron ccircumflex -35
+KPX Amacron Ccircumflex -70
+KPX Amacron cacute -35
+KPX Amacron Cacute -70
+KPX Amacron ydieresis -90
+KPX Amacron udieresis -45
+KPX Amacron ucircumflex -45
+KPX Amacron oslash -35
+KPX Amacron odieresis -35
+KPX Amacron edieresis -30
+KPX Amacron ccedilla -35
+KPX Amacron Udieresis -75
+KPX Amacron Ucircumflex -75
+KPX Amacron Oslash -70
+KPX Amacron Odieresis -70
+KPX Amacron Ccedilla -70
+KPX Amacron guillemotleft -85
+KPX Amacron y -90
+KPX Amacron w -80
+KPX Amacron v -85
+KPX Amacron u -45
+KPX Amacron t -40
+KPX Amacron q -35
+KPX Amacron o -35
+KPX Amacron g -25
+KPX Amacron e -30
+KPX Amacron d -35
+KPX Amacron c -35
+KPX Amacron b -15
+KPX Amacron Y -90
+KPX Amacron W -100
+KPX Amacron V -140
+KPX Amacron U -75
+KPX Amacron T -70
+KPX Amacron Q -65
+KPX Amacron O -70
+KPX Amacron G -70
+KPX Amacron C -70
+KPX Amacron period -25
+KPX Amacron hyphen -35
+KPX Amacron comma -35
+KPX Amacron T_h -70
+KPX amacron jacute -20
+KPX amacron quoteright -35
+KPX amacron wdieresis -35
+KPX amacron wacute -35
+KPX amacron wgrave -35
+KPX amacron ycircumflex -40
+KPX amacron wcircumflex -35
+KPX amacron jcircumflex -20
+KPX amacron ydieresis -40
+KPX amacron y -40
+KPX amacron w -35
+KPX amacron v -35
+KPX amacron j -20
+KPX Aogonek ydieresis.sc -75
+KPX Aogonek udieresis.sc -60
+KPX Aogonek ucircumflex.sc -60
+KPX Aogonek oslash.sc -60
+KPX Aogonek odieresis.sc -60
+KPX Aogonek ccedilla.sc -60
+KPX Aogonek y.sc -75
+KPX Aogonek w.sc -85
+KPX Aogonek v.sc -115
+KPX Aogonek u.sc -60
+KPX Aogonek t.sc -60
+KPX Aogonek q.sc -55
+KPX Aogonek o.sc -60
+KPX Aogonek g.sc -60
+KPX Aogonek c.sc -60
+KPX Aogonek ycircumflex.sc -75
+KPX Aogonek wgrave.sc -85
+KPX Aogonek wdieresis.sc -85
+KPX Aogonek wcircumflex.sc -85
+KPX Aogonek wacute.sc -85
+KPX Aogonek uring.sc -60
+KPX Aogonek uogonek.sc -60
+KPX Aogonek umacron.sc -60
+KPX Aogonek uhungarumlaut.sc -60
+KPX Aogonek ubreve.sc -60
+KPX Aogonek uni021B.sc -60
+KPX Aogonek tcaron.sc -60
+KPX Aogonek omacron.sc -60
+KPX Aogonek ohungarumlaut.sc -60
+KPX Aogonek obreve.sc -60
+KPX Aogonek gdotaccent.sc -60
+KPX Aogonek gcommaaccent.sc -60
+KPX Aogonek gcircumflex.sc -60
+KPX Aogonek gbreve.sc -60
+KPX Aogonek cdotaccent.sc -60
+KPX Aogonek ccircumflex.sc -60
+KPX Aogonek ccaron.sc -60
+KPX Aogonek cacute.sc -60
+KPX Aogonek oogonek.sc -60
+KPX Aogonek gcaron.sc -60
+KPX Aogonek gacute.sc -60
+KPX Aogonek guilsinglleft -90
+KPX Aogonek quotedblright -125
+KPX Aogonek quoteright -120
+KPX Aogonek wdieresis -80
+KPX Aogonek Wdieresis -100
+KPX Aogonek wacute -80
+KPX Aogonek Wacute -100
+KPX Aogonek wgrave -80
+KPX Aogonek Wgrave -100
+KPX Aogonek uni021B -40
+KPX Aogonek uni021A -70
+KPX Aogonek gacute -25
+KPX Aogonek Gacute -70
+KPX Aogonek oogonek -35
+KPX Aogonek Oogonek -70
+KPX Aogonek gcaron -25
+KPX Aogonek Gcaron -70
+KPX Aogonek Ydieresis -90
+KPX Aogonek Ycircumflex -90
+KPX Aogonek wcircumflex -80
+KPX Aogonek Wcircumflex -100
+KPX Aogonek uogonek -45
+KPX Aogonek Uogonek -75
+KPX Aogonek uhungarumlaut -45
+KPX Aogonek Uhungarumlaut -75
+KPX Aogonek uring -45
+KPX Aogonek Uring -75
+KPX Aogonek ubreve -45
+KPX Aogonek Ubreve -75
+KPX Aogonek umacron -45
+KPX Aogonek Umacron -75
+KPX Aogonek tcaron -40
+KPX Aogonek Tcaron -70
+KPX Aogonek ohungarumlaut -35
+KPX Aogonek Ohungarumlaut -70
+KPX Aogonek obreve -35
+KPX Aogonek Obreve -70
+KPX Aogonek omacron -35
+KPX Aogonek Omacron -70
+KPX Aogonek gcommaaccent -25
+KPX Aogonek Gcommaaccent -70
+KPX Aogonek gdotaccent -25
+KPX Aogonek Gdotaccent -70
+KPX Aogonek gbreve -25
+KPX Aogonek Gbreve -70
+KPX Aogonek gcircumflex -25
+KPX Aogonek Gcircumflex -70
+KPX Aogonek ecaron -30
+KPX Aogonek eogonek -30
+KPX Aogonek edotaccent -30
+KPX Aogonek ebreve -30
+KPX Aogonek emacron -30
+KPX Aogonek dcaron -35
+KPX Aogonek ccaron -35
+KPX Aogonek Ccaron -70
+KPX Aogonek cdotaccent -35
+KPX Aogonek Cdotaccent -70
+KPX Aogonek ccircumflex -35
+KPX Aogonek Ccircumflex -70
+KPX Aogonek cacute -35
+KPX Aogonek Cacute -70
+KPX Aogonek udieresis -45
+KPX Aogonek ucircumflex -45
+KPX Aogonek oslash -35
+KPX Aogonek odieresis -35
+KPX Aogonek edieresis -30
+KPX Aogonek ccedilla -35
+KPX Aogonek Udieresis -75
+KPX Aogonek Ucircumflex -75
+KPX Aogonek Oslash -70
+KPX Aogonek Odieresis -70
+KPX Aogonek Ccedilla -70
+KPX Aogonek guillemotleft -85
+KPX Aogonek w -80
+KPX Aogonek v -85
+KPX Aogonek u -45
+KPX Aogonek t -40
+KPX Aogonek q -35
+KPX Aogonek o -35
+KPX Aogonek g -25
+KPX Aogonek e -30
+KPX Aogonek d -35
+KPX Aogonek c -35
+KPX Aogonek b -15
+KPX Aogonek Y -90
+KPX Aogonek W -100
+KPX Aogonek V -140
+KPX Aogonek U -75
+KPX Aogonek T -70
+KPX Aogonek Q -65
+KPX Aogonek O -70
+KPX Aogonek G -70
+KPX Aogonek C -70
+KPX Aogonek period -25
+KPX Aogonek hyphen -35
+KPX Aogonek comma -35
+KPX Aogonek T_h -70
+KPX aogonek quoteright -35
+KPX aogonek wdieresis -35
+KPX aogonek wacute -35
+KPX aogonek wgrave -35
+KPX aogonek wcircumflex -35
+KPX aogonek w -35
+KPX aogonek v -35
+KPX Cacute oslash.sc -35
+KPX Cacute odieresis.sc -35
+KPX Cacute aring.sc -10
+KPX Cacute adieresis.sc -10
+KPX Cacute o.sc -35
+KPX Cacute k.sc -10
+KPX Cacute h.sc -10
+KPX Cacute a.sc -10
+KPX Cacute omacron.sc -35
+KPX Cacute ohungarumlaut.sc -35
+KPX Cacute obreve.sc -35
+KPX Cacute kcommaaccent.sc -10
+KPX Cacute hcircumflex.sc -10
+KPX Cacute aogonek.sc -10
+KPX Cacute amacron.sc -10
+KPX Cacute oogonek.sc -35
+KPX Cacute Oogonek -40
+KPX Cacute Ohungarumlaut -40
+KPX Cacute Obreve -40
+KPX Cacute Omacron -40
+KPX Cacute Kcommaaccent -10
+KPX Cacute Hcircumflex -10
+KPX Cacute Aogonek -15
+KPX Cacute Amacron -15
+KPX Cacute Oslash -40
+KPX Cacute Odieresis -40
+KPX Cacute Aring -15
+KPX Cacute Adieresis -15
+KPX Cacute O -40
+KPX Cacute K -10
+KPX Cacute H -10
+KPX Cacute A -15
+KPX Ccircumflex oslash.sc -35
+KPX Ccircumflex odieresis.sc -35
+KPX Ccircumflex aring.sc -10
+KPX Ccircumflex adieresis.sc -10
+KPX Ccircumflex o.sc -35
+KPX Ccircumflex k.sc -10
+KPX Ccircumflex h.sc -10
+KPX Ccircumflex a.sc -10
+KPX Ccircumflex omacron.sc -35
+KPX Ccircumflex ohungarumlaut.sc -35
+KPX Ccircumflex obreve.sc -35
+KPX Ccircumflex kcommaaccent.sc -10
+KPX Ccircumflex hcircumflex.sc -10
+KPX Ccircumflex aogonek.sc -10
+KPX Ccircumflex amacron.sc -10
+KPX Ccircumflex oogonek.sc -35
+KPX Ccircumflex Oogonek -40
+KPX Ccircumflex Ohungarumlaut -40
+KPX Ccircumflex Obreve -40
+KPX Ccircumflex Omacron -40
+KPX Ccircumflex Kcommaaccent -10
+KPX Ccircumflex Hcircumflex -10
+KPX Ccircumflex Aogonek -15
+KPX Ccircumflex Amacron -15
+KPX Ccircumflex Oslash -40
+KPX Ccircumflex Odieresis -40
+KPX Ccircumflex Aring -15
+KPX Ccircumflex Adieresis -15
+KPX Ccircumflex O -40
+KPX Ccircumflex K -10
+KPX Ccircumflex H -10
+KPX Ccircumflex A -15
+KPX Cdotaccent oslash.sc -35
+KPX Cdotaccent odieresis.sc -35
+KPX Cdotaccent aring.sc -10
+KPX Cdotaccent adieresis.sc -10
+KPX Cdotaccent o.sc -35
+KPX Cdotaccent k.sc -10
+KPX Cdotaccent h.sc -10
+KPX Cdotaccent a.sc -10
+KPX Cdotaccent omacron.sc -35
+KPX Cdotaccent ohungarumlaut.sc -35
+KPX Cdotaccent obreve.sc -35
+KPX Cdotaccent kcommaaccent.sc -10
+KPX Cdotaccent hcircumflex.sc -10
+KPX Cdotaccent aogonek.sc -10
+KPX Cdotaccent amacron.sc -10
+KPX Cdotaccent oogonek.sc -35
+KPX Cdotaccent Oogonek -40
+KPX Cdotaccent Ohungarumlaut -40
+KPX Cdotaccent Obreve -40
+KPX Cdotaccent Omacron -40
+KPX Cdotaccent Kcommaaccent -10
+KPX Cdotaccent Hcircumflex -10
+KPX Cdotaccent Aogonek -15
+KPX Cdotaccent Amacron -15
+KPX Cdotaccent Oslash -40
+KPX Cdotaccent Odieresis -40
+KPX Cdotaccent Aring -15
+KPX Cdotaccent Adieresis -15
+KPX Cdotaccent O -40
+KPX Cdotaccent K -10
+KPX Cdotaccent H -10
+KPX Cdotaccent A -15
+KPX Ccaron oslash.sc -35
+KPX Ccaron odieresis.sc -35
+KPX Ccaron aring.sc -10
+KPX Ccaron adieresis.sc -10
+KPX Ccaron o.sc -35
+KPX Ccaron k.sc -10
+KPX Ccaron h.sc -10
+KPX Ccaron a.sc -10
+KPX Ccaron omacron.sc -35
+KPX Ccaron ohungarumlaut.sc -35
+KPX Ccaron obreve.sc -35
+KPX Ccaron kcommaaccent.sc -10
+KPX Ccaron hcircumflex.sc -10
+KPX Ccaron aogonek.sc -10
+KPX Ccaron amacron.sc -10
+KPX Ccaron oogonek.sc -35
+KPX Ccaron Oogonek -40
+KPX Ccaron Ohungarumlaut -40
+KPX Ccaron Obreve -40
+KPX Ccaron Omacron -40
+KPX Ccaron Kcommaaccent -10
+KPX Ccaron Hcircumflex -10
+KPX Ccaron Aogonek -15
+KPX Ccaron Amacron -15
+KPX Ccaron Oslash -40
+KPX Ccaron Odieresis -40
+KPX Ccaron Aring -15
+KPX Ccaron Adieresis -15
+KPX Ccaron O -40
+KPX Ccaron K -10
+KPX Ccaron H -10
+KPX Ccaron A -15
+KPX Dcaron ydieresis.sc -45
+KPX Dcaron aring.sc -65
+KPX Dcaron adieresis.sc -65
+KPX Dcaron y.sc -45
+KPX Dcaron x.sc -50
+KPX Dcaron w.sc -35
+KPX Dcaron v.sc -50
+KPX Dcaron t.sc -10
+KPX Dcaron j.sc -25
+KPX Dcaron a.sc -65
+KPX Dcaron ycircumflex.sc -45
+KPX Dcaron wgrave.sc -35
+KPX Dcaron wdieresis.sc -35
+KPX Dcaron wcircumflex.sc -35
+KPX Dcaron wacute.sc -35
+KPX Dcaron uni021B.sc -10
+KPX Dcaron tcaron.sc -10
+KPX Dcaron jcircumflex.sc -25
+KPX Dcaron aogonek.sc -65
+KPX Dcaron amacron.sc -65
+KPX Dcaron Jacute -30
+KPX Dcaron jacute.sc -25
+KPX Dcaron Wdieresis -45
+KPX Dcaron Wacute -45
+KPX Dcaron Wgrave -45
+KPX Dcaron uni021A -15
+KPX Dcaron Ydieresis -55
+KPX Dcaron Ycircumflex -55
+KPX Dcaron Wcircumflex -45
+KPX Dcaron Tcaron -15
+KPX Dcaron Jcircumflex -30
+KPX Dcaron Aogonek -80
+KPX Dcaron Amacron -80
+KPX Dcaron Aring -80
+KPX Dcaron Adieresis -80
+KPX Dcaron Y -55
+KPX Dcaron X -60
+KPX Dcaron W -45
+KPX Dcaron V -60
+KPX Dcaron T -15
+KPX Dcaron J -30
+KPX Dcaron A -80
+KPX Dcaron T_h -15
+KPX dcaron quotedblright 40
+KPX dcaron quotedblleft 40
+KPX dcaron quoteright 40
+KPX dcaron quoteleft 40
+KPX dcaron lcaron 35
+KPX dcaron lcommaaccent 35
+KPX dcaron lacute 35
+KPX dcaron kcommaaccent 35
+KPX dcaron hcircumflex 35
+KPX dcaron thorn 35
+KPX dcaron l 35
+KPX dcaron k 35
+KPX dcaron h 35
+KPX dcaron b 35
+KPX dcaron backslash 40
+KPX Dcroat atilde.sc -65
+KPX Dcroat acircumflex.sc -65
+KPX Dcroat aacute.sc -65
+KPX Dcroat agrave.sc -65
+KPX Dcroat a.sc -65
+KPX Dcroat abreve.sc -65
+KPX Dcroat ahookabove.sc -65
+KPX Dcroat adotbelow.sc -65
+KPX Dcroat acircumflextilde.sc -65
+KPX Dcroat acircumflexhookabove.sc -65
+KPX Dcroat acircumflexgrave.sc -65
+KPX Dcroat acircumflexdotbelow.sc -65
+KPX Dcroat acircumflexacute.sc -65
+KPX Dcroat abrevetilde.sc -65
+KPX Dcroat abrevehookabove.sc -65
+KPX Dcroat abrevegrave.sc -65
+KPX Dcroat abrevedotbelow.sc -65
+KPX Dcroat abreveacute.sc -65
+KPX Dcroat Abrevedotbelow -80
+KPX Dcroat Abrevetilde -80
+KPX Dcroat Abrevehookabove -80
+KPX Dcroat Abrevegrave -80
+KPX Dcroat Abreveacute -80
+KPX Dcroat Acircumflexdotbelow -80
+KPX Dcroat Acircumflextilde -80
+KPX Dcroat Acircumflexhookabove -80
+KPX Dcroat Acircumflexgrave -80
+KPX Dcroat Acircumflexacute -80
+KPX Dcroat Ahookabove -80
+KPX Dcroat Adotbelow -80
+KPX Dcroat Abreve -80
+KPX Dcroat Atilde -80
+KPX Dcroat Acircumflex -80
+KPX Dcroat Aacute -80
+KPX Dcroat Agrave -80
+KPX Dcroat A -80
+KPX emacron wdieresis -10
+KPX emacron wacute -10
+KPX emacron wgrave -10
+KPX emacron ycircumflex -15
+KPX emacron wcircumflex -10
+KPX emacron ydieresis -15
+KPX emacron y -15
+KPX emacron w -10
+KPX emacron v -10
+KPX ebreve wdieresis -10
+KPX ebreve wacute -10
+KPX ebreve wgrave -10
+KPX ebreve ycircumflex -15
+KPX ebreve wcircumflex -10
+KPX ebreve ydieresis -15
+KPX ebreve y -15
+KPX ebreve w -10
+KPX ebreve v -10
+KPX edotaccent wdieresis -10
+KPX edotaccent wacute -10
+KPX edotaccent wgrave -10
+KPX edotaccent ycircumflex -15
+KPX edotaccent wcircumflex -10
+KPX edotaccent ydieresis -15
+KPX edotaccent y -15
+KPX edotaccent w -10
+KPX edotaccent v -10
+KPX eogonek wdieresis -10
+KPX eogonek wacute -10
+KPX eogonek wgrave -10
+KPX eogonek wcircumflex -10
+KPX eogonek w -10
+KPX eogonek v -10
+KPX ecaron wdieresis -10
+KPX ecaron wacute -10
+KPX ecaron wgrave -10
+KPX ecaron ycircumflex -15
+KPX ecaron wcircumflex -10
+KPX ecaron ydieresis -15
+KPX ecaron y -15
+KPX ecaron w -10
+KPX ecaron v -10
+KPX Gcircumflex ydieresis.sc -15
+KPX Gcircumflex aring.sc -20
+KPX Gcircumflex adieresis.sc -20
+KPX Gcircumflex y.sc -15
+KPX Gcircumflex w.sc -10
+KPX Gcircumflex v.sc -10
+KPX Gcircumflex t.sc -20
+KPX Gcircumflex a.sc -20
+KPX Gcircumflex ycircumflex.sc -15
+KPX Gcircumflex wgrave.sc -10
+KPX Gcircumflex wdieresis.sc -10
+KPX Gcircumflex wcircumflex.sc -10
+KPX Gcircumflex wacute.sc -10
+KPX Gcircumflex uni021B.sc -20
+KPX Gcircumflex tcaron.sc -20
+KPX Gcircumflex aogonek.sc -20
+KPX Gcircumflex amacron.sc -20
+KPX Gcircumflex Wdieresis -15
+KPX Gcircumflex Wacute -15
+KPX Gcircumflex Wgrave -15
+KPX Gcircumflex uni021A -25
+KPX Gcircumflex Ydieresis -20
+KPX Gcircumflex Ycircumflex -20
+KPX Gcircumflex Wcircumflex -15
+KPX Gcircumflex Tcaron -25
+KPX Gcircumflex Aogonek -25
+KPX Gcircumflex Amacron -25
+KPX Gcircumflex Aring -25
+KPX Gcircumflex Adieresis -25
+KPX Gcircumflex Y -20
+KPX Gcircumflex W -15
+KPX Gcircumflex V -15
+KPX Gcircumflex T -25
+KPX Gcircumflex A -25
+KPX Gcircumflex T_h -25
+KPX gcircumflex rdotaccent 15
+KPX gcircumflex aeacute -15
+KPX gcircumflex rcaron 15
+KPX gcircumflex rcommaaccent 15
+KPX gcircumflex racute 15
+KPX gcircumflex ecaron -20
+KPX gcircumflex eogonek -20
+KPX gcircumflex edotaccent -20
+KPX gcircumflex ebreve -20
+KPX gcircumflex emacron -20
+KPX gcircumflex aogonek -15
+KPX gcircumflex amacron -15
+KPX gcircumflex edieresis -20
+KPX gcircumflex ae -15
+KPX gcircumflex aring -15
+KPX gcircumflex adieresis -15
+KPX gcircumflex r 15
+KPX gcircumflex e -20
+KPX gcircumflex a -15
+KPX Gbreve ydieresis.sc -15
+KPX Gbreve aring.sc -20
+KPX Gbreve adieresis.sc -20
+KPX Gbreve y.sc -15
+KPX Gbreve w.sc -10
+KPX Gbreve v.sc -10
+KPX Gbreve t.sc -20
+KPX Gbreve a.sc -20
+KPX Gbreve ycircumflex.sc -15
+KPX Gbreve wgrave.sc -10
+KPX Gbreve wdieresis.sc -10
+KPX Gbreve wcircumflex.sc -10
+KPX Gbreve wacute.sc -10
+KPX Gbreve uni021B.sc -20
+KPX Gbreve tcaron.sc -20
+KPX Gbreve aogonek.sc -20
+KPX Gbreve amacron.sc -20
+KPX Gbreve Wdieresis -15
+KPX Gbreve Wacute -15
+KPX Gbreve Wgrave -15
+KPX Gbreve uni021A -25
+KPX Gbreve Ydieresis -20
+KPX Gbreve Ycircumflex -20
+KPX Gbreve Wcircumflex -15
+KPX Gbreve Tcaron -25
+KPX Gbreve Aogonek -25
+KPX Gbreve Amacron -25
+KPX Gbreve Aring -25
+KPX Gbreve Adieresis -25
+KPX Gbreve Y -20
+KPX Gbreve W -15
+KPX Gbreve V -15
+KPX Gbreve T -25
+KPX Gbreve A -25
+KPX Gbreve T_h -25
+KPX gbreve rdotaccent 15
+KPX gbreve aeacute -15
+KPX gbreve rcaron 15
+KPX gbreve rcommaaccent 15
+KPX gbreve racute 15
+KPX gbreve ecaron -20
+KPX gbreve eogonek -20
+KPX gbreve edotaccent -20
+KPX gbreve ebreve -20
+KPX gbreve emacron -20
+KPX gbreve aogonek -15
+KPX gbreve amacron -15
+KPX gbreve edieresis -20
+KPX gbreve ae -15
+KPX gbreve aring -15
+KPX gbreve adieresis -15
+KPX gbreve r 15
+KPX gbreve e -20
+KPX gbreve a -15
+KPX Gdotaccent ydieresis.sc -15
+KPX Gdotaccent aring.sc -20
+KPX Gdotaccent adieresis.sc -20
+KPX Gdotaccent y.sc -15
+KPX Gdotaccent w.sc -10
+KPX Gdotaccent v.sc -10
+KPX Gdotaccent t.sc -20
+KPX Gdotaccent a.sc -20
+KPX Gdotaccent ycircumflex.sc -15
+KPX Gdotaccent wgrave.sc -10
+KPX Gdotaccent wdieresis.sc -10
+KPX Gdotaccent wcircumflex.sc -10
+KPX Gdotaccent wacute.sc -10
+KPX Gdotaccent uni021B.sc -20
+KPX Gdotaccent tcaron.sc -20
+KPX Gdotaccent aogonek.sc -20
+KPX Gdotaccent amacron.sc -20
+KPX Gdotaccent Wdieresis -15
+KPX Gdotaccent Wacute -15
+KPX Gdotaccent Wgrave -15
+KPX Gdotaccent uni021A -25
+KPX Gdotaccent Ydieresis -20
+KPX Gdotaccent Ycircumflex -20
+KPX Gdotaccent Wcircumflex -15
+KPX Gdotaccent Tcaron -25
+KPX Gdotaccent Aogonek -25
+KPX Gdotaccent Amacron -25
+KPX Gdotaccent Aring -25
+KPX Gdotaccent Adieresis -25
+KPX Gdotaccent Y -20
+KPX Gdotaccent W -15
+KPX Gdotaccent V -15
+KPX Gdotaccent T -25
+KPX Gdotaccent A -25
+KPX Gdotaccent T_h -25
+KPX gdotaccent rdotaccent 15
+KPX gdotaccent aeacute -15
+KPX gdotaccent rcaron 15
+KPX gdotaccent rcommaaccent 15
+KPX gdotaccent racute 15
+KPX gdotaccent ecaron -20
+KPX gdotaccent eogonek -20
+KPX gdotaccent edotaccent -20
+KPX gdotaccent ebreve -20
+KPX gdotaccent emacron -20
+KPX gdotaccent aogonek -15
+KPX gdotaccent amacron -15
+KPX gdotaccent edieresis -20
+KPX gdotaccent ae -15
+KPX gdotaccent aring -15
+KPX gdotaccent adieresis -15
+KPX gdotaccent r 15
+KPX gdotaccent e -20
+KPX gdotaccent a -15
+KPX Gcommaaccent ydieresis.sc -15
+KPX Gcommaaccent aring.sc -20
+KPX Gcommaaccent adieresis.sc -20
+KPX Gcommaaccent y.sc -15
+KPX Gcommaaccent w.sc -10
+KPX Gcommaaccent v.sc -10
+KPX Gcommaaccent t.sc -20
+KPX Gcommaaccent a.sc -20
+KPX Gcommaaccent ycircumflex.sc -15
+KPX Gcommaaccent wgrave.sc -10
+KPX Gcommaaccent wdieresis.sc -10
+KPX Gcommaaccent wcircumflex.sc -10
+KPX Gcommaaccent wacute.sc -10
+KPX Gcommaaccent uni021B.sc -20
+KPX Gcommaaccent tcaron.sc -20
+KPX Gcommaaccent aogonek.sc -20
+KPX Gcommaaccent amacron.sc -20
+KPX Gcommaaccent Wdieresis -15
+KPX Gcommaaccent Wacute -15
+KPX Gcommaaccent Wgrave -15
+KPX Gcommaaccent uni021A -25
+KPX Gcommaaccent Ydieresis -20
+KPX Gcommaaccent Ycircumflex -20
+KPX Gcommaaccent Wcircumflex -15
+KPX Gcommaaccent Tcaron -25
+KPX Gcommaaccent Aogonek -25
+KPX Gcommaaccent Amacron -25
+KPX Gcommaaccent Aring -25
+KPX Gcommaaccent Adieresis -25
+KPX Gcommaaccent Y -20
+KPX Gcommaaccent W -15
+KPX Gcommaaccent V -15
+KPX Gcommaaccent T -25
+KPX Gcommaaccent A -25
+KPX Gcommaaccent T_h -25
+KPX gcommaaccent rdotaccent 15
+KPX gcommaaccent aeacute -15
+KPX gcommaaccent rcaron 15
+KPX gcommaaccent rcommaaccent 15
+KPX gcommaaccent racute 15
+KPX gcommaaccent ecaron -20
+KPX gcommaaccent eogonek -20
+KPX gcommaaccent edotaccent -20
+KPX gcommaaccent ebreve -20
+KPX gcommaaccent emacron -20
+KPX gcommaaccent aogonek -15
+KPX gcommaaccent amacron -15
+KPX gcommaaccent edieresis -20
+KPX gcommaaccent ae -15
+KPX gcommaaccent aring -15
+KPX gcommaaccent adieresis -15
+KPX gcommaaccent r 15
+KPX gcommaaccent e -20
+KPX gcommaaccent a -15
+KPX hcircumflex quoteright -35
+KPX hcircumflex ycircumflex -35
+KPX hcircumflex ydieresis -35
+KPX hcircumflex y -35
+KPX imacron jacute -15
+KPX imacron uni021A -30
+KPX imacron Tcaron -30
+KPX imacron jcircumflex -15
+KPX imacron j -15
+KPX imacron T -30
+KPX imacron T_h -30
+KPX ibreve jacute -15
+KPX ibreve uni021A -30
+KPX ibreve Tcaron -30
+KPX ibreve jcircumflex -15
+KPX ibreve j -15
+KPX ibreve T -30
+KPX ibreve T_h -30
+KPX iogonek uni021A -30
+KPX iogonek Tcaron -30
+KPX iogonek T -30
+KPX iogonek T_h -30
+KPX Jcircumflex ae.sc -30
+KPX Jcircumflex aring.sc -40
+KPX Jcircumflex adieresis.sc -40
+KPX Jcircumflex a.sc -40
+KPX Jcircumflex aeacute.sc -30
+KPX Jcircumflex aogonek.sc -40
+KPX Jcircumflex amacron.sc -40
+KPX Jcircumflex AEacute -35
+KPX Jcircumflex Aogonek -50
+KPX Jcircumflex Amacron -50
+KPX Jcircumflex AE -35
+KPX Jcircumflex Aring -50
+KPX Jcircumflex Adieresis -50
+KPX Jcircumflex A -50
+KPX Kcommaaccent oslash.sc -50
+KPX Kcommaaccent odieresis.sc -50
+KPX Kcommaaccent ccedilla.sc -55
+KPX Kcommaaccent o.sc -50
+KPX Kcommaaccent g.sc -55
+KPX Kcommaaccent c.sc -55
+KPX Kcommaaccent omacron.sc -50
+KPX Kcommaaccent ohungarumlaut.sc -50
+KPX Kcommaaccent obreve.sc -50
+KPX Kcommaaccent gdotaccent.sc -55
+KPX Kcommaaccent gcommaaccent.sc -55
+KPX Kcommaaccent gcircumflex.sc -55
+KPX Kcommaaccent gbreve.sc -55
+KPX Kcommaaccent cdotaccent.sc -55
+KPX Kcommaaccent ccircumflex.sc -55
+KPX Kcommaaccent ccaron.sc -55
+KPX Kcommaaccent cacute.sc -55
+KPX Kcommaaccent oogonek.sc -50
+KPX Kcommaaccent oe.sc -50
+KPX Kcommaaccent gcaron.sc -55
+KPX Kcommaaccent gacute.sc -55
+KPX Kcommaaccent Gacute -65
+KPX Kcommaaccent oogonek -30
+KPX Kcommaaccent Oogonek -60
+KPX Kcommaaccent Gcaron -65
+KPX Kcommaaccent ycircumflex -90
+KPX Kcommaaccent uogonek -35
+KPX Kcommaaccent uhungarumlaut -35
+KPX Kcommaaccent uring -35
+KPX Kcommaaccent ubreve -35
+KPX Kcommaaccent umacron -35
+KPX Kcommaaccent OE -60
+KPX Kcommaaccent ohungarumlaut -30
+KPX Kcommaaccent Ohungarumlaut -60
+KPX Kcommaaccent obreve -30
+KPX Kcommaaccent Obreve -60
+KPX Kcommaaccent omacron -30
+KPX Kcommaaccent Omacron -60
+KPX Kcommaaccent Gcommaaccent -65
+KPX Kcommaaccent Gdotaccent -65
+KPX Kcommaaccent Gbreve -65
+KPX Kcommaaccent Gcircumflex -65
+KPX Kcommaaccent ecaron -20
+KPX Kcommaaccent eogonek -20
+KPX Kcommaaccent edotaccent -20
+KPX Kcommaaccent ebreve -20
+KPX Kcommaaccent emacron -20
+KPX Kcommaaccent Ccaron -65
+KPX Kcommaaccent Cdotaccent -65
+KPX Kcommaaccent Ccircumflex -65
+KPX Kcommaaccent Cacute -65
+KPX Kcommaaccent ydieresis -90
+KPX Kcommaaccent udieresis -35
+KPX Kcommaaccent ucircumflex -35
+KPX Kcommaaccent oslash -30
+KPX Kcommaaccent odieresis -30
+KPX Kcommaaccent edieresis -20
+KPX Kcommaaccent Oslash -60
+KPX Kcommaaccent Odieresis -60
+KPX Kcommaaccent Ccedilla -65
+KPX Kcommaaccent y -90
+KPX Kcommaaccent u -35
+KPX Kcommaaccent o -30
+KPX Kcommaaccent e -20
+KPX Kcommaaccent O -60
+KPX Kcommaaccent G -65
+KPX Kcommaaccent C -65
+KPX Kcommaaccent hyphen -75
+KPX kcommaaccent uni0219 10
+KPX kcommaaccent gacute -10
+KPX kcommaaccent oogonek -20
+KPX kcommaaccent gcaron -10
+KPX kcommaaccent scaron 10
+KPX kcommaaccent scedilla 10
+KPX kcommaaccent scircumflex 10
+KPX kcommaaccent sacute 10
+KPX kcommaaccent ohungarumlaut -20
+KPX kcommaaccent obreve -20
+KPX kcommaaccent omacron -20
+KPX kcommaaccent gcommaaccent -10
+KPX kcommaaccent gdotaccent -10
+KPX kcommaaccent gbreve -10
+KPX kcommaaccent gcircumflex -10
+KPX kcommaaccent ecaron -10
+KPX kcommaaccent eogonek -10
+KPX kcommaaccent edotaccent -10
+KPX kcommaaccent ebreve -10
+KPX kcommaaccent emacron -10
+KPX kcommaaccent oslash -20
+KPX kcommaaccent odieresis -20
+KPX kcommaaccent edieresis -10
+KPX kcommaaccent s 10
+KPX kcommaaccent o -20
+KPX kcommaaccent g -10
+KPX kcommaaccent e -10
+KPX kcommaaccent hyphen -65
+KPX kcommaaccent comma -20
+KPX Lacute ydieresis.sc -85
+KPX Lacute udieresis.sc -35
+KPX Lacute ucircumflex.sc -35
+KPX Lacute oslash.sc -15
+KPX Lacute odieresis.sc -15
+KPX Lacute ccedilla.sc -15
+KPX Lacute y.sc -85
+KPX Lacute w.sc -70
+KPX Lacute v.sc -105
+KPX Lacute u.sc -35
+KPX Lacute t.sc -65
+KPX Lacute o.sc -15
+KPX Lacute g.sc -15
+KPX Lacute c.sc -15
+KPX Lacute ycircumflex.sc -85
+KPX Lacute wgrave.sc -70
+KPX Lacute wdieresis.sc -70
+KPX Lacute wcircumflex.sc -70
+KPX Lacute wacute.sc -70
+KPX Lacute uring.sc -35
+KPX Lacute uogonek.sc -35
+KPX Lacute umacron.sc -35
+KPX Lacute uhungarumlaut.sc -35
+KPX Lacute ubreve.sc -35
+KPX Lacute uni021B.sc -65
+KPX Lacute tcaron.sc -65
+KPX Lacute omacron.sc -15
+KPX Lacute ohungarumlaut.sc -15
+KPX Lacute obreve.sc -15
+KPX Lacute gdotaccent.sc -15
+KPX Lacute gcommaaccent.sc -15
+KPX Lacute gcircumflex.sc -15
+KPX Lacute gbreve.sc -15
+KPX Lacute cdotaccent.sc -15
+KPX Lacute ccircumflex.sc -15
+KPX Lacute ccaron.sc -15
+KPX Lacute cacute.sc -15
+KPX Lacute oogonek.sc -15
+KPX Lacute gcaron.sc -15
+KPX Lacute gacute.sc -15
+KPX Lacute quotedblright -130
+KPX Lacute quoteright -125
+KPX Lacute Wdieresis -85
+KPX Lacute Wacute -85
+KPX Lacute Wgrave -85
+KPX Lacute uni021A -80
+KPX Lacute Gacute -20
+KPX Lacute Oogonek -20
+KPX Lacute Gcaron -20
+KPX Lacute Ydieresis -100
+KPX Lacute ycircumflex -60
+KPX Lacute Ycircumflex -100
+KPX Lacute Wcircumflex -85
+KPX Lacute uogonek -35
+KPX Lacute Uogonek -45
+KPX Lacute uhungarumlaut -35
+KPX Lacute Uhungarumlaut -45
+KPX Lacute uring -35
+KPX Lacute Uring -45
+KPX Lacute ubreve -35
+KPX Lacute Ubreve -45
+KPX Lacute umacron -35
+KPX Lacute Umacron -45
+KPX Lacute Tcaron -80
+KPX Lacute Ohungarumlaut -20
+KPX Lacute Obreve -20
+KPX Lacute Omacron -20
+KPX Lacute Gcommaaccent -20
+KPX Lacute Gdotaccent -20
+KPX Lacute Gbreve -20
+KPX Lacute Gcircumflex -20
+KPX Lacute Ccaron -20
+KPX Lacute Cdotaccent -20
+KPX Lacute Ccircumflex -20
+KPX Lacute Cacute -20
+KPX Lacute ydieresis -60
+KPX Lacute udieresis -35
+KPX Lacute ucircumflex -35
+KPX Lacute Udieresis -45
+KPX Lacute Ucircumflex -45
+KPX Lacute Oslash -20
+KPX Lacute Odieresis -20
+KPX Lacute Ccedilla -20
+KPX Lacute y -60
+KPX Lacute u -35
+KPX Lacute Y -100
+KPX Lacute W -85
+KPX Lacute V -125
+KPX Lacute U -45
+KPX Lacute T -80
+KPX Lacute O -20
+KPX Lacute G -20
+KPX Lacute C -20
+KPX Lacute T_h -80
+KPX lacute ycircumflex -25
+KPX lacute ydieresis -25
+KPX lacute y -25
+KPX lacute v -20
+KPX Lcommaaccent ydieresis.sc -85
+KPX Lcommaaccent udieresis.sc -35
+KPX Lcommaaccent ucircumflex.sc -35
+KPX Lcommaaccent oslash.sc -15
+KPX Lcommaaccent odieresis.sc -15
+KPX Lcommaaccent ccedilla.sc -15
+KPX Lcommaaccent y.sc -85
+KPX Lcommaaccent w.sc -70
+KPX Lcommaaccent v.sc -105
+KPX Lcommaaccent u.sc -35
+KPX Lcommaaccent t.sc -65
+KPX Lcommaaccent o.sc -15
+KPX Lcommaaccent g.sc -15
+KPX Lcommaaccent c.sc -15
+KPX Lcommaaccent ycircumflex.sc -85
+KPX Lcommaaccent wgrave.sc -70
+KPX Lcommaaccent wdieresis.sc -70
+KPX Lcommaaccent wcircumflex.sc -70
+KPX Lcommaaccent wacute.sc -70
+KPX Lcommaaccent uring.sc -35
+KPX Lcommaaccent uogonek.sc -35
+KPX Lcommaaccent umacron.sc -35
+KPX Lcommaaccent uhungarumlaut.sc -35
+KPX Lcommaaccent ubreve.sc -35
+KPX Lcommaaccent uni021B.sc -65
+KPX Lcommaaccent tcaron.sc -65
+KPX Lcommaaccent omacron.sc -15
+KPX Lcommaaccent ohungarumlaut.sc -15
+KPX Lcommaaccent obreve.sc -15
+KPX Lcommaaccent gdotaccent.sc -15
+KPX Lcommaaccent gcommaaccent.sc -15
+KPX Lcommaaccent gcircumflex.sc -15
+KPX Lcommaaccent gbreve.sc -15
+KPX Lcommaaccent cdotaccent.sc -15
+KPX Lcommaaccent ccircumflex.sc -15
+KPX Lcommaaccent ccaron.sc -15
+KPX Lcommaaccent cacute.sc -15
+KPX Lcommaaccent oogonek.sc -15
+KPX Lcommaaccent gcaron.sc -15
+KPX Lcommaaccent gacute.sc -15
+KPX Lcommaaccent quotedblright -130
+KPX Lcommaaccent quoteright -125
+KPX Lcommaaccent Wdieresis -85
+KPX Lcommaaccent Wacute -85
+KPX Lcommaaccent Wgrave -85
+KPX Lcommaaccent uni021A -80
+KPX Lcommaaccent Gacute -20
+KPX Lcommaaccent Oogonek -20
+KPX Lcommaaccent Gcaron -20
+KPX Lcommaaccent Ydieresis -100
+KPX Lcommaaccent ycircumflex -60
+KPX Lcommaaccent Ycircumflex -100
+KPX Lcommaaccent Wcircumflex -85
+KPX Lcommaaccent uogonek -35
+KPX Lcommaaccent Uogonek -45
+KPX Lcommaaccent uhungarumlaut -35
+KPX Lcommaaccent Uhungarumlaut -45
+KPX Lcommaaccent uring -35
+KPX Lcommaaccent Uring -45
+KPX Lcommaaccent ubreve -35
+KPX Lcommaaccent Ubreve -45
+KPX Lcommaaccent umacron -35
+KPX Lcommaaccent Umacron -45
+KPX Lcommaaccent Tcaron -80
+KPX Lcommaaccent Ohungarumlaut -20
+KPX Lcommaaccent Obreve -20
+KPX Lcommaaccent Omacron -20
+KPX Lcommaaccent Gcommaaccent -20
+KPX Lcommaaccent Gdotaccent -20
+KPX Lcommaaccent Gbreve -20
+KPX Lcommaaccent Gcircumflex -20
+KPX Lcommaaccent Ccaron -20
+KPX Lcommaaccent Cdotaccent -20
+KPX Lcommaaccent Ccircumflex -20
+KPX Lcommaaccent Cacute -20
+KPX Lcommaaccent ydieresis -60
+KPX Lcommaaccent udieresis -35
+KPX Lcommaaccent ucircumflex -35
+KPX Lcommaaccent Udieresis -45
+KPX Lcommaaccent Ucircumflex -45
+KPX Lcommaaccent Oslash -20
+KPX Lcommaaccent Odieresis -20
+KPX Lcommaaccent Ccedilla -20
+KPX Lcommaaccent y -60
+KPX Lcommaaccent u -35
+KPX Lcommaaccent Y -100
+KPX Lcommaaccent W -85
+KPX Lcommaaccent V -125
+KPX Lcommaaccent U -45
+KPX Lcommaaccent T -80
+KPX Lcommaaccent O -20
+KPX Lcommaaccent G -20
+KPX Lcommaaccent C -20
+KPX Lcommaaccent T_h -80
+KPX lcommaaccent ycircumflex -25
+KPX lcommaaccent ydieresis -25
+KPX lcommaaccent y -25
+KPX lcommaaccent v -20
+KPX Lcaron ydieresis.sc -40
+KPX Lcaron yacute.sc -40
+KPX Lcaron udieresis.sc -20
+KPX Lcaron ucircumflex.sc -20
+KPX Lcaron uacute.sc -20
+KPX Lcaron ugrave.sc -20
+KPX Lcaron oslash.sc -15
+KPX Lcaron odieresis.sc -15
+KPX Lcaron ccedilla.sc -15
+KPX Lcaron y.sc -40
+KPX Lcaron w.sc -35
+KPX Lcaron v.sc -50
+KPX Lcaron u.sc -20
+KPX Lcaron t.sc -35
+KPX Lcaron o.sc -15
+KPX Lcaron g.sc -15
+KPX Lcaron c.sc -15
+KPX Lcaron ygrave.sc -40
+KPX Lcaron ycircumflex.sc -40
+KPX Lcaron wgrave.sc -35
+KPX Lcaron wdieresis.sc -35
+KPX Lcaron wcircumflex.sc -35
+KPX Lcaron wacute.sc -35
+KPX Lcaron utilde.sc -20
+KPX Lcaron uring.sc -20
+KPX Lcaron uogonek.sc -20
+KPX Lcaron umacron.sc -20
+KPX Lcaron uhungarumlaut.sc -20
+KPX Lcaron ubreve.sc -20
+KPX Lcaron uni021B.sc -35
+KPX Lcaron tcaron.sc -35
+KPX Lcaron omacron.sc -15
+KPX Lcaron ohungarumlaut.sc -15
+KPX Lcaron obreve.sc -15
+KPX Lcaron gdotaccent.sc -15
+KPX Lcaron gcommaaccent.sc -15
+KPX Lcaron gcircumflex.sc -15
+KPX Lcaron gbreve.sc -15
+KPX Lcaron cdotaccent.sc -15
+KPX Lcaron ccircumflex.sc -15
+KPX Lcaron ccaron.sc -15
+KPX Lcaron cacute.sc -15
+KPX Lcaron ytilde.sc -40
+KPX Lcaron yhookabove.sc -40
+KPX Lcaron ydotbelow.sc -40
+KPX Lcaron uhorntilde.sc -20
+KPX Lcaron uhornhookabove.sc -20
+KPX Lcaron uhorngrave.sc -20
+KPX Lcaron uhorndotbelow.sc -20
+KPX Lcaron uhornacute.sc -20
+KPX Lcaron uhookabove.sc -20
+KPX Lcaron udotbelow.sc -20
+KPX Lcaron oogonek.sc -15
+KPX Lcaron gcaron.sc -15
+KPX Lcaron gacute.sc -15
+KPX Lcaron quotedblright -130
+KPX Lcaron quoteright -125
+KPX Lcaron Ytilde -50
+KPX Lcaron Yhookabove -50
+KPX Lcaron Ydotbelow -50
+KPX Lcaron Ygrave -50
+KPX Lcaron Uhorndotbelow -25
+KPX Lcaron Uhorntilde -25
+KPX Lcaron Uhornhookabove -25
+KPX Lcaron Uhorngrave -25
+KPX Lcaron Uhornacute -25
+KPX Lcaron Uhookabove -25
+KPX Lcaron Udotbelow -25
+KPX Lcaron Wdieresis -45
+KPX Lcaron Wacute -45
+KPX Lcaron Wgrave -45
+KPX Lcaron uni021A -40
+KPX Lcaron Gacute -20
+KPX Lcaron Oogonek -20
+KPX Lcaron Gcaron -20
+KPX Lcaron Ydieresis -50
+KPX Lcaron ycircumflex -60
+KPX Lcaron Ycircumflex -50
+KPX Lcaron Wcircumflex -45
+KPX Lcaron uogonek -35
+KPX Lcaron Uogonek -25
+KPX Lcaron uhungarumlaut -35
+KPX Lcaron Uhungarumlaut -25
+KPX Lcaron uring -35
+KPX Lcaron Uring -25
+KPX Lcaron ubreve -35
+KPX Lcaron Ubreve -25
+KPX Lcaron umacron -35
+KPX Lcaron Umacron -25
+KPX Lcaron Utilde -25
+KPX Lcaron Tcaron -40
+KPX Lcaron Ohungarumlaut -20
+KPX Lcaron Obreve -20
+KPX Lcaron Omacron -20
+KPX Lcaron Gcommaaccent -20
+KPX Lcaron Gdotaccent -20
+KPX Lcaron Gbreve -20
+KPX Lcaron Gcircumflex -20
+KPX Lcaron Ccaron -20
+KPX Lcaron Cdotaccent -20
+KPX Lcaron Ccircumflex -20
+KPX Lcaron Cacute -20
+KPX Lcaron ydieresis -60
+KPX Lcaron udieresis -35
+KPX Lcaron ucircumflex -35
+KPX Lcaron Yacute -50
+KPX Lcaron Udieresis -25
+KPX Lcaron Ucircumflex -25
+KPX Lcaron Uacute -25
+KPX Lcaron Ugrave -25
+KPX Lcaron Oslash -20
+KPX Lcaron Odieresis -20
+KPX Lcaron Ccedilla -20
+KPX Lcaron y -60
+KPX Lcaron u -35
+KPX Lcaron Y -50
+KPX Lcaron W -45
+KPX Lcaron V -65
+KPX Lcaron U -25
+KPX Lcaron T -40
+KPX Lcaron O -20
+KPX Lcaron G -20
+KPX Lcaron C -20
+KPX Lcaron T_h -40
+KPX lcaron quotedblright 40
+KPX lcaron quotedblleft 40
+KPX lcaron quoteright 40
+KPX lcaron quoteleft 40
+KPX lcaron ycircumflex -25
+KPX lcaron lcaron 35
+KPX lcaron lcommaaccent 35
+KPX lcaron lacute 35
+KPX lcaron kcommaaccent 35
+KPX lcaron hcircumflex 35
+KPX lcaron ydieresis -25
+KPX lcaron thorn 35
+KPX lcaron y -25
+KPX lcaron v -20
+KPX lcaron l 35
+KPX lcaron k 35
+KPX lcaron h 35
+KPX lcaron b 35
+KPX lcaron backslash 40
+KPX Lslash ydieresis.sc -85
+KPX Lslash udieresis.sc -35
+KPX Lslash ucircumflex.sc -35
+KPX Lslash oslash.sc -15
+KPX Lslash odieresis.sc -15
+KPX Lslash ccedilla.sc -15
+KPX Lslash y.sc -85
+KPX Lslash w.sc -70
+KPX Lslash v.sc -105
+KPX Lslash u.sc -35
+KPX Lslash t.sc -65
+KPX Lslash o.sc -15
+KPX Lslash g.sc -15
+KPX Lslash c.sc -15
+KPX Lslash ycircumflex.sc -85
+KPX Lslash wgrave.sc -70
+KPX Lslash wdieresis.sc -70
+KPX Lslash wcircumflex.sc -70
+KPX Lslash wacute.sc -70
+KPX Lslash uring.sc -35
+KPX Lslash uogonek.sc -35
+KPX Lslash umacron.sc -35
+KPX Lslash uhungarumlaut.sc -35
+KPX Lslash ubreve.sc -35
+KPX Lslash uni021B.sc -65
+KPX Lslash tcaron.sc -65
+KPX Lslash omacron.sc -15
+KPX Lslash ohungarumlaut.sc -15
+KPX Lslash obreve.sc -15
+KPX Lslash gdotaccent.sc -15
+KPX Lslash gcommaaccent.sc -15
+KPX Lslash gcircumflex.sc -15
+KPX Lslash gbreve.sc -15
+KPX Lslash cdotaccent.sc -15
+KPX Lslash ccircumflex.sc -15
+KPX Lslash ccaron.sc -15
+KPX Lslash cacute.sc -15
+KPX Lslash oogonek.sc -15
+KPX Lslash gcaron.sc -15
+KPX Lslash gacute.sc -15
+KPX Lslash quotedblright -130
+KPX Lslash quoteright -125
+KPX Lslash Ytilde -80
+KPX Lslash Yhookabove -80
+KPX Lslash Ydotbelow -80
+KPX Lslash Ygrave -80
+KPX Lslash Uhorndotbelow -35
+KPX Lslash Uhorntilde -35
+KPX Lslash Uhornhookabove -35
+KPX Lslash Uhorngrave -35
+KPX Lslash Uhornacute -35
+KPX Lslash Uhookabove -35
+KPX Lslash Udotbelow -35
+KPX Lslash Wdieresis -70
+KPX Lslash Wacute -70
+KPX Lslash Wgrave -70
+KPX Lslash uni021A -65
+KPX Lslash Gacute -20
+KPX Lslash Oogonek -20
+KPX Lslash Gcaron -20
+KPX Lslash Ydieresis -80
+KPX Lslash ycircumflex -60
+KPX Lslash Ycircumflex -80
+KPX Lslash Wcircumflex -70
+KPX Lslash uogonek -35
+KPX Lslash Uogonek -35
+KPX Lslash uhungarumlaut -35
+KPX Lslash Uhungarumlaut -35
+KPX Lslash uring -35
+KPX Lslash Uring -35
+KPX Lslash ubreve -35
+KPX Lslash Ubreve -35
+KPX Lslash umacron -35
+KPX Lslash Umacron -35
+KPX Lslash Utilde -35
+KPX Lslash Tcaron -65
+KPX Lslash Ohungarumlaut -20
+KPX Lslash Obreve -20
+KPX Lslash Omacron -20
+KPX Lslash Gcommaaccent -20
+KPX Lslash Gdotaccent -20
+KPX Lslash Gbreve -20
+KPX Lslash Gcircumflex -20
+KPX Lslash Ccaron -20
+KPX Lslash Cdotaccent -20
+KPX Lslash Ccircumflex -20
+KPX Lslash Cacute -20
+KPX Lslash ydieresis -60
+KPX Lslash udieresis -35
+KPX Lslash ucircumflex -35
+KPX Lslash Yacute -80
+KPX Lslash Udieresis -35
+KPX Lslash Ucircumflex -35
+KPX Lslash Uacute -35
+KPX Lslash Ugrave -35
+KPX Lslash Oslash -20
+KPX Lslash Odieresis -20
+KPX Lslash Ccedilla -20
+KPX Lslash y -60
+KPX Lslash u -35
+KPX Lslash Y -80
+KPX Lslash W -70
+KPX Lslash V -100
+KPX Lslash U -35
+KPX Lslash T -65
+KPX Lslash O -20
+KPX Lslash G -20
+KPX Lslash C -20
+KPX Lslash T_h -65
+KPX lslash ycircumflex -25
+KPX lslash ydieresis -25
+KPX lslash y -25
+KPX lslash v -20
+KPX Nacute oslash.sc -20
+KPX Nacute odieresis.sc -20
+KPX Nacute ccedilla.sc -25
+KPX Nacute ae.sc -25
+KPX Nacute aring.sc -35
+KPX Nacute adieresis.sc -35
+KPX Nacute o.sc -20
+KPX Nacute g.sc -25
+KPX Nacute c.sc -25
+KPX Nacute a.sc -35
+KPX Nacute omacron.sc -20
+KPX Nacute ohungarumlaut.sc -20
+KPX Nacute obreve.sc -20
+KPX Nacute gdotaccent.sc -25
+KPX Nacute gcommaaccent.sc -25
+KPX Nacute gcircumflex.sc -25
+KPX Nacute gbreve.sc -25
+KPX Nacute cdotaccent.sc -25
+KPX Nacute ccircumflex.sc -25
+KPX Nacute ccaron.sc -25
+KPX Nacute cacute.sc -25
+KPX Nacute aeacute.sc -25
+KPX Nacute aogonek.sc -35
+KPX Nacute amacron.sc -35
+KPX Nacute oogonek.sc -20
+KPX Nacute gcaron.sc -25
+KPX Nacute gacute.sc -25
+KPX Nacute aeacute -35
+KPX Nacute AEacute -30
+KPX Nacute Gacute -30
+KPX Nacute oogonek -30
+KPX Nacute Oogonek -25
+KPX Nacute Gcaron -30
+KPX Nacute uogonek -40
+KPX Nacute uhungarumlaut -40
+KPX Nacute uring -40
+KPX Nacute ubreve -40
+KPX Nacute umacron -40
+KPX Nacute ohungarumlaut -30
+KPX Nacute Ohungarumlaut -25
+KPX Nacute obreve -30
+KPX Nacute Obreve -25
+KPX Nacute omacron -30
+KPX Nacute Omacron -25
+KPX Nacute Gcommaaccent -30
+KPX Nacute Gdotaccent -30
+KPX Nacute Gbreve -30
+KPX Nacute Gcircumflex -30
+KPX Nacute ecaron -25
+KPX Nacute eogonek -25
+KPX Nacute edotaccent -25
+KPX Nacute ebreve -25
+KPX Nacute emacron -25
+KPX Nacute Ccaron -30
+KPX Nacute Cdotaccent -30
+KPX Nacute Ccircumflex -30
+KPX Nacute Cacute -30
+KPX Nacute aogonek -30
+KPX Nacute Aogonek -40
+KPX Nacute amacron -30
+KPX Nacute Amacron -40
+KPX Nacute udieresis -40
+KPX Nacute ucircumflex -40
+KPX Nacute oslash -30
+KPX Nacute odieresis -30
+KPX Nacute edieresis -25
+KPX Nacute ae -35
+KPX Nacute aring -30
+KPX Nacute adieresis -30
+KPX Nacute Oslash -25
+KPX Nacute Odieresis -25
+KPX Nacute Ccedilla -30
+KPX Nacute AE -30
+KPX Nacute Aring -40
+KPX Nacute Adieresis -40
+KPX Nacute u -40
+KPX Nacute o -30
+KPX Nacute e -25
+KPX Nacute a -30
+KPX Nacute O -25
+KPX Nacute G -30
+KPX Nacute C -30
+KPX Nacute A -40
+KPX Nacute period -30
+KPX Nacute comma -45
+KPX nacute quoteright -30
+KPX nacute wdieresis -35
+KPX nacute wacute -35
+KPX nacute wgrave -35
+KPX nacute uni021A -60
+KPX nacute ycircumflex -35
+KPX nacute wcircumflex -35
+KPX nacute Tcaron -60
+KPX nacute ydieresis -35
+KPX nacute y -35
+KPX nacute w -35
+KPX nacute v -35
+KPX nacute p -20
+KPX nacute T -60
+KPX nacute T_h -60
+KPX Ncommaaccent oslash.sc -20
+KPX Ncommaaccent odieresis.sc -20
+KPX Ncommaaccent ccedilla.sc -25
+KPX Ncommaaccent ae.sc -25
+KPX Ncommaaccent aring.sc -35
+KPX Ncommaaccent adieresis.sc -35
+KPX Ncommaaccent o.sc -20
+KPX Ncommaaccent g.sc -25
+KPX Ncommaaccent c.sc -25
+KPX Ncommaaccent a.sc -35
+KPX Ncommaaccent omacron.sc -20
+KPX Ncommaaccent ohungarumlaut.sc -20
+KPX Ncommaaccent obreve.sc -20
+KPX Ncommaaccent gdotaccent.sc -25
+KPX Ncommaaccent gcommaaccent.sc -25
+KPX Ncommaaccent gcircumflex.sc -25
+KPX Ncommaaccent gbreve.sc -25
+KPX Ncommaaccent cdotaccent.sc -25
+KPX Ncommaaccent ccircumflex.sc -25
+KPX Ncommaaccent ccaron.sc -25
+KPX Ncommaaccent cacute.sc -25
+KPX Ncommaaccent aeacute.sc -25
+KPX Ncommaaccent aogonek.sc -35
+KPX Ncommaaccent amacron.sc -35
+KPX Ncommaaccent oogonek.sc -20
+KPX Ncommaaccent gcaron.sc -25
+KPX Ncommaaccent gacute.sc -25
+KPX Ncommaaccent aeacute -35
+KPX Ncommaaccent AEacute -30
+KPX Ncommaaccent Gacute -30
+KPX Ncommaaccent oogonek -30
+KPX Ncommaaccent Oogonek -25
+KPX Ncommaaccent Gcaron -30
+KPX Ncommaaccent uogonek -40
+KPX Ncommaaccent uhungarumlaut -40
+KPX Ncommaaccent uring -40
+KPX Ncommaaccent ubreve -40
+KPX Ncommaaccent umacron -40
+KPX Ncommaaccent ohungarumlaut -30
+KPX Ncommaaccent Ohungarumlaut -25
+KPX Ncommaaccent obreve -30
+KPX Ncommaaccent Obreve -25
+KPX Ncommaaccent omacron -30
+KPX Ncommaaccent Omacron -25
+KPX Ncommaaccent Gcommaaccent -30
+KPX Ncommaaccent Gdotaccent -30
+KPX Ncommaaccent Gbreve -30
+KPX Ncommaaccent Gcircumflex -30
+KPX Ncommaaccent ecaron -25
+KPX Ncommaaccent eogonek -25
+KPX Ncommaaccent edotaccent -25
+KPX Ncommaaccent ebreve -25
+KPX Ncommaaccent emacron -25
+KPX Ncommaaccent Ccaron -30
+KPX Ncommaaccent Cdotaccent -30
+KPX Ncommaaccent Ccircumflex -30
+KPX Ncommaaccent Cacute -30
+KPX Ncommaaccent aogonek -30
+KPX Ncommaaccent Aogonek -40
+KPX Ncommaaccent amacron -30
+KPX Ncommaaccent Amacron -40
+KPX Ncommaaccent udieresis -40
+KPX Ncommaaccent ucircumflex -40
+KPX Ncommaaccent oslash -30
+KPX Ncommaaccent odieresis -30
+KPX Ncommaaccent edieresis -25
+KPX Ncommaaccent ae -35
+KPX Ncommaaccent aring -30
+KPX Ncommaaccent adieresis -30
+KPX Ncommaaccent Oslash -25
+KPX Ncommaaccent Odieresis -25
+KPX Ncommaaccent Ccedilla -30
+KPX Ncommaaccent AE -30
+KPX Ncommaaccent Aring -40
+KPX Ncommaaccent Adieresis -40
+KPX Ncommaaccent u -40
+KPX Ncommaaccent o -30
+KPX Ncommaaccent e -25
+KPX Ncommaaccent a -30
+KPX Ncommaaccent O -25
+KPX Ncommaaccent G -30
+KPX Ncommaaccent C -30
+KPX Ncommaaccent A -40
+KPX Ncommaaccent period -30
+KPX Ncommaaccent comma -45
+KPX ncommaaccent quoteright -30
+KPX ncommaaccent wdieresis -35
+KPX ncommaaccent wacute -35
+KPX ncommaaccent wgrave -35
+KPX ncommaaccent uni021A -60
+KPX ncommaaccent ycircumflex -35
+KPX ncommaaccent wcircumflex -35
+KPX ncommaaccent Tcaron -60
+KPX ncommaaccent ydieresis -35
+KPX ncommaaccent y -35
+KPX ncommaaccent w -35
+KPX ncommaaccent v -35
+KPX ncommaaccent p -20
+KPX ncommaaccent T -60
+KPX ncommaaccent T_h -60
+KPX Ncaron oslash.sc -20
+KPX Ncaron odieresis.sc -20
+KPX Ncaron ccedilla.sc -25
+KPX Ncaron ae.sc -25
+KPX Ncaron aring.sc -35
+KPX Ncaron adieresis.sc -35
+KPX Ncaron o.sc -20
+KPX Ncaron g.sc -25
+KPX Ncaron c.sc -25
+KPX Ncaron a.sc -35
+KPX Ncaron omacron.sc -20
+KPX Ncaron ohungarumlaut.sc -20
+KPX Ncaron obreve.sc -20
+KPX Ncaron gdotaccent.sc -25
+KPX Ncaron gcommaaccent.sc -25
+KPX Ncaron gcircumflex.sc -25
+KPX Ncaron gbreve.sc -25
+KPX Ncaron cdotaccent.sc -25
+KPX Ncaron ccircumflex.sc -25
+KPX Ncaron ccaron.sc -25
+KPX Ncaron cacute.sc -25
+KPX Ncaron aeacute.sc -25
+KPX Ncaron aogonek.sc -35
+KPX Ncaron amacron.sc -35
+KPX Ncaron oogonek.sc -20
+KPX Ncaron gcaron.sc -25
+KPX Ncaron gacute.sc -25
+KPX Ncaron aeacute -35
+KPX Ncaron AEacute -30
+KPX Ncaron Gacute -30
+KPX Ncaron oogonek -30
+KPX Ncaron Oogonek -25
+KPX Ncaron Gcaron -30
+KPX Ncaron uogonek -40
+KPX Ncaron uhungarumlaut -40
+KPX Ncaron uring -40
+KPX Ncaron ubreve -40
+KPX Ncaron umacron -40
+KPX Ncaron ohungarumlaut -30
+KPX Ncaron Ohungarumlaut -25
+KPX Ncaron obreve -30
+KPX Ncaron Obreve -25
+KPX Ncaron omacron -30
+KPX Ncaron Omacron -25
+KPX Ncaron Gcommaaccent -30
+KPX Ncaron Gdotaccent -30
+KPX Ncaron Gbreve -30
+KPX Ncaron Gcircumflex -30
+KPX Ncaron ecaron -25
+KPX Ncaron eogonek -25
+KPX Ncaron edotaccent -25
+KPX Ncaron ebreve -25
+KPX Ncaron emacron -25
+KPX Ncaron Ccaron -30
+KPX Ncaron Cdotaccent -30
+KPX Ncaron Ccircumflex -30
+KPX Ncaron Cacute -30
+KPX Ncaron aogonek -30
+KPX Ncaron Aogonek -40
+KPX Ncaron amacron -30
+KPX Ncaron Amacron -40
+KPX Ncaron udieresis -40
+KPX Ncaron ucircumflex -40
+KPX Ncaron oslash -30
+KPX Ncaron odieresis -30
+KPX Ncaron edieresis -25
+KPX Ncaron ae -35
+KPX Ncaron aring -30
+KPX Ncaron adieresis -30
+KPX Ncaron Oslash -25
+KPX Ncaron Odieresis -25
+KPX Ncaron Ccedilla -30
+KPX Ncaron AE -30
+KPX Ncaron Aring -40
+KPX Ncaron Adieresis -40
+KPX Ncaron u -40
+KPX Ncaron o -30
+KPX Ncaron e -25
+KPX Ncaron a -30
+KPX Ncaron O -25
+KPX Ncaron G -30
+KPX Ncaron C -30
+KPX Ncaron A -40
+KPX Ncaron period -30
+KPX Ncaron comma -45
+KPX ncaron quoteright -30
+KPX ncaron wdieresis -35
+KPX ncaron wacute -35
+KPX ncaron wgrave -35
+KPX ncaron uni021A -60
+KPX ncaron ycircumflex -35
+KPX ncaron wcircumflex -35
+KPX ncaron Tcaron -60
+KPX ncaron ydieresis -35
+KPX ncaron y -35
+KPX ncaron w -35
+KPX ncaron v -35
+KPX ncaron p -20
+KPX ncaron T -60
+KPX ncaron T_h -60
+KPX Omacron ydieresis.sc -45
+KPX Omacron ae.sc -55
+KPX Omacron aring.sc -60
+KPX Omacron adieresis.sc -60
+KPX Omacron y.sc -45
+KPX Omacron x.sc -50
+KPX Omacron w.sc -35
+KPX Omacron v.sc -45
+KPX Omacron t.sc -10
+KPX Omacron a.sc -60
+KPX Omacron ycircumflex.sc -45
+KPX Omacron wgrave.sc -35
+KPX Omacron wdieresis.sc -35
+KPX Omacron wcircumflex.sc -35
+KPX Omacron wacute.sc -35
+KPX Omacron uni021B.sc -10
+KPX Omacron tcaron.sc -10
+KPX Omacron aeacute.sc -55
+KPX Omacron aogonek.sc -60
+KPX Omacron amacron.sc -60
+KPX Omacron Wdieresis -45
+KPX Omacron Wacute -45
+KPX Omacron Wgrave -45
+KPX Omacron uni021A -15
+KPX Omacron AEacute -65
+KPX Omacron Ydieresis -55
+KPX Omacron Ycircumflex -55
+KPX Omacron Wcircumflex -45
+KPX Omacron Tcaron -15
+KPX Omacron Aogonek -75
+KPX Omacron Amacron -75
+KPX Omacron AE -65
+KPX Omacron Aring -75
+KPX Omacron Adieresis -75
+KPX Omacron Y -55
+KPX Omacron X -60
+KPX Omacron W -45
+KPX Omacron V -55
+KPX Omacron T -15
+KPX Omacron A -75
+KPX Omacron T_h -15
+KPX omacron quoteright -20
+KPX omacron wdieresis -25
+KPX omacron wacute -25
+KPX omacron wgrave -25
+KPX omacron uni021B -15
+KPX omacron uni021A -100
+KPX omacron ycircumflex -30
+KPX omacron wcircumflex -25
+KPX omacron tcaron -15
+KPX omacron Tcaron -100
+KPX omacron ydieresis -30
+KPX omacron y -30
+KPX omacron x -30
+KPX omacron w -25
+KPX omacron v -25
+KPX omacron t -15
+KPX omacron T -100
+KPX omacron T_h -100
+KPX Obreve ydieresis.sc -45
+KPX Obreve ae.sc -55
+KPX Obreve aring.sc -60
+KPX Obreve adieresis.sc -60
+KPX Obreve y.sc -45
+KPX Obreve x.sc -50
+KPX Obreve w.sc -35
+KPX Obreve v.sc -45
+KPX Obreve t.sc -10
+KPX Obreve a.sc -60
+KPX Obreve ycircumflex.sc -45
+KPX Obreve wgrave.sc -35
+KPX Obreve wdieresis.sc -35
+KPX Obreve wcircumflex.sc -35
+KPX Obreve wacute.sc -35
+KPX Obreve uni021B.sc -10
+KPX Obreve tcaron.sc -10
+KPX Obreve aeacute.sc -55
+KPX Obreve aogonek.sc -60
+KPX Obreve amacron.sc -60
+KPX Obreve Wdieresis -45
+KPX Obreve Wacute -45
+KPX Obreve Wgrave -45
+KPX Obreve uni021A -15
+KPX Obreve AEacute -65
+KPX Obreve Ydieresis -55
+KPX Obreve Ycircumflex -55
+KPX Obreve Wcircumflex -45
+KPX Obreve Tcaron -15
+KPX Obreve Aogonek -75
+KPX Obreve Amacron -75
+KPX Obreve AE -65
+KPX Obreve Aring -75
+KPX Obreve Adieresis -75
+KPX Obreve Y -55
+KPX Obreve X -60
+KPX Obreve W -45
+KPX Obreve V -55
+KPX Obreve T -15
+KPX Obreve A -75
+KPX Obreve T_h -15
+KPX obreve quoteright -20
+KPX obreve wdieresis -25
+KPX obreve wacute -25
+KPX obreve wgrave -25
+KPX obreve uni021B -15
+KPX obreve uni021A -100
+KPX obreve ycircumflex -30
+KPX obreve wcircumflex -25
+KPX obreve tcaron -15
+KPX obreve Tcaron -100
+KPX obreve ydieresis -30
+KPX obreve y -30
+KPX obreve x -30
+KPX obreve w -25
+KPX obreve v -25
+KPX obreve t -15
+KPX obreve T -100
+KPX obreve T_h -100
+KPX Ohungarumlaut ydieresis.sc -45
+KPX Ohungarumlaut ae.sc -55
+KPX Ohungarumlaut aring.sc -60
+KPX Ohungarumlaut adieresis.sc -60
+KPX Ohungarumlaut y.sc -45
+KPX Ohungarumlaut x.sc -50
+KPX Ohungarumlaut w.sc -35
+KPX Ohungarumlaut v.sc -45
+KPX Ohungarumlaut t.sc -10
+KPX Ohungarumlaut a.sc -60
+KPX Ohungarumlaut ycircumflex.sc -45
+KPX Ohungarumlaut wgrave.sc -35
+KPX Ohungarumlaut wdieresis.sc -35
+KPX Ohungarumlaut wcircumflex.sc -35
+KPX Ohungarumlaut wacute.sc -35
+KPX Ohungarumlaut uni021B.sc -10
+KPX Ohungarumlaut tcaron.sc -10
+KPX Ohungarumlaut aeacute.sc -55
+KPX Ohungarumlaut aogonek.sc -60
+KPX Ohungarumlaut amacron.sc -60
+KPX Ohungarumlaut Wdieresis -45
+KPX Ohungarumlaut Wacute -45
+KPX Ohungarumlaut Wgrave -45
+KPX Ohungarumlaut uni021A -15
+KPX Ohungarumlaut AEacute -65
+KPX Ohungarumlaut Ydieresis -55
+KPX Ohungarumlaut Ycircumflex -55
+KPX Ohungarumlaut Wcircumflex -45
+KPX Ohungarumlaut Tcaron -15
+KPX Ohungarumlaut Aogonek -75
+KPX Ohungarumlaut Amacron -75
+KPX Ohungarumlaut AE -65
+KPX Ohungarumlaut Aring -75
+KPX Ohungarumlaut Adieresis -75
+KPX Ohungarumlaut Y -55
+KPX Ohungarumlaut X -60
+KPX Ohungarumlaut W -45
+KPX Ohungarumlaut V -55
+KPX Ohungarumlaut T -15
+KPX Ohungarumlaut A -75
+KPX Ohungarumlaut T_h -15
+KPX ohungarumlaut quoteright -20
+KPX ohungarumlaut wdieresis -25
+KPX ohungarumlaut wacute -25
+KPX ohungarumlaut wgrave -25
+KPX ohungarumlaut uni021B -15
+KPX ohungarumlaut uni021A -100
+KPX ohungarumlaut ycircumflex -30
+KPX ohungarumlaut wcircumflex -25
+KPX ohungarumlaut tcaron -15
+KPX ohungarumlaut Tcaron -100
+KPX ohungarumlaut ydieresis -30
+KPX ohungarumlaut y -30
+KPX ohungarumlaut x -30
+KPX ohungarumlaut w -25
+KPX ohungarumlaut v -25
+KPX ohungarumlaut t -15
+KPX ohungarumlaut T -100
+KPX ohungarumlaut T_h -100
+KPX Racute ydieresis.sc -40
+KPX Racute udieresis.sc -45
+KPX Racute ucircumflex.sc -45
+KPX Racute oslash.sc -35
+KPX Racute odieresis.sc -35
+KPX Racute ccedilla.sc -35
+KPX Racute y.sc -40
+KPX Racute w.sc -45
+KPX Racute v.sc -45
+KPX Racute u.sc -45
+KPX Racute t.sc -30
+KPX Racute o.sc -35
+KPX Racute g.sc -35
+KPX Racute c.sc -35
+KPX Racute ycircumflex.sc -40
+KPX Racute wgrave.sc -45
+KPX Racute wdieresis.sc -45
+KPX Racute wcircumflex.sc -45
+KPX Racute wacute.sc -45
+KPX Racute uring.sc -45
+KPX Racute uogonek.sc -45
+KPX Racute umacron.sc -45
+KPX Racute uhungarumlaut.sc -45
+KPX Racute ubreve.sc -45
+KPX Racute uni021B.sc -30
+KPX Racute tcaron.sc -30
+KPX Racute omacron.sc -35
+KPX Racute ohungarumlaut.sc -35
+KPX Racute obreve.sc -35
+KPX Racute gdotaccent.sc -35
+KPX Racute gcommaaccent.sc -35
+KPX Racute gcircumflex.sc -35
+KPX Racute gbreve.sc -35
+KPX Racute cdotaccent.sc -35
+KPX Racute ccircumflex.sc -35
+KPX Racute ccaron.sc -35
+KPX Racute cacute.sc -35
+KPX Racute oogonek.sc -35
+KPX Racute oe.sc -35
+KPX Racute gcaron.sc -35
+KPX Racute gacute.sc -35
+KPX Racute Wdieresis -55
+KPX Racute Wacute -55
+KPX Racute Wgrave -55
+KPX Racute uni021A -35
+KPX Racute Gacute -40
+KPX Racute oogonek -25
+KPX Racute Oogonek -40
+KPX Racute Gcaron -40
+KPX Racute Ydieresis -50
+KPX Racute ycircumflex -35
+KPX Racute Ycircumflex -50
+KPX Racute Wcircumflex -55
+KPX Racute uogonek -35
+KPX Racute Uogonek -55
+KPX Racute uhungarumlaut -35
+KPX Racute Uhungarumlaut -55
+KPX Racute uring -35
+KPX Racute Uring -55
+KPX Racute ubreve -35
+KPX Racute Ubreve -55
+KPX Racute umacron -35
+KPX Racute Umacron -55
+KPX Racute Tcaron -35
+KPX Racute oe -25
+KPX Racute OE -40
+KPX Racute ohungarumlaut -25
+KPX Racute Ohungarumlaut -40
+KPX Racute obreve -25
+KPX Racute Obreve -40
+KPX Racute omacron -25
+KPX Racute Omacron -40
+KPX Racute Gcommaaccent -40
+KPX Racute Gdotaccent -40
+KPX Racute Gbreve -40
+KPX Racute Gcircumflex -40
+KPX Racute ecaron -20
+KPX Racute eogonek -20
+KPX Racute edotaccent -20
+KPX Racute ebreve -20
+KPX Racute emacron -20
+KPX Racute Ccaron -40
+KPX Racute Cdotaccent -40
+KPX Racute Ccircumflex -40
+KPX Racute Cacute -40
+KPX Racute ydieresis -35
+KPX Racute udieresis -35
+KPX Racute ucircumflex -35
+KPX Racute oslash -25
+KPX Racute odieresis -25
+KPX Racute edieresis -20
+KPX Racute Udieresis -55
+KPX Racute Ucircumflex -55
+KPX Racute Oslash -40
+KPX Racute Odieresis -40
+KPX Racute Ccedilla -40
+KPX Racute y -35
+KPX Racute u -35
+KPX Racute o -25
+KPX Racute e -20
+KPX Racute Y -50
+KPX Racute W -55
+KPX Racute V -55
+KPX Racute U -55
+KPX Racute T -35
+KPX Racute O -40
+KPX Racute G -40
+KPX Racute C -40
+KPX Racute hyphen -50
+KPX Racute T_h -35
+KPX racute jacute 25
+KPX racute wdieresis 20
+KPX racute wacute 20
+KPX racute wgrave 20
+KPX racute aeacute -15
+KPX racute gacute -10
+KPX racute gcaron -10
+KPX racute zcaron -10
+KPX racute zdotaccent -10
+KPX racute zacute -10
+KPX racute ycircumflex 15
+KPX racute wcircumflex 20
+KPX racute uogonek 10
+KPX racute uhungarumlaut 10
+KPX racute uring 10
+KPX racute ubreve 10
+KPX racute umacron 10
+KPX racute ncaron 15
+KPX racute ncommaaccent 15
+KPX racute nacute 15
+KPX racute lslash -30
+KPX racute lcaron -30
+KPX racute lcommaaccent -30
+KPX racute lacute -30
+KPX racute kcommaaccent -30
+KPX racute jcircumflex 25
+KPX racute hcircumflex -20
+KPX racute gcommaaccent -10
+KPX racute gdotaccent -10
+KPX racute gbreve -10
+KPX racute gcircumflex -10
+KPX racute dcaron -15
+KPX racute aogonek -15
+KPX racute amacron -15
+KPX racute ydieresis 15
+KPX racute udieresis 10
+KPX racute ucircumflex 10
+KPX racute ntilde 15
+KPX racute ae -15
+KPX racute aring -15
+KPX racute adieresis -15
+KPX racute z -10
+KPX racute y 15
+KPX racute x 10
+KPX racute w 20
+KPX racute v 20
+KPX racute u 10
+KPX racute q -15
+KPX racute p 15
+KPX racute n 15
+KPX racute m 10
+KPX racute l -30
+KPX racute k -30
+KPX racute j 25
+KPX racute h -20
+KPX racute g -10
+KPX racute d -15
+KPX racute a -15
+KPX racute semicolon -30
+KPX racute colon -20
+KPX racute period -60
+KPX racute hyphen -30
+KPX racute comma -70
+KPX Rcommaaccent ydieresis.sc -40
+KPX Rcommaaccent udieresis.sc -45
+KPX Rcommaaccent ucircumflex.sc -45
+KPX Rcommaaccent oslash.sc -35
+KPX Rcommaaccent odieresis.sc -35
+KPX Rcommaaccent ccedilla.sc -35
+KPX Rcommaaccent y.sc -40
+KPX Rcommaaccent w.sc -45
+KPX Rcommaaccent v.sc -45
+KPX Rcommaaccent u.sc -45
+KPX Rcommaaccent t.sc -30
+KPX Rcommaaccent o.sc -35
+KPX Rcommaaccent g.sc -35
+KPX Rcommaaccent c.sc -35
+KPX Rcommaaccent ycircumflex.sc -40
+KPX Rcommaaccent wgrave.sc -45
+KPX Rcommaaccent wdieresis.sc -45
+KPX Rcommaaccent wcircumflex.sc -45
+KPX Rcommaaccent wacute.sc -45
+KPX Rcommaaccent uring.sc -45
+KPX Rcommaaccent uogonek.sc -45
+KPX Rcommaaccent umacron.sc -45
+KPX Rcommaaccent uhungarumlaut.sc -45
+KPX Rcommaaccent ubreve.sc -45
+KPX Rcommaaccent uni021B.sc -30
+KPX Rcommaaccent tcaron.sc -30
+KPX Rcommaaccent omacron.sc -35
+KPX Rcommaaccent ohungarumlaut.sc -35
+KPX Rcommaaccent obreve.sc -35
+KPX Rcommaaccent gdotaccent.sc -35
+KPX Rcommaaccent gcommaaccent.sc -35
+KPX Rcommaaccent gcircumflex.sc -35
+KPX Rcommaaccent gbreve.sc -35
+KPX Rcommaaccent cdotaccent.sc -35
+KPX Rcommaaccent ccircumflex.sc -35
+KPX Rcommaaccent ccaron.sc -35
+KPX Rcommaaccent cacute.sc -35
+KPX Rcommaaccent oogonek.sc -35
+KPX Rcommaaccent oe.sc -35
+KPX Rcommaaccent gcaron.sc -35
+KPX Rcommaaccent gacute.sc -35
+KPX Rcommaaccent Wdieresis -55
+KPX Rcommaaccent Wacute -55
+KPX Rcommaaccent Wgrave -55
+KPX Rcommaaccent uni021A -35
+KPX Rcommaaccent Gacute -40
+KPX Rcommaaccent oogonek -25
+KPX Rcommaaccent Oogonek -40
+KPX Rcommaaccent Gcaron -40
+KPX Rcommaaccent Ydieresis -50
+KPX Rcommaaccent ycircumflex -35
+KPX Rcommaaccent Ycircumflex -50
+KPX Rcommaaccent Wcircumflex -55
+KPX Rcommaaccent uogonek -35
+KPX Rcommaaccent Uogonek -55
+KPX Rcommaaccent uhungarumlaut -35
+KPX Rcommaaccent Uhungarumlaut -55
+KPX Rcommaaccent uring -35
+KPX Rcommaaccent Uring -55
+KPX Rcommaaccent ubreve -35
+KPX Rcommaaccent Ubreve -55
+KPX Rcommaaccent umacron -35
+KPX Rcommaaccent Umacron -55
+KPX Rcommaaccent Tcaron -35
+KPX Rcommaaccent oe -25
+KPX Rcommaaccent OE -40
+KPX Rcommaaccent ohungarumlaut -25
+KPX Rcommaaccent Ohungarumlaut -40
+KPX Rcommaaccent obreve -25
+KPX Rcommaaccent Obreve -40
+KPX Rcommaaccent omacron -25
+KPX Rcommaaccent Omacron -40
+KPX Rcommaaccent Gcommaaccent -40
+KPX Rcommaaccent Gdotaccent -40
+KPX Rcommaaccent Gbreve -40
+KPX Rcommaaccent Gcircumflex -40
+KPX Rcommaaccent ecaron -20
+KPX Rcommaaccent eogonek -20
+KPX Rcommaaccent edotaccent -20
+KPX Rcommaaccent ebreve -20
+KPX Rcommaaccent emacron -20
+KPX Rcommaaccent Ccaron -40
+KPX Rcommaaccent Cdotaccent -40
+KPX Rcommaaccent Ccircumflex -40
+KPX Rcommaaccent Cacute -40
+KPX Rcommaaccent ydieresis -35
+KPX Rcommaaccent udieresis -35
+KPX Rcommaaccent ucircumflex -35
+KPX Rcommaaccent oslash -25
+KPX Rcommaaccent odieresis -25
+KPX Rcommaaccent edieresis -20
+KPX Rcommaaccent Udieresis -55
+KPX Rcommaaccent Ucircumflex -55
+KPX Rcommaaccent Oslash -40
+KPX Rcommaaccent Odieresis -40
+KPX Rcommaaccent Ccedilla -40
+KPX Rcommaaccent y -35
+KPX Rcommaaccent u -35
+KPX Rcommaaccent o -25
+KPX Rcommaaccent e -20
+KPX Rcommaaccent Y -50
+KPX Rcommaaccent W -55
+KPX Rcommaaccent V -55
+KPX Rcommaaccent U -55
+KPX Rcommaaccent T -35
+KPX Rcommaaccent O -40
+KPX Rcommaaccent G -40
+KPX Rcommaaccent C -40
+KPX Rcommaaccent hyphen -50
+KPX Rcommaaccent T_h -35
+KPX rcommaaccent jacute 25
+KPX rcommaaccent wdieresis 20
+KPX rcommaaccent wacute 20
+KPX rcommaaccent wgrave 20
+KPX rcommaaccent aeacute -15
+KPX rcommaaccent gacute -10
+KPX rcommaaccent gcaron -10
+KPX rcommaaccent zcaron -10
+KPX rcommaaccent zdotaccent -10
+KPX rcommaaccent zacute -10
+KPX rcommaaccent ycircumflex 15
+KPX rcommaaccent wcircumflex 20
+KPX rcommaaccent uogonek 10
+KPX rcommaaccent uhungarumlaut 10
+KPX rcommaaccent uring 10
+KPX rcommaaccent ubreve 10
+KPX rcommaaccent umacron 10
+KPX rcommaaccent ncaron 15
+KPX rcommaaccent ncommaaccent 15
+KPX rcommaaccent nacute 15
+KPX rcommaaccent lslash -30
+KPX rcommaaccent lcaron -30
+KPX rcommaaccent lcommaaccent -30
+KPX rcommaaccent lacute -30
+KPX rcommaaccent kcommaaccent -30
+KPX rcommaaccent jcircumflex 25
+KPX rcommaaccent hcircumflex -20
+KPX rcommaaccent gcommaaccent -10
+KPX rcommaaccent gdotaccent -10
+KPX rcommaaccent gbreve -10
+KPX rcommaaccent gcircumflex -10
+KPX rcommaaccent dcaron -15
+KPX rcommaaccent aogonek -15
+KPX rcommaaccent amacron -15
+KPX rcommaaccent ydieresis 15
+KPX rcommaaccent udieresis 10
+KPX rcommaaccent ucircumflex 10
+KPX rcommaaccent ntilde 15
+KPX rcommaaccent ae -15
+KPX rcommaaccent aring -15
+KPX rcommaaccent adieresis -15
+KPX rcommaaccent z -10
+KPX rcommaaccent y 15
+KPX rcommaaccent x 10
+KPX rcommaaccent w 20
+KPX rcommaaccent v 20
+KPX rcommaaccent u 10
+KPX rcommaaccent q -15
+KPX rcommaaccent p 15
+KPX rcommaaccent n 15
+KPX rcommaaccent m 10
+KPX rcommaaccent l -30
+KPX rcommaaccent k -30
+KPX rcommaaccent j 25
+KPX rcommaaccent h -20
+KPX rcommaaccent g -10
+KPX rcommaaccent d -15
+KPX rcommaaccent a -15
+KPX rcommaaccent semicolon -30
+KPX rcommaaccent colon -20
+KPX rcommaaccent period -60
+KPX rcommaaccent hyphen -30
+KPX rcommaaccent comma -70
+KPX Rcaron ydieresis.sc -40
+KPX Rcaron udieresis.sc -45
+KPX Rcaron ucircumflex.sc -45
+KPX Rcaron oslash.sc -35
+KPX Rcaron odieresis.sc -35
+KPX Rcaron ccedilla.sc -35
+KPX Rcaron y.sc -40
+KPX Rcaron w.sc -45
+KPX Rcaron v.sc -45
+KPX Rcaron u.sc -45
+KPX Rcaron t.sc -30
+KPX Rcaron o.sc -35
+KPX Rcaron g.sc -35
+KPX Rcaron c.sc -35
+KPX Rcaron ycircumflex.sc -40
+KPX Rcaron wgrave.sc -45
+KPX Rcaron wdieresis.sc -45
+KPX Rcaron wcircumflex.sc -45
+KPX Rcaron wacute.sc -45
+KPX Rcaron uring.sc -45
+KPX Rcaron uogonek.sc -45
+KPX Rcaron umacron.sc -45
+KPX Rcaron uhungarumlaut.sc -45
+KPX Rcaron ubreve.sc -45
+KPX Rcaron uni021B.sc -30
+KPX Rcaron tcaron.sc -30
+KPX Rcaron omacron.sc -35
+KPX Rcaron ohungarumlaut.sc -35
+KPX Rcaron obreve.sc -35
+KPX Rcaron gdotaccent.sc -35
+KPX Rcaron gcommaaccent.sc -35
+KPX Rcaron gcircumflex.sc -35
+KPX Rcaron gbreve.sc -35
+KPX Rcaron cdotaccent.sc -35
+KPX Rcaron ccircumflex.sc -35
+KPX Rcaron ccaron.sc -35
+KPX Rcaron cacute.sc -35
+KPX Rcaron oogonek.sc -35
+KPX Rcaron oe.sc -35
+KPX Rcaron gcaron.sc -35
+KPX Rcaron gacute.sc -35
+KPX Rcaron Wdieresis -55
+KPX Rcaron Wacute -55
+KPX Rcaron Wgrave -55
+KPX Rcaron uni021A -35
+KPX Rcaron Gacute -40
+KPX Rcaron oogonek -25
+KPX Rcaron Oogonek -40
+KPX Rcaron Gcaron -40
+KPX Rcaron Ydieresis -50
+KPX Rcaron ycircumflex -35
+KPX Rcaron Ycircumflex -50
+KPX Rcaron Wcircumflex -55
+KPX Rcaron uogonek -35
+KPX Rcaron Uogonek -55
+KPX Rcaron uhungarumlaut -35
+KPX Rcaron Uhungarumlaut -55
+KPX Rcaron uring -35
+KPX Rcaron Uring -55
+KPX Rcaron ubreve -35
+KPX Rcaron Ubreve -55
+KPX Rcaron umacron -35
+KPX Rcaron Umacron -55
+KPX Rcaron Tcaron -35
+KPX Rcaron oe -25
+KPX Rcaron OE -40
+KPX Rcaron ohungarumlaut -25
+KPX Rcaron Ohungarumlaut -40
+KPX Rcaron obreve -25
+KPX Rcaron Obreve -40
+KPX Rcaron omacron -25
+KPX Rcaron Omacron -40
+KPX Rcaron Gcommaaccent -40
+KPX Rcaron Gdotaccent -40
+KPX Rcaron Gbreve -40
+KPX Rcaron Gcircumflex -40
+KPX Rcaron ecaron -20
+KPX Rcaron eogonek -20
+KPX Rcaron edotaccent -20
+KPX Rcaron ebreve -20
+KPX Rcaron emacron -20
+KPX Rcaron Ccaron -40
+KPX Rcaron Cdotaccent -40
+KPX Rcaron Ccircumflex -40
+KPX Rcaron Cacute -40
+KPX Rcaron ydieresis -35
+KPX Rcaron udieresis -35
+KPX Rcaron ucircumflex -35
+KPX Rcaron oslash -25
+KPX Rcaron odieresis -25
+KPX Rcaron edieresis -20
+KPX Rcaron Udieresis -55
+KPX Rcaron Ucircumflex -55
+KPX Rcaron Oslash -40
+KPX Rcaron Odieresis -40
+KPX Rcaron Ccedilla -40
+KPX Rcaron y -35
+KPX Rcaron u -35
+KPX Rcaron o -25
+KPX Rcaron e -20
+KPX Rcaron Y -50
+KPX Rcaron W -55
+KPX Rcaron V -55
+KPX Rcaron U -55
+KPX Rcaron T -35
+KPX Rcaron O -40
+KPX Rcaron G -40
+KPX Rcaron C -40
+KPX Rcaron hyphen -50
+KPX Rcaron T_h -35
+KPX rcaron jacute 25
+KPX rcaron wdieresis 20
+KPX rcaron wacute 20
+KPX rcaron wgrave 20
+KPX rcaron aeacute -15
+KPX rcaron gacute -10
+KPX rcaron gcaron -10
+KPX rcaron zcaron -10
+KPX rcaron zdotaccent -10
+KPX rcaron zacute -10
+KPX rcaron ycircumflex 15
+KPX rcaron wcircumflex 20
+KPX rcaron uogonek 10
+KPX rcaron uhungarumlaut 10
+KPX rcaron uring 10
+KPX rcaron ubreve 10
+KPX rcaron umacron 10
+KPX rcaron ncaron 15
+KPX rcaron ncommaaccent 15
+KPX rcaron nacute 15
+KPX rcaron lslash -30
+KPX rcaron lcaron -30
+KPX rcaron lcommaaccent -30
+KPX rcaron lacute -30
+KPX rcaron kcommaaccent -30
+KPX rcaron jcircumflex 25
+KPX rcaron hcircumflex -20
+KPX rcaron gcommaaccent -10
+KPX rcaron gdotaccent -10
+KPX rcaron gbreve -10
+KPX rcaron gcircumflex -10
+KPX rcaron dcaron -15
+KPX rcaron aogonek -15
+KPX rcaron amacron -15
+KPX rcaron ydieresis 15
+KPX rcaron udieresis 10
+KPX rcaron ucircumflex 10
+KPX rcaron ntilde 15
+KPX rcaron ae -15
+KPX rcaron aring -15
+KPX rcaron adieresis -15
+KPX rcaron z -10
+KPX rcaron y 15
+KPX rcaron x 10
+KPX rcaron w 20
+KPX rcaron v 20
+KPX rcaron u 10
+KPX rcaron q -15
+KPX rcaron p 15
+KPX rcaron n 15
+KPX rcaron m 10
+KPX rcaron l -30
+KPX rcaron k -30
+KPX rcaron j 25
+KPX rcaron h -20
+KPX rcaron g -10
+KPX rcaron d -15
+KPX rcaron a -15
+KPX rcaron semicolon -30
+KPX rcaron colon -20
+KPX rcaron period -60
+KPX rcaron hyphen -30
+KPX rcaron comma -70
+KPX Sacute ydieresis.sc -10
+KPX Sacute ae.sc -25
+KPX Sacute aring.sc -35
+KPX Sacute adieresis.sc -35
+KPX Sacute y.sc -10
+KPX Sacute w.sc -10
+KPX Sacute v.sc -10
+KPX Sacute t.sc -15
+KPX Sacute a.sc -35
+KPX Sacute ycircumflex.sc -10
+KPX Sacute wgrave.sc -10
+KPX Sacute wdieresis.sc -10
+KPX Sacute wcircumflex.sc -10
+KPX Sacute wacute.sc -10
+KPX Sacute uni021B.sc -15
+KPX Sacute tcaron.sc -15
+KPX Sacute aeacute.sc -25
+KPX Sacute aogonek.sc -35
+KPX Sacute amacron.sc -35
+KPX Sacute Wdieresis -15
+KPX Sacute Wacute -15
+KPX Sacute Wgrave -15
+KPX Sacute uni021B -20
+KPX Sacute uni021A -20
+KPX Sacute AEacute -30
+KPX Sacute Ydieresis -15
+KPX Sacute Ycircumflex -15
+KPX Sacute Wcircumflex -15
+KPX Sacute tcaron -20
+KPX Sacute Tcaron -20
+KPX Sacute Aogonek -40
+KPX Sacute Amacron -40
+KPX Sacute AE -30
+KPX Sacute Aring -40
+KPX Sacute Adieresis -40
+KPX Sacute t -20
+KPX Sacute Y -15
+KPX Sacute W -15
+KPX Sacute V -15
+KPX Sacute T -20
+KPX Sacute A -40
+KPX Sacute T_h -20
+KPX sacute quoteright -15
+KPX sacute uni021B -15
+KPX sacute tcaron -15
+KPX sacute t -15
+KPX Scircumflex ydieresis.sc -10
+KPX Scircumflex ae.sc -25
+KPX Scircumflex aring.sc -35
+KPX Scircumflex adieresis.sc -35
+KPX Scircumflex y.sc -10
+KPX Scircumflex w.sc -10
+KPX Scircumflex v.sc -10
+KPX Scircumflex t.sc -15
+KPX Scircumflex a.sc -35
+KPX Scircumflex ycircumflex.sc -10
+KPX Scircumflex wgrave.sc -10
+KPX Scircumflex wdieresis.sc -10
+KPX Scircumflex wcircumflex.sc -10
+KPX Scircumflex wacute.sc -10
+KPX Scircumflex uni021B.sc -15
+KPX Scircumflex tcaron.sc -15
+KPX Scircumflex aeacute.sc -25
+KPX Scircumflex aogonek.sc -35
+KPX Scircumflex amacron.sc -35
+KPX Scircumflex Wdieresis -15
+KPX Scircumflex Wacute -15
+KPX Scircumflex Wgrave -15
+KPX Scircumflex uni021B -20
+KPX Scircumflex uni021A -20
+KPX Scircumflex AEacute -30
+KPX Scircumflex Ydieresis -15
+KPX Scircumflex Ycircumflex -15
+KPX Scircumflex Wcircumflex -15
+KPX Scircumflex tcaron -20
+KPX Scircumflex Tcaron -20
+KPX Scircumflex Aogonek -40
+KPX Scircumflex Amacron -40
+KPX Scircumflex AE -30
+KPX Scircumflex Aring -40
+KPX Scircumflex Adieresis -40
+KPX Scircumflex t -20
+KPX Scircumflex Y -15
+KPX Scircumflex W -15
+KPX Scircumflex V -15
+KPX Scircumflex T -20
+KPX Scircumflex A -40
+KPX Scircumflex T_h -20
+KPX scircumflex quoteright -15
+KPX scircumflex uni021B -15
+KPX scircumflex tcaron -15
+KPX scircumflex t -15
+KPX Scedilla ydieresis.sc -10
+KPX Scedilla ae.sc -25
+KPX Scedilla aring.sc -35
+KPX Scedilla adieresis.sc -35
+KPX Scedilla y.sc -10
+KPX Scedilla w.sc -10
+KPX Scedilla v.sc -10
+KPX Scedilla t.sc -15
+KPX Scedilla a.sc -35
+KPX Scedilla ycircumflex.sc -10
+KPX Scedilla wgrave.sc -10
+KPX Scedilla wdieresis.sc -10
+KPX Scedilla wcircumflex.sc -10
+KPX Scedilla wacute.sc -10
+KPX Scedilla uni021B.sc -15
+KPX Scedilla tcaron.sc -15
+KPX Scedilla aeacute.sc -25
+KPX Scedilla aogonek.sc -35
+KPX Scedilla amacron.sc -35
+KPX Scedilla Wdieresis -15
+KPX Scedilla Wacute -15
+KPX Scedilla Wgrave -15
+KPX Scedilla uni021B -20
+KPX Scedilla uni021A -20
+KPX Scedilla AEacute -30
+KPX Scedilla Ydieresis -15
+KPX Scedilla Ycircumflex -15
+KPX Scedilla Wcircumflex -15
+KPX Scedilla tcaron -20
+KPX Scedilla Tcaron -20
+KPX Scedilla Aogonek -40
+KPX Scedilla Amacron -40
+KPX Scedilla AE -30
+KPX Scedilla Aring -40
+KPX Scedilla Adieresis -40
+KPX Scedilla t -20
+KPX Scedilla Y -15
+KPX Scedilla W -15
+KPX Scedilla V -15
+KPX Scedilla T -20
+KPX Scedilla A -40
+KPX Scedilla T_h -20
+KPX scedilla quoteright -15
+KPX scedilla uni021B -15
+KPX scedilla tcaron -15
+KPX scedilla t -15
+KPX Scaron ydieresis.sc -10
+KPX Scaron ae.sc -25
+KPX Scaron aring.sc -35
+KPX Scaron adieresis.sc -35
+KPX Scaron y.sc -10
+KPX Scaron w.sc -10
+KPX Scaron v.sc -10
+KPX Scaron t.sc -15
+KPX Scaron a.sc -35
+KPX Scaron ycircumflex.sc -10
+KPX Scaron wgrave.sc -10
+KPX Scaron wdieresis.sc -10
+KPX Scaron wcircumflex.sc -10
+KPX Scaron wacute.sc -10
+KPX Scaron uni021B.sc -15
+KPX Scaron tcaron.sc -15
+KPX Scaron aeacute.sc -25
+KPX Scaron aogonek.sc -35
+KPX Scaron amacron.sc -35
+KPX Scaron Wdieresis -15
+KPX Scaron Wacute -15
+KPX Scaron Wgrave -15
+KPX Scaron uni021B -20
+KPX Scaron uni021A -20
+KPX Scaron AEacute -30
+KPX Scaron Ydieresis -15
+KPX Scaron Ycircumflex -15
+KPX Scaron Wcircumflex -15
+KPX Scaron tcaron -20
+KPX Scaron Tcaron -20
+KPX Scaron Aogonek -40
+KPX Scaron Amacron -40
+KPX Scaron AE -30
+KPX Scaron Aring -40
+KPX Scaron Adieresis -40
+KPX Scaron t -20
+KPX Scaron Y -15
+KPX Scaron W -15
+KPX Scaron V -15
+KPX Scaron T -20
+KPX Scaron A -40
+KPX Scaron T_h -20
+KPX scaron quoteright -15
+KPX scaron uni021B -15
+KPX scaron tcaron -15
+KPX scaron t -15
+KPX Tcaron oslash.sc -15
+KPX Tcaron odieresis.sc -10
+KPX Tcaron otilde.sc -10
+KPX Tcaron ocircumflex.sc -10
+KPX Tcaron oacute.sc -10
+KPX Tcaron ograve.sc -10
+KPX Tcaron ccedilla.sc -20
+KPX Tcaron ae.sc -80
+KPX Tcaron aring.sc -25
+KPX Tcaron adieresis.sc -25
+KPX Tcaron atilde.sc -25
+KPX Tcaron acircumflex.sc -25
+KPX Tcaron aacute.sc -40
+KPX Tcaron agrave.sc -25
+KPX Tcaron o.sc -15
+KPX Tcaron g.sc -20
+KPX Tcaron c.sc -20
+KPX Tcaron a.sc -55
+KPX Tcaron omacron.sc -10
+KPX Tcaron ohungarumlaut.sc -10
+KPX Tcaron obreve.sc -10
+KPX Tcaron gdotaccent.sc -10
+KPX Tcaron gcommaaccent.sc -20
+KPX Tcaron gcircumflex.sc -10
+KPX Tcaron gbreve.sc -10
+KPX Tcaron cdotaccent.sc -10
+KPX Tcaron ccircumflex.sc -10
+KPX Tcaron ccaron.sc -10
+KPX Tcaron cacute.sc -15
+KPX Tcaron aeacute.sc -80
+KPX Tcaron aogonek.sc -55
+KPX Tcaron amacron.sc -25
+KPX Tcaron abreve.sc -25
+KPX Tcaron jacute -10
+KPX Tcaron oogonek.sc -15
+KPX Tcaron ohorntilde.sc -10
+KPX Tcaron ohornhookabove.sc -10
+KPX Tcaron ohorngrave.sc -10
+KPX Tcaron ohorndotbelow.sc -10
+KPX Tcaron ohornacute.sc -10
+KPX Tcaron ohookabove.sc -10
+KPX Tcaron oe.sc -40
+KPX Tcaron ocircumflexdotbelow.sc -10
+KPX Tcaron gcaron.sc -10
+KPX Tcaron gacute.sc -15
+KPX Tcaron ahookabove.sc -25
+KPX Tcaron acircumflexdotbelow.sc -25
+KPX Tcaron abrevedotbelow.sc -25
+KPX Tcaron guilsinglleft -135
+KPX Tcaron ytilde -55
+KPX Tcaron yhookabove -55
+KPX Tcaron ygrave -55
+KPX Tcaron uhorndotbelow -55
+KPX Tcaron uhorntilde -55
+KPX Tcaron uhornhookabove -55
+KPX Tcaron uhorngrave -55
+KPX Tcaron uhornacute -55
+KPX Tcaron uhookabove -55
+KPX Tcaron ohorndotbelow -50
+KPX Tcaron ohorntilde -50
+KPX Tcaron ohornhookabove -50
+KPX Tcaron ohorngrave -50
+KPX Tcaron ohornacute -50
+KPX Tcaron ocircumflexdotbelow -50
+KPX Tcaron ohookabove -50
+KPX Tcaron ihookabove -15
+KPX Tcaron ecircumflexdotbelow -50
+KPX Tcaron etilde -50
+KPX Tcaron ehookabove -50
+KPX Tcaron abrevedotbelow -40
+KPX Tcaron acircumflexdotbelow -40
+KPX Tcaron ahookabove -40
+KPX Tcaron wdieresis -55
+KPX Tcaron wacute -80
+KPX Tcaron wgrave -55
+KPX Tcaron rdotaccent -35
+KPX Tcaron uni0219 -70
+KPX Tcaron aeacute -75
+KPX Tcaron AEacute -115
+KPX Tcaron gacute -70
+KPX Tcaron Gacute -25
+KPX Tcaron oogonek -100
+KPX Tcaron Oogonek -20
+KPX Tcaron gcaron -50
+KPX Tcaron Gcaron -25
+KPX Tcaron ycircumflex -55
+KPX Tcaron wcircumflex -55
+KPX Tcaron uogonek -110
+KPX Tcaron uhungarumlaut -55
+KPX Tcaron uring -55
+KPX Tcaron ubreve -55
+KPX Tcaron umacron -55
+KPX Tcaron utilde -55
+KPX Tcaron scaron -35
+KPX Tcaron scedilla -70
+KPX Tcaron scircumflex -35
+KPX Tcaron sacute -55
+KPX Tcaron rcaron -35
+KPX Tcaron rcommaaccent -65
+KPX Tcaron racute -50
+KPX Tcaron oe -70
+KPX Tcaron OE -55
+KPX Tcaron ohungarumlaut -50
+KPX Tcaron Ohungarumlaut -20
+KPX Tcaron obreve -50
+KPX Tcaron Obreve -20
+KPX Tcaron omacron -50
+KPX Tcaron Omacron -20
+KPX Tcaron jcircumflex -5
+KPX Tcaron iogonek -25
+KPX Tcaron ibreve -15
+KPX Tcaron imacron -15
+KPX Tcaron itilde -15
+KPX Tcaron gcommaaccent -95
+KPX Tcaron Gcommaaccent -25
+KPX Tcaron gdotaccent -50
+KPX Tcaron Gdotaccent -25
+KPX Tcaron gbreve -50
+KPX Tcaron Gbreve -25
+KPX Tcaron gcircumflex -50
+KPX Tcaron Gcircumflex -25
+KPX Tcaron ecaron -50
+KPX Tcaron eogonek -95
+KPX Tcaron edotaccent -50
+KPX Tcaron ebreve -50
+KPX Tcaron emacron -50
+KPX Tcaron ccaron -50
+KPX Tcaron Ccaron -25
+KPX Tcaron cdotaccent -50
+KPX Tcaron Cdotaccent -25
+KPX Tcaron ccircumflex -50
+KPX Tcaron Ccircumflex -25
+KPX Tcaron cacute -70
+KPX Tcaron Cacute -25
+KPX Tcaron aogonek -80
+KPX Tcaron Aogonek -65
+KPX Tcaron abreve -40
+KPX Tcaron amacron -40
+KPX Tcaron Amacron -65
+KPX Tcaron ydieresis -55
+KPX Tcaron yacute -85
+KPX Tcaron udieresis -55
+KPX Tcaron ucircumflex -55
+KPX Tcaron uacute -85
+KPX Tcaron ugrave -55
+KPX Tcaron oslash -100
+KPX Tcaron odieresis -50
+KPX Tcaron otilde -50
+KPX Tcaron ocircumflex -50
+KPX Tcaron oacute -75
+KPX Tcaron ograve -50
+KPX Tcaron idieresis -15
+KPX Tcaron icircumflex -15
+KPX Tcaron iacute -20
+KPX Tcaron igrave -15
+KPX Tcaron edieresis -50
+KPX Tcaron ecircumflex -50
+KPX Tcaron eacute -70
+KPX Tcaron egrave -50
+KPX Tcaron ccedilla -95
+KPX Tcaron ae -75
+KPX Tcaron aring -40
+KPX Tcaron adieresis -40
+KPX Tcaron atilde -40
+KPX Tcaron acircumflex -40
+KPX Tcaron aacute -60
+KPX Tcaron agrave -40
+KPX Tcaron Oslash -20
+KPX Tcaron Odieresis -20
+KPX Tcaron Ccedilla -25
+KPX Tcaron AE -115
+KPX Tcaron Aring -65
+KPX Tcaron Adieresis -65
+KPX Tcaron guillemotleft -125
+KPX Tcaron y -110
+KPX Tcaron w -105
+KPX Tcaron v -105
+KPX Tcaron u -110
+KPX Tcaron s -70
+KPX Tcaron r -65
+KPX Tcaron o -100
+KPX Tcaron j -10
+KPX Tcaron i -25
+KPX Tcaron g -95
+KPX Tcaron e -95
+KPX Tcaron c -95
+KPX Tcaron a -80
+KPX Tcaron O -20
+KPX Tcaron G -25
+KPX Tcaron C -25
+KPX Tcaron A -65
+KPX Tcaron semicolon -100
+KPX Tcaron colon -95
+KPX Tcaron period -90
+KPX Tcaron hyphen -75
+KPX Tcaron comma -100
+KPX tcaron quotedblright 35
+KPX tcaron quotedblleft 35
+KPX tcaron quoteright 35
+KPX tcaron quoteleft 35
+KPX tcaron oogonek -10
+KPX tcaron ohungarumlaut -10
+KPX tcaron obreve -10
+KPX tcaron omacron -10
+KPX tcaron lcaron 30
+KPX tcaron lcommaaccent 30
+KPX tcaron lacute 30
+KPX tcaron kcommaaccent 30
+KPX tcaron hcircumflex 15
+KPX tcaron thorn 30
+KPX tcaron oslash -10
+KPX tcaron odieresis -10
+KPX tcaron o -10
+KPX tcaron l 30
+KPX tcaron k 30
+KPX tcaron h 15
+KPX tcaron b 30
+KPX tcaron backslash 35
+KPX tcaron semicolon -25
+KPX Utilde aring.sc -35
+KPX Utilde adieresis.sc -35
+KPX Utilde atilde.sc -35
+KPX Utilde acircumflex.sc -35
+KPX Utilde aacute.sc -50
+KPX Utilde agrave.sc -35
+KPX Utilde a.sc -65
+KPX Utilde amacron.sc -35
+KPX Utilde abreve.sc -35
+KPX Utilde ahookabove.sc -35
+KPX Utilde acircumflexdotbelow.sc -35
+KPX Utilde abrevedotbelow.sc -35
+KPX Utilde rdotaccent -20
+KPX Utilde rcaron -20
+KPX Utilde racute -30
+KPX Utilde ncaron -20
+KPX Utilde nacute -25
+KPX Utilde ntilde -20
+KPX Utilde n -35
+KPX Utilde m -40
+KPX Utilde A -80
+KPX Umacron ae.sc -60
+KPX Umacron aring.sc -35
+KPX Umacron adieresis.sc -35
+KPX Umacron atilde.sc -35
+KPX Umacron acircumflex.sc -35
+KPX Umacron aacute.sc -50
+KPX Umacron agrave.sc -35
+KPX Umacron a.sc -65
+KPX Umacron aeacute.sc -60
+KPX Umacron aogonek.sc -65
+KPX Umacron amacron.sc -35
+KPX Umacron abreve.sc -35
+KPX Umacron ahookabove.sc -35
+KPX Umacron acircumflexdotbelow.sc -35
+KPX Umacron abrevedotbelow.sc -35
+KPX Umacron rdotaccent -20
+KPX Umacron AEacute -70
+KPX Umacron rcaron -20
+KPX Umacron rcommaaccent -40
+KPX Umacron racute -30
+KPX Umacron ncaron -20
+KPX Umacron ncommaaccent -35
+KPX Umacron nacute -25
+KPX Umacron Aogonek -80
+KPX Umacron Amacron -80
+KPX Umacron ntilde -20
+KPX Umacron AE -70
+KPX Umacron Aring -80
+KPX Umacron Adieresis -80
+KPX Umacron r -40
+KPX Umacron p -35
+KPX Umacron n -35
+KPX Umacron m -40
+KPX Umacron A -80
+KPX Umacron period -50
+KPX Umacron comma -65
+KPX umacron quoteright -20
+KPX Ubreve ae.sc -60
+KPX Ubreve aring.sc -35
+KPX Ubreve adieresis.sc -35
+KPX Ubreve atilde.sc -35
+KPX Ubreve acircumflex.sc -35
+KPX Ubreve aacute.sc -50
+KPX Ubreve agrave.sc -35
+KPX Ubreve a.sc -65
+KPX Ubreve aeacute.sc -60
+KPX Ubreve aogonek.sc -65
+KPX Ubreve amacron.sc -35
+KPX Ubreve abreve.sc -35
+KPX Ubreve ahookabove.sc -35
+KPX Ubreve acircumflexdotbelow.sc -35
+KPX Ubreve abrevedotbelow.sc -35
+KPX Ubreve rdotaccent -20
+KPX Ubreve AEacute -70
+KPX Ubreve rcaron -20
+KPX Ubreve rcommaaccent -40
+KPX Ubreve racute -30
+KPX Ubreve ncaron -20
+KPX Ubreve ncommaaccent -35
+KPX Ubreve nacute -25
+KPX Ubreve Aogonek -80
+KPX Ubreve Amacron -80
+KPX Ubreve ntilde -20
+KPX Ubreve AE -70
+KPX Ubreve Aring -80
+KPX Ubreve Adieresis -80
+KPX Ubreve r -40
+KPX Ubreve p -35
+KPX Ubreve n -35
+KPX Ubreve m -40
+KPX Ubreve A -80
+KPX Ubreve period -50
+KPX Ubreve comma -65
+KPX ubreve quoteright -20
+KPX Uring ae.sc -60
+KPX Uring aring.sc -35
+KPX Uring adieresis.sc -35
+KPX Uring atilde.sc -35
+KPX Uring acircumflex.sc -35
+KPX Uring aacute.sc -50
+KPX Uring agrave.sc -35
+KPX Uring a.sc -65
+KPX Uring aeacute.sc -60
+KPX Uring aogonek.sc -65
+KPX Uring amacron.sc -35
+KPX Uring abreve.sc -35
+KPX Uring ahookabove.sc -35
+KPX Uring acircumflexdotbelow.sc -35
+KPX Uring abrevedotbelow.sc -35
+KPX Uring rdotaccent -20
+KPX Uring AEacute -70
+KPX Uring rcaron -20
+KPX Uring rcommaaccent -40
+KPX Uring racute -30
+KPX Uring ncaron -20
+KPX Uring ncommaaccent -35
+KPX Uring nacute -25
+KPX Uring Aogonek -80
+KPX Uring Amacron -80
+KPX Uring ntilde -20
+KPX Uring AE -70
+KPX Uring Aring -80
+KPX Uring Adieresis -80
+KPX Uring r -40
+KPX Uring p -35
+KPX Uring n -35
+KPX Uring m -40
+KPX Uring A -80
+KPX Uring period -50
+KPX Uring comma -65
+KPX uring quoteright -20
+KPX Uhungarumlaut ae.sc -60
+KPX Uhungarumlaut aring.sc -35
+KPX Uhungarumlaut adieresis.sc -35
+KPX Uhungarumlaut atilde.sc -35
+KPX Uhungarumlaut acircumflex.sc -35
+KPX Uhungarumlaut aacute.sc -50
+KPX Uhungarumlaut agrave.sc -35
+KPX Uhungarumlaut a.sc -65
+KPX Uhungarumlaut aeacute.sc -60
+KPX Uhungarumlaut aogonek.sc -65
+KPX Uhungarumlaut amacron.sc -35
+KPX Uhungarumlaut abreve.sc -35
+KPX Uhungarumlaut ahookabove.sc -35
+KPX Uhungarumlaut acircumflexdotbelow.sc -35
+KPX Uhungarumlaut abrevedotbelow.sc -35
+KPX Uhungarumlaut rdotaccent -20
+KPX Uhungarumlaut AEacute -70
+KPX Uhungarumlaut rcaron -20
+KPX Uhungarumlaut rcommaaccent -40
+KPX Uhungarumlaut racute -30
+KPX Uhungarumlaut ncaron -20
+KPX Uhungarumlaut ncommaaccent -35
+KPX Uhungarumlaut nacute -25
+KPX Uhungarumlaut Aogonek -80
+KPX Uhungarumlaut Amacron -80
+KPX Uhungarumlaut ntilde -20
+KPX Uhungarumlaut AE -70
+KPX Uhungarumlaut Aring -80
+KPX Uhungarumlaut Adieresis -80
+KPX Uhungarumlaut r -40
+KPX Uhungarumlaut p -35
+KPX Uhungarumlaut n -35
+KPX Uhungarumlaut m -40
+KPX Uhungarumlaut A -80
+KPX Uhungarumlaut period -50
+KPX Uhungarumlaut comma -65
+KPX uhungarumlaut quoteright -20
+KPX Uogonek ae.sc -60
+KPX Uogonek aring.sc -35
+KPX Uogonek adieresis.sc -35
+KPX Uogonek atilde.sc -35
+KPX Uogonek acircumflex.sc -35
+KPX Uogonek aacute.sc -50
+KPX Uogonek agrave.sc -35
+KPX Uogonek a.sc -65
+KPX Uogonek aeacute.sc -60
+KPX Uogonek aogonek.sc -65
+KPX Uogonek amacron.sc -35
+KPX Uogonek abreve.sc -35
+KPX Uogonek ahookabove.sc -35
+KPX Uogonek acircumflexdotbelow.sc -35
+KPX Uogonek abrevedotbelow.sc -35
+KPX Uogonek rdotaccent -20
+KPX Uogonek AEacute -70
+KPX Uogonek rcaron -20
+KPX Uogonek rcommaaccent -40
+KPX Uogonek racute -30
+KPX Uogonek ncaron -20
+KPX Uogonek ncommaaccent -35
+KPX Uogonek nacute -25
+KPX Uogonek Aogonek -80
+KPX Uogonek Amacron -80
+KPX Uogonek ntilde -20
+KPX Uogonek AE -70
+KPX Uogonek Aring -80
+KPX Uogonek Adieresis -80
+KPX Uogonek r -40
+KPX Uogonek p -35
+KPX Uogonek n -35
+KPX Uogonek m -40
+KPX Uogonek A -80
+KPX Uogonek period -50
+KPX Uogonek comma -65
+KPX uogonek quoteright -20
+KPX Wcircumflex oslash.sc -45
+KPX Wcircumflex odieresis.sc -25
+KPX Wcircumflex otilde.sc -25
+KPX Wcircumflex ocircumflex.sc -25
+KPX Wcircumflex oacute.sc -35
+KPX Wcircumflex ograve.sc -25
+KPX Wcircumflex ccedilla.sc -45
+KPX Wcircumflex ae.sc -80
+KPX Wcircumflex aring.sc -50
+KPX Wcircumflex adieresis.sc -50
+KPX Wcircumflex atilde.sc -50
+KPX Wcircumflex acircumflex.sc -50
+KPX Wcircumflex aacute.sc -70
+KPX Wcircumflex agrave.sc -50
+KPX Wcircumflex s.sc -30
+KPX Wcircumflex o.sc -45
+KPX Wcircumflex g.sc -45
+KPX Wcircumflex c.sc -45
+KPX Wcircumflex a.sc -95
+KPX Wcircumflex uni0219.sc -30
+KPX Wcircumflex scircumflex.sc -15
+KPX Wcircumflex scedilla.sc -30
+KPX Wcircumflex sacute.sc -20
+KPX Wcircumflex omacron.sc -25
+KPX Wcircumflex ohungarumlaut.sc -25
+KPX Wcircumflex obreve.sc -25
+KPX Wcircumflex gdotaccent.sc -25
+KPX Wcircumflex gcommaaccent.sc -45
+KPX Wcircumflex gcircumflex.sc -25
+KPX Wcircumflex gbreve.sc -25
+KPX Wcircumflex cdotaccent.sc -25
+KPX Wcircumflex ccircumflex.sc -25
+KPX Wcircumflex ccaron.sc -25
+KPX Wcircumflex cacute.sc -35
+KPX Wcircumflex aeacute.sc -80
+KPX Wcircumflex aogonek.sc -95
+KPX Wcircumflex amacron.sc -50
+KPX Wcircumflex abreve.sc -50
+KPX Wcircumflex scaron.sc -15
+KPX Wcircumflex oogonek.sc -45
+KPX Wcircumflex ohorntilde.sc -25
+KPX Wcircumflex ohornhookabove.sc -25
+KPX Wcircumflex ohorngrave.sc -25
+KPX Wcircumflex ohorndotbelow.sc -25
+KPX Wcircumflex ohornacute.sc -25
+KPX Wcircumflex ohookabove.sc -25
+KPX Wcircumflex oe.sc -40
+KPX Wcircumflex ocircumflexdotbelow.sc -25
+KPX Wcircumflex gcaron.sc -25
+KPX Wcircumflex gacute.sc -35
+KPX Wcircumflex ahookabove.sc -50
+KPX Wcircumflex acircumflexdotbelow.sc -50
+KPX Wcircumflex abrevedotbelow.sc -50
+KPX Wcircumflex guilsinglleft -100
+KPX Wcircumflex ytilde -25
+KPX Wcircumflex yhookabove -25
+KPX Wcircumflex ygrave -25
+KPX Wcircumflex uhorndotbelow -25
+KPX Wcircumflex uhorntilde -25
+KPX Wcircumflex uhornhookabove -25
+KPX Wcircumflex uhorngrave -25
+KPX Wcircumflex uhornacute -25
+KPX Wcircumflex uhookabove -25
+KPX Wcircumflex ohorndotbelow -35
+KPX Wcircumflex ohorntilde -35
+KPX Wcircumflex ohornhookabove -35
+KPX Wcircumflex ohorngrave -35
+KPX Wcircumflex ohornacute -35
+KPX Wcircumflex ocircumflexdotbelow -35
+KPX Wcircumflex ohookabove -35
+KPX Wcircumflex ecircumflexdotbelow -35
+KPX Wcircumflex etilde -35
+KPX Wcircumflex ehookabove -35
+KPX Wcircumflex abrevedotbelow -40
+KPX Wcircumflex acircumflexdotbelow -40
+KPX Wcircumflex ahookabove -40
+KPX Wcircumflex rdotaccent -30
+KPX Wcircumflex uni0218 -35
+KPX Wcircumflex aeacute -75
+KPX Wcircumflex AEacute -115
+KPX Wcircumflex gacute -60
+KPX Wcircumflex Gacute -55
+KPX Wcircumflex oogonek -70
+KPX Wcircumflex Oogonek -55
+KPX Wcircumflex gcaron -40
+KPX Wcircumflex Gcaron -55
+KPX Wcircumflex ycircumflex -25
+KPX Wcircumflex uogonek -50
+KPX Wcircumflex uhungarumlaut -25
+KPX Wcircumflex uring -25
+KPX Wcircumflex ubreve -25
+KPX Wcircumflex umacron -25
+KPX Wcircumflex utilde -25
+KPX Wcircumflex Scaron -35
+KPX Wcircumflex Scedilla -35
+KPX Wcircumflex Scircumflex -35
+KPX Wcircumflex Sacute -35
+KPX Wcircumflex rcaron -30
+KPX Wcircumflex rcommaaccent -55
+KPX Wcircumflex racute -40
+KPX Wcircumflex oe -70
+KPX Wcircumflex OE -55
+KPX Wcircumflex ohungarumlaut -35
+KPX Wcircumflex Ohungarumlaut -55
+KPX Wcircumflex obreve -35
+KPX Wcircumflex Obreve -55
+KPX Wcircumflex omacron -35
+KPX Wcircumflex Omacron -55
+KPX Wcircumflex iogonek -25
+KPX Wcircumflex gcommaaccent -80
+KPX Wcircumflex Gcommaaccent -55
+KPX Wcircumflex gdotaccent -40
+KPX Wcircumflex Gdotaccent -55
+KPX Wcircumflex gbreve -40
+KPX Wcircumflex Gbreve -55
+KPX Wcircumflex gcircumflex -40
+KPX Wcircumflex Gcircumflex -55
+KPX Wcircumflex ecaron -35
+KPX Wcircumflex eogonek -65
+KPX Wcircumflex edotaccent -35
+KPX Wcircumflex ebreve -35
+KPX Wcircumflex emacron -35
+KPX Wcircumflex Ccaron -55
+KPX Wcircumflex Cdotaccent -55
+KPX Wcircumflex Ccircumflex -55
+KPX Wcircumflex Cacute -55
+KPX Wcircumflex aogonek -75
+KPX Wcircumflex Aogonek -115
+KPX Wcircumflex abreve -40
+KPX Wcircumflex amacron -40
+KPX Wcircumflex Amacron -115
+KPX Wcircumflex ydieresis -25
+KPX Wcircumflex yacute -35
+KPX Wcircumflex udieresis -25
+KPX Wcircumflex ucircumflex -25
+KPX Wcircumflex uacute -40
+KPX Wcircumflex ugrave -25
+KPX Wcircumflex oslash -70
+KPX Wcircumflex odieresis -35
+KPX Wcircumflex otilde -35
+KPX Wcircumflex ocircumflex -35
+KPX Wcircumflex oacute -55
+KPX Wcircumflex ograve -35
+KPX Wcircumflex iacute -10
+KPX Wcircumflex edieresis -35
+KPX Wcircumflex ecircumflex -35
+KPX Wcircumflex eacute -50
+KPX Wcircumflex egrave -35
+KPX Wcircumflex ae -75
+KPX Wcircumflex aring -40
+KPX Wcircumflex adieresis -40
+KPX Wcircumflex atilde -40
+KPX Wcircumflex acircumflex -40
+KPX Wcircumflex aacute -55
+KPX Wcircumflex agrave -40
+KPX Wcircumflex Oslash -55
+KPX Wcircumflex Odieresis -55
+KPX Wcircumflex Ccedilla -55
+KPX Wcircumflex AE -115
+KPX Wcircumflex Aring -115
+KPX Wcircumflex Adieresis -115
+KPX Wcircumflex guillemotleft -95
+KPX Wcircumflex y -45
+KPX Wcircumflex u -50
+KPX Wcircumflex r -55
+KPX Wcircumflex o -70
+KPX Wcircumflex i -25
+KPX Wcircumflex g -80
+KPX Wcircumflex e -65
+KPX Wcircumflex a -75
+KPX Wcircumflex S -35
+KPX Wcircumflex O -55
+KPX Wcircumflex G -55
+KPX Wcircumflex C -55
+KPX Wcircumflex A -115
+KPX Wcircumflex semicolon -95
+KPX Wcircumflex colon -80
+KPX Wcircumflex period -90
+KPX Wcircumflex hyphen -45
+KPX Wcircumflex comma -105
+KPX wcircumflex uni0219 -15
+KPX wcircumflex aeacute -30
+KPX wcircumflex gacute -40
+KPX wcircumflex oogonek -40
+KPX wcircumflex gcaron -40
+KPX wcircumflex scaron -15
+KPX wcircumflex scedilla -15
+KPX wcircumflex scircumflex -15
+KPX wcircumflex sacute -15
+KPX wcircumflex oe -40
+KPX wcircumflex ohungarumlaut -40
+KPX wcircumflex obreve -40
+KPX wcircumflex omacron -40
+KPX wcircumflex lslash -35
+KPX wcircumflex lcaron -35
+KPX wcircumflex lcommaaccent -35
+KPX wcircumflex lacute -35
+KPX wcircumflex gcommaaccent -40
+KPX wcircumflex gdotaccent -40
+KPX wcircumflex gbreve -40
+KPX wcircumflex gcircumflex -40
+KPX wcircumflex ecaron -40
+KPX wcircumflex eogonek -40
+KPX wcircumflex edotaccent -40
+KPX wcircumflex ebreve -40
+KPX wcircumflex emacron -40
+KPX wcircumflex ccaron -50
+KPX wcircumflex cdotaccent -50
+KPX wcircumflex ccircumflex -50
+KPX wcircumflex cacute -50
+KPX wcircumflex aogonek -30
+KPX wcircumflex amacron -30
+KPX wcircumflex oslash -40
+KPX wcircumflex odieresis -40
+KPX wcircumflex edieresis -40
+KPX wcircumflex ccedilla -50
+KPX wcircumflex ae -30
+KPX wcircumflex aring -30
+KPX wcircumflex adieresis -30
+KPX wcircumflex s -15
+KPX wcircumflex o -40
+KPX wcircumflex l -35
+KPX wcircumflex g -40
+KPX wcircumflex e -40
+KPX wcircumflex c -50
+KPX wcircumflex a -30
+KPX wcircumflex semicolon -35
+KPX wcircumflex colon -20
+KPX wcircumflex period -90
+KPX wcircumflex hyphen -30
+KPX wcircumflex comma -105
+KPX Ycircumflex zdotaccent -67
+KPX Ycircumflex zcaron -67
+KPX Ycircumflex zacute -67
+KPX Ycircumflex z -67
+KPX Ycircumflex scircumflex -67
+KPX Ycircumflex scedilla -67
+KPX Ycircumflex scaron -67
+KPX Ycircumflex sacute -67
+KPX Ycircumflex s -67
+KPX Ycircumflex cdotaccent -67
+KPX Ycircumflex ccircumflex -67
+KPX Ycircumflex ccedilla -67
+KPX Ycircumflex ccaron -67
+KPX Ycircumflex cacute -67
+KPX Ycircumflex c -67
+KPX Ycircumflex oslash.sc -60
+KPX Ycircumflex odieresis.sc -30
+KPX Ycircumflex otilde.sc -30
+KPX Ycircumflex ocircumflex.sc -30
+KPX Ycircumflex oacute.sc -45
+KPX Ycircumflex ograve.sc -30
+KPX Ycircumflex ccedilla.sc -60
+KPX Ycircumflex ae.sc -80
+KPX Ycircumflex aring.sc -30
+KPX Ycircumflex adieresis.sc -30
+KPX Ycircumflex atilde.sc -30
+KPX Ycircumflex acircumflex.sc -30
+KPX Ycircumflex aacute.sc -45
+KPX Ycircumflex agrave.sc -30
+KPX Ycircumflex s.sc -30
+KPX Ycircumflex o.sc -60
+KPX Ycircumflex g.sc -60
+KPX Ycircumflex c.sc -60
+KPX Ycircumflex a.sc -60
+KPX Ycircumflex uni0219.sc -30
+KPX Ycircumflex scircumflex.sc -15
+KPX Ycircumflex scedilla.sc -30
+KPX Ycircumflex sacute.sc -20
+KPX Ycircumflex omacron.sc -30
+KPX Ycircumflex ohungarumlaut.sc -30
+KPX Ycircumflex obreve.sc -30
+KPX Ycircumflex gdotaccent.sc -30
+KPX Ycircumflex gcommaaccent.sc -60
+KPX Ycircumflex gcircumflex.sc -30
+KPX Ycircumflex gbreve.sc -30
+KPX Ycircumflex cdotaccent.sc -30
+KPX Ycircumflex ccircumflex.sc -30
+KPX Ycircumflex ccaron.sc -30
+KPX Ycircumflex cacute.sc -45
+KPX Ycircumflex aeacute.sc -80
+KPX Ycircumflex aogonek.sc -60
+KPX Ycircumflex amacron.sc -30
+KPX Ycircumflex abreve.sc -30
+KPX Ycircumflex scaron.sc -15
+KPX Ycircumflex oogonek.sc -60
+KPX Ycircumflex ohorntilde.sc -30
+KPX Ycircumflex ohornhookabove.sc -30
+KPX Ycircumflex ohorngrave.sc -30
+KPX Ycircumflex ohorndotbelow.sc -30
+KPX Ycircumflex ohornacute.sc -30
+KPX Ycircumflex ohookabove.sc -30
+KPX Ycircumflex oe.sc -40
+KPX Ycircumflex ocircumflexdotbelow.sc -30
+KPX Ycircumflex gcaron.sc -30
+KPX Ycircumflex gacute.sc -45
+KPX Ycircumflex ahookabove.sc -30
+KPX Ycircumflex acircumflexdotbelow.sc -30
+KPX Ycircumflex abrevedotbelow.sc -30
+KPX Ycircumflex guilsinglleft -135
+KPX Ycircumflex uhorndotbelow -40
+KPX Ycircumflex uhorntilde -40
+KPX Ycircumflex uhornhookabove -40
+KPX Ycircumflex uhorngrave -40
+KPX Ycircumflex uhornacute -40
+KPX Ycircumflex uhookabove -40
+KPX Ycircumflex ohorndotbelow -50
+KPX Ycircumflex ohorntilde -50
+KPX Ycircumflex ohornhookabove -50
+KPX Ycircumflex ohorngrave -50
+KPX Ycircumflex ohornacute -50
+KPX Ycircumflex ocircumflexdotbelow -50
+KPX Ycircumflex ohookabove -50
+KPX Ycircumflex ecircumflexdotbelow -45
+KPX Ycircumflex etilde -45
+KPX Ycircumflex ehookabove -45
+KPX Ycircumflex abrevedotbelow -45
+KPX Ycircumflex acircumflexdotbelow -45
+KPX Ycircumflex ahookabove -45
+KPX Ycircumflex uni0218 -35
+KPX Ycircumflex aeacute -75
+KPX Ycircumflex AEacute -115
+KPX Ycircumflex gacute -75
+KPX Ycircumflex Gacute -70
+KPX Ycircumflex oogonek -95
+KPX Ycircumflex Oogonek -70
+KPX Ycircumflex gcaron -50
+KPX Ycircumflex Gcaron -70
+KPX Ycircumflex uogonek -80
+KPX Ycircumflex uhungarumlaut -40
+KPX Ycircumflex uring -40
+KPX Ycircumflex ubreve -40
+KPX Ycircumflex umacron -40
+KPX Ycircumflex utilde -40
+KPX Ycircumflex Scaron -35
+KPX Ycircumflex Scedilla -35
+KPX Ycircumflex Scircumflex -35
+KPX Ycircumflex Sacute -35
+KPX Ycircumflex oe -70
+KPX Ycircumflex OE -55
+KPX Ycircumflex ohungarumlaut -50
+KPX Ycircumflex Ohungarumlaut -70
+KPX Ycircumflex obreve -50
+KPX Ycircumflex Obreve -70
+KPX Ycircumflex omacron -50
+KPX Ycircumflex Omacron -70
+KPX Ycircumflex iogonek -25
+KPX Ycircumflex gcommaaccent -100
+KPX Ycircumflex Gcommaaccent -70
+KPX Ycircumflex gdotaccent -50
+KPX Ycircumflex Gdotaccent -70
+KPX Ycircumflex gbreve -50
+KPX Ycircumflex Gbreve -70
+KPX Ycircumflex gcircumflex -50
+KPX Ycircumflex Gcircumflex -70
+KPX Ycircumflex ecaron -45
+KPX Ycircumflex eogonek -90
+KPX Ycircumflex edotaccent -45
+KPX Ycircumflex ebreve -45
+KPX Ycircumflex emacron -45
+KPX Ycircumflex Ccaron -70
+KPX Ycircumflex Cdotaccent -70
+KPX Ycircumflex Ccircumflex -70
+KPX Ycircumflex Cacute -70
+KPX Ycircumflex aogonek -85
+KPX Ycircumflex Aogonek -70
+KPX Ycircumflex abreve -45
+KPX Ycircumflex amacron -45
+KPX Ycircumflex Amacron -70
+KPX Ycircumflex udieresis -40
+KPX Ycircumflex ucircumflex -40
+KPX Ycircumflex uacute -60
+KPX Ycircumflex ugrave -40
+KPX Ycircumflex oslash -95
+KPX Ycircumflex odieresis -50
+KPX Ycircumflex otilde -50
+KPX Ycircumflex ocircumflex -50
+KPX Ycircumflex oacute -70
+KPX Ycircumflex ograve -50
+KPX Ycircumflex iacute -10
+KPX Ycircumflex edieresis -45
+KPX Ycircumflex ecircumflex -45
+KPX Ycircumflex eacute -70
+KPX Ycircumflex egrave -45
+KPX Ycircumflex ae -75
+KPX Ycircumflex aring -45
+KPX Ycircumflex adieresis -45
+KPX Ycircumflex atilde -45
+KPX Ycircumflex acircumflex -45
+KPX Ycircumflex aacute -65
+KPX Ycircumflex agrave -45
+KPX Ycircumflex Oslash -70
+KPX Ycircumflex Odieresis -70
+KPX Ycircumflex Ccedilla -70
+KPX Ycircumflex AE -115
+KPX Ycircumflex Aring -70
+KPX Ycircumflex Adieresis -70
+KPX Ycircumflex guillemotleft -125
+KPX Ycircumflex v -70
+KPX Ycircumflex u -80
+KPX Ycircumflex p -75
+KPX Ycircumflex o -95
+KPX Ycircumflex i -25
+KPX Ycircumflex g -100
+KPX Ycircumflex e -90
+KPX Ycircumflex a -85
+KPX Ycircumflex S -35
+KPX Ycircumflex O -70
+KPX Ycircumflex G -70
+KPX Ycircumflex C -70
+KPX Ycircumflex A -70
+KPX Ycircumflex semicolon -110
+KPX Ycircumflex colon -100
+KPX Ycircumflex period -100
+KPX Ycircumflex hyphen -80
+KPX Ycircumflex comma -110
+KPX ycircumflex aeacute -30
+KPX ycircumflex gacute -35
+KPX ycircumflex oogonek -35
+KPX ycircumflex gcaron -35
+KPX ycircumflex oe -40
+KPX ycircumflex ohungarumlaut -35
+KPX ycircumflex obreve -35
+KPX ycircumflex omacron -35
+KPX ycircumflex lslash -25
+KPX ycircumflex lcaron -25
+KPX ycircumflex lcommaaccent -25
+KPX ycircumflex lacute -25
+KPX ycircumflex gcommaaccent -35
+KPX ycircumflex gdotaccent -35
+KPX ycircumflex gbreve -35
+KPX ycircumflex gcircumflex -35
+KPX ycircumflex ecaron -35
+KPX ycircumflex eogonek -35
+KPX ycircumflex edotaccent -35
+KPX ycircumflex ebreve -35
+KPX ycircumflex emacron -35
+KPX ycircumflex ccaron -45
+KPX ycircumflex cdotaccent -45
+KPX ycircumflex ccircumflex -45
+KPX ycircumflex cacute -45
+KPX ycircumflex aogonek -25
+KPX ycircumflex amacron -25
+KPX ycircumflex oslash -35
+KPX ycircumflex odieresis -35
+KPX ycircumflex edieresis -35
+KPX ycircumflex ccedilla -45
+KPX ycircumflex ae -30
+KPX ycircumflex aring -25
+KPX ycircumflex adieresis -25
+KPX ycircumflex o -35
+KPX ycircumflex l -25
+KPX ycircumflex g -35
+KPX ycircumflex e -35
+KPX ycircumflex c -45
+KPX ycircumflex a -25
+KPX ycircumflex semicolon -30
+KPX ycircumflex colon -15
+KPX ycircumflex period -90
+KPX ycircumflex hyphen -25
+KPX ycircumflex comma -105
+KPX Ydieresis zdotaccent -67
+KPX Ydieresis zcaron -67
+KPX Ydieresis zacute -67
+KPX Ydieresis z -67
+KPX Ydieresis scircumflex -67
+KPX Ydieresis scedilla -67
+KPX Ydieresis scaron -67
+KPX Ydieresis sacute -67
+KPX Ydieresis s -67
+KPX Ydieresis cdotaccent -67
+KPX Ydieresis ccircumflex -67
+KPX Ydieresis ccedilla -67
+KPX Ydieresis ccaron -67
+KPX Ydieresis cacute -67
+KPX Ydieresis c -67
+KPX Ydieresis oslash.sc -60
+KPX Ydieresis odieresis.sc -30
+KPX Ydieresis otilde.sc -30
+KPX Ydieresis ocircumflex.sc -30
+KPX Ydieresis oacute.sc -45
+KPX Ydieresis ograve.sc -30
+KPX Ydieresis ccedilla.sc -60
+KPX Ydieresis ae.sc -80
+KPX Ydieresis aring.sc -30
+KPX Ydieresis adieresis.sc -30
+KPX Ydieresis atilde.sc -30
+KPX Ydieresis acircumflex.sc -30
+KPX Ydieresis aacute.sc -45
+KPX Ydieresis agrave.sc -30
+KPX Ydieresis s.sc -30
+KPX Ydieresis o.sc -60
+KPX Ydieresis g.sc -60
+KPX Ydieresis c.sc -60
+KPX Ydieresis a.sc -60
+KPX Ydieresis uni0219.sc -30
+KPX Ydieresis scircumflex.sc -15
+KPX Ydieresis scedilla.sc -30
+KPX Ydieresis sacute.sc -20
+KPX Ydieresis omacron.sc -30
+KPX Ydieresis ohungarumlaut.sc -30
+KPX Ydieresis obreve.sc -30
+KPX Ydieresis gdotaccent.sc -30
+KPX Ydieresis gcommaaccent.sc -60
+KPX Ydieresis gcircumflex.sc -30
+KPX Ydieresis gbreve.sc -30
+KPX Ydieresis cdotaccent.sc -30
+KPX Ydieresis ccircumflex.sc -30
+KPX Ydieresis ccaron.sc -30
+KPX Ydieresis cacute.sc -45
+KPX Ydieresis aeacute.sc -80
+KPX Ydieresis aogonek.sc -60
+KPX Ydieresis amacron.sc -30
+KPX Ydieresis abreve.sc -30
+KPX Ydieresis scaron.sc -15
+KPX Ydieresis oogonek.sc -60
+KPX Ydieresis ohorntilde.sc -30
+KPX Ydieresis ohornhookabove.sc -30
+KPX Ydieresis ohorngrave.sc -30
+KPX Ydieresis ohorndotbelow.sc -30
+KPX Ydieresis ohornacute.sc -30
+KPX Ydieresis ohookabove.sc -30
+KPX Ydieresis oe.sc -40
+KPX Ydieresis ocircumflexdotbelow.sc -30
+KPX Ydieresis gcaron.sc -30
+KPX Ydieresis gacute.sc -45
+KPX Ydieresis ahookabove.sc -30
+KPX Ydieresis acircumflexdotbelow.sc -30
+KPX Ydieresis abrevedotbelow.sc -30
+KPX Ydieresis guilsinglleft -135
+KPX Ydieresis uhorndotbelow -40
+KPX Ydieresis uhorntilde -40
+KPX Ydieresis uhornhookabove -40
+KPX Ydieresis uhorngrave -40
+KPX Ydieresis uhornacute -40
+KPX Ydieresis uhookabove -40
+KPX Ydieresis ohorndotbelow -50
+KPX Ydieresis ohorntilde -50
+KPX Ydieresis ohornhookabove -50
+KPX Ydieresis ohorngrave -50
+KPX Ydieresis ohornacute -50
+KPX Ydieresis ocircumflexdotbelow -50
+KPX Ydieresis ohookabove -50
+KPX Ydieresis ecircumflexdotbelow -45
+KPX Ydieresis etilde -45
+KPX Ydieresis ehookabove -45
+KPX Ydieresis abrevedotbelow -45
+KPX Ydieresis acircumflexdotbelow -45
+KPX Ydieresis ahookabove -45
+KPX Ydieresis uni0218 -35
+KPX Ydieresis aeacute -75
+KPX Ydieresis AEacute -115
+KPX Ydieresis gacute -75
+KPX Ydieresis Gacute -70
+KPX Ydieresis oogonek -95
+KPX Ydieresis Oogonek -70
+KPX Ydieresis gcaron -50
+KPX Ydieresis Gcaron -70
+KPX Ydieresis uogonek -80
+KPX Ydieresis uhungarumlaut -40
+KPX Ydieresis uring -40
+KPX Ydieresis ubreve -40
+KPX Ydieresis umacron -40
+KPX Ydieresis utilde -40
+KPX Ydieresis Scaron -35
+KPX Ydieresis Scedilla -35
+KPX Ydieresis Scircumflex -35
+KPX Ydieresis Sacute -35
+KPX Ydieresis oe -70
+KPX Ydieresis OE -55
+KPX Ydieresis ohungarumlaut -50
+KPX Ydieresis Ohungarumlaut -70
+KPX Ydieresis obreve -50
+KPX Ydieresis Obreve -70
+KPX Ydieresis omacron -50
+KPX Ydieresis Omacron -70
+KPX Ydieresis iogonek -25
+KPX Ydieresis gcommaaccent -100
+KPX Ydieresis Gcommaaccent -70
+KPX Ydieresis gdotaccent -50
+KPX Ydieresis Gdotaccent -70
+KPX Ydieresis gbreve -50
+KPX Ydieresis Gbreve -70
+KPX Ydieresis gcircumflex -50
+KPX Ydieresis Gcircumflex -70
+KPX Ydieresis ecaron -45
+KPX Ydieresis eogonek -90
+KPX Ydieresis edotaccent -45
+KPX Ydieresis ebreve -45
+KPX Ydieresis emacron -45
+KPX Ydieresis Ccaron -70
+KPX Ydieresis Cdotaccent -70
+KPX Ydieresis Ccircumflex -70
+KPX Ydieresis Cacute -70
+KPX Ydieresis aogonek -85
+KPX Ydieresis Aogonek -70
+KPX Ydieresis abreve -45
+KPX Ydieresis amacron -45
+KPX Ydieresis Amacron -70
+KPX Ydieresis udieresis -40
+KPX Ydieresis ucircumflex -40
+KPX Ydieresis uacute -60
+KPX Ydieresis ugrave -40
+KPX Ydieresis oslash -95
+KPX Ydieresis odieresis -50
+KPX Ydieresis otilde -50
+KPX Ydieresis ocircumflex -50
+KPX Ydieresis oacute -70
+KPX Ydieresis ograve -50
+KPX Ydieresis iacute -10
+KPX Ydieresis edieresis -45
+KPX Ydieresis ecircumflex -45
+KPX Ydieresis eacute -70
+KPX Ydieresis egrave -45
+KPX Ydieresis ae -75
+KPX Ydieresis aring -45
+KPX Ydieresis adieresis -45
+KPX Ydieresis atilde -45
+KPX Ydieresis acircumflex -45
+KPX Ydieresis aacute -65
+KPX Ydieresis agrave -45
+KPX Ydieresis Oslash -70
+KPX Ydieresis Odieresis -70
+KPX Ydieresis Ccedilla -70
+KPX Ydieresis AE -115
+KPX Ydieresis Aring -70
+KPX Ydieresis Adieresis -70
+KPX Ydieresis guillemotleft -125
+KPX Ydieresis v -70
+KPX Ydieresis u -80
+KPX Ydieresis p -75
+KPX Ydieresis o -95
+KPX Ydieresis i -25
+KPX Ydieresis g -100
+KPX Ydieresis e -90
+KPX Ydieresis a -85
+KPX Ydieresis S -35
+KPX Ydieresis O -70
+KPX Ydieresis G -70
+KPX Ydieresis C -70
+KPX Ydieresis A -70
+KPX Ydieresis semicolon -110
+KPX Ydieresis colon -100
+KPX Ydieresis period -100
+KPX Ydieresis hyphen -80
+KPX Ydieresis comma -110
+KPX Zacute ycircumflex -60
+KPX Zacute ydieresis -60
+KPX Zacute y -60
+KPX Zacute v -60
+KPX Zdotaccent ycircumflex -60
+KPX Zdotaccent ydieresis -60
+KPX Zdotaccent y -60
+KPX Zdotaccent v -60
+KPX Zcaron ycircumflex -60
+KPX Zcaron ydieresis -60
+KPX Zcaron y -60
+KPX Zcaron v -60
+KPX Uhorn a.sc -65
+KPX Uhorn n -35
+KPX Uhorn A -80
+KPX Gcaron ydieresis.sc -15
+KPX Gcaron aring.sc -20
+KPX Gcaron adieresis.sc -20
+KPX Gcaron y.sc -15
+KPX Gcaron w.sc -10
+KPX Gcaron v.sc -10
+KPX Gcaron t.sc -20
+KPX Gcaron a.sc -20
+KPX Gcaron ycircumflex.sc -15
+KPX Gcaron wgrave.sc -10
+KPX Gcaron wdieresis.sc -10
+KPX Gcaron wcircumflex.sc -10
+KPX Gcaron wacute.sc -10
+KPX Gcaron uni021B.sc -20
+KPX Gcaron tcaron.sc -20
+KPX Gcaron aogonek.sc -20
+KPX Gcaron amacron.sc -20
+KPX Gcaron Wdieresis -15
+KPX Gcaron Wacute -15
+KPX Gcaron Wgrave -15
+KPX Gcaron uni021A -25
+KPX Gcaron Ydieresis -20
+KPX Gcaron Ycircumflex -20
+KPX Gcaron Wcircumflex -15
+KPX Gcaron Tcaron -25
+KPX Gcaron Aogonek -25
+KPX Gcaron Amacron -25
+KPX Gcaron Aring -25
+KPX Gcaron Adieresis -25
+KPX Gcaron Y -20
+KPX Gcaron W -15
+KPX Gcaron V -15
+KPX Gcaron T -25
+KPX Gcaron A -25
+KPX Gcaron T_h -25
+KPX gcaron rdotaccent 15
+KPX gcaron aeacute -15
+KPX gcaron rcaron 15
+KPX gcaron rcommaaccent 15
+KPX gcaron racute 15
+KPX gcaron ecaron -20
+KPX gcaron eogonek -20
+KPX gcaron edotaccent -20
+KPX gcaron ebreve -20
+KPX gcaron emacron -20
+KPX gcaron aogonek -15
+KPX gcaron amacron -15
+KPX gcaron edieresis -20
+KPX gcaron ae -15
+KPX gcaron aring -15
+KPX gcaron adieresis -15
+KPX gcaron r 15
+KPX gcaron e -20
+KPX gcaron a -15
+KPX Oogonek ydieresis.sc -45
+KPX Oogonek ae.sc -55
+KPX Oogonek aring.sc -60
+KPX Oogonek adieresis.sc -60
+KPX Oogonek y.sc -45
+KPX Oogonek x.sc -50
+KPX Oogonek w.sc -35
+KPX Oogonek v.sc -45
+KPX Oogonek t.sc -10
+KPX Oogonek a.sc -60
+KPX Oogonek ycircumflex.sc -45
+KPX Oogonek wgrave.sc -35
+KPX Oogonek wdieresis.sc -35
+KPX Oogonek wcircumflex.sc -35
+KPX Oogonek wacute.sc -35
+KPX Oogonek uni021B.sc -10
+KPX Oogonek tcaron.sc -10
+KPX Oogonek aeacute.sc -55
+KPX Oogonek aogonek.sc -60
+KPX Oogonek amacron.sc -60
+KPX Oogonek Wdieresis -45
+KPX Oogonek Wacute -45
+KPX Oogonek Wgrave -45
+KPX Oogonek uni021A -15
+KPX Oogonek AEacute -65
+KPX Oogonek Ydieresis -55
+KPX Oogonek Ycircumflex -55
+KPX Oogonek Wcircumflex -45
+KPX Oogonek Tcaron -15
+KPX Oogonek Aogonek -75
+KPX Oogonek Amacron -75
+KPX Oogonek AE -65
+KPX Oogonek Aring -75
+KPX Oogonek Adieresis -75
+KPX Oogonek Y -55
+KPX Oogonek X -60
+KPX Oogonek W -45
+KPX Oogonek V -55
+KPX Oogonek T -15
+KPX Oogonek A -75
+KPX Oogonek T_h -15
+KPX oogonek quoteright -20
+KPX oogonek wdieresis -25
+KPX oogonek wacute -25
+KPX oogonek wgrave -25
+KPX oogonek uni021B -15
+KPX oogonek uni021A -100
+KPX oogonek wcircumflex -25
+KPX oogonek tcaron -15
+KPX oogonek Tcaron -100
+KPX oogonek x -30
+KPX oogonek w -25
+KPX oogonek v -25
+KPX oogonek t -15
+KPX oogonek T -100
+KPX oogonek T_h -100
+KPX Gacute ydieresis.sc -15
+KPX Gacute aring.sc -20
+KPX Gacute adieresis.sc -20
+KPX Gacute y.sc -15
+KPX Gacute w.sc -10
+KPX Gacute v.sc -10
+KPX Gacute t.sc -20
+KPX Gacute a.sc -20
+KPX Gacute ycircumflex.sc -15
+KPX Gacute wgrave.sc -10
+KPX Gacute wdieresis.sc -10
+KPX Gacute wcircumflex.sc -10
+KPX Gacute wacute.sc -10
+KPX Gacute uni021B.sc -20
+KPX Gacute tcaron.sc -20
+KPX Gacute aogonek.sc -20
+KPX Gacute amacron.sc -20
+KPX Gacute Wdieresis -15
+KPX Gacute Wacute -15
+KPX Gacute Wgrave -15
+KPX Gacute uni021A -25
+KPX Gacute Ydieresis -20
+KPX Gacute Ycircumflex -20
+KPX Gacute Wcircumflex -15
+KPX Gacute Tcaron -25
+KPX Gacute Aogonek -25
+KPX Gacute Amacron -25
+KPX Gacute Aring -25
+KPX Gacute Adieresis -25
+KPX Gacute Y -20
+KPX Gacute W -15
+KPX Gacute V -15
+KPX Gacute T -25
+KPX Gacute A -25
+KPX Gacute T_h -25
+KPX gacute rdotaccent 15
+KPX gacute aeacute -15
+KPX gacute rcaron 15
+KPX gacute rcommaaccent 15
+KPX gacute racute 15
+KPX gacute ecaron -20
+KPX gacute eogonek -20
+KPX gacute edotaccent -20
+KPX gacute ebreve -20
+KPX gacute emacron -20
+KPX gacute aogonek -15
+KPX gacute amacron -15
+KPX gacute edieresis -20
+KPX gacute ae -15
+KPX gacute aring -15
+KPX gacute adieresis -15
+KPX gacute r 15
+KPX gacute e -20
+KPX gacute a -15
+KPX aeacute ycircumflex -15
+KPX aeacute ydieresis -15
+KPX aeacute y -15
+KPX uni0218 ydieresis.sc -10
+KPX uni0218 ae.sc -25
+KPX uni0218 aring.sc -35
+KPX uni0218 adieresis.sc -35
+KPX uni0218 y.sc -10
+KPX uni0218 w.sc -10
+KPX uni0218 v.sc -10
+KPX uni0218 t.sc -15
+KPX uni0218 a.sc -35
+KPX uni0218 ycircumflex.sc -10
+KPX uni0218 wgrave.sc -10
+KPX uni0218 wdieresis.sc -10
+KPX uni0218 wcircumflex.sc -10
+KPX uni0218 wacute.sc -10
+KPX uni0218 uni021B.sc -15
+KPX uni0218 tcaron.sc -15
+KPX uni0218 aeacute.sc -25
+KPX uni0218 aogonek.sc -35
+KPX uni0218 amacron.sc -35
+KPX uni0218 Wdieresis -15
+KPX uni0218 Wacute -15
+KPX uni0218 Wgrave -15
+KPX uni0218 uni021B -20
+KPX uni0218 uni021A -20
+KPX uni0218 AEacute -30
+KPX uni0218 Ydieresis -15
+KPX uni0218 Ycircumflex -15
+KPX uni0218 Wcircumflex -15
+KPX uni0218 tcaron -20
+KPX uni0218 Tcaron -20
+KPX uni0218 Aogonek -40
+KPX uni0218 Amacron -40
+KPX uni0218 AE -30
+KPX uni0218 Aring -40
+KPX uni0218 Adieresis -40
+KPX uni0218 t -20
+KPX uni0218 Y -15
+KPX uni0218 W -15
+KPX uni0218 V -15
+KPX uni0218 T -20
+KPX uni0218 A -40
+KPX uni0218 T_h -20
+KPX uni0219 quoteright -15
+KPX uni0219 uni021B -15
+KPX uni0219 tcaron -15
+KPX uni0219 t -15
+KPX uni021A oslash.sc -15
+KPX uni021A odieresis.sc -10
+KPX uni021A otilde.sc -10
+KPX uni021A ocircumflex.sc -10
+KPX uni021A oacute.sc -10
+KPX uni021A ograve.sc -10
+KPX uni021A ccedilla.sc -20
+KPX uni021A ae.sc -80
+KPX uni021A aring.sc -25
+KPX uni021A adieresis.sc -25
+KPX uni021A atilde.sc -25
+KPX uni021A acircumflex.sc -25
+KPX uni021A aacute.sc -40
+KPX uni021A agrave.sc -25
+KPX uni021A o.sc -15
+KPX uni021A g.sc -20
+KPX uni021A c.sc -20
+KPX uni021A a.sc -55
+KPX uni021A omacron.sc -10
+KPX uni021A ohungarumlaut.sc -10
+KPX uni021A obreve.sc -10
+KPX uni021A gdotaccent.sc -10
+KPX uni021A gcommaaccent.sc -20
+KPX uni021A gcircumflex.sc -10
+KPX uni021A gbreve.sc -10
+KPX uni021A cdotaccent.sc -10
+KPX uni021A ccircumflex.sc -10
+KPX uni021A ccaron.sc -10
+KPX uni021A cacute.sc -15
+KPX uni021A aeacute.sc -80
+KPX uni021A aogonek.sc -55
+KPX uni021A amacron.sc -25
+KPX uni021A abreve.sc -25
+KPX uni021A jacute -10
+KPX uni021A oogonek.sc -15
+KPX uni021A ohorntilde.sc -10
+KPX uni021A ohornhookabove.sc -10
+KPX uni021A ohorngrave.sc -10
+KPX uni021A ohorndotbelow.sc -10
+KPX uni021A ohornacute.sc -10
+KPX uni021A ohookabove.sc -10
+KPX uni021A oe.sc -40
+KPX uni021A ocircumflexdotbelow.sc -10
+KPX uni021A gcaron.sc -10
+KPX uni021A gacute.sc -15
+KPX uni021A ahookabove.sc -25
+KPX uni021A acircumflexdotbelow.sc -25
+KPX uni021A abrevedotbelow.sc -25
+KPX uni021A guilsinglleft -135
+KPX uni021A ytilde -55
+KPX uni021A yhookabove -55
+KPX uni021A ygrave -55
+KPX uni021A uhorndotbelow -55
+KPX uni021A uhorntilde -55
+KPX uni021A uhornhookabove -55
+KPX uni021A uhorngrave -55
+KPX uni021A uhornacute -55
+KPX uni021A uhookabove -55
+KPX uni021A ohorndotbelow -50
+KPX uni021A ohorntilde -50
+KPX uni021A ohornhookabove -50
+KPX uni021A ohorngrave -50
+KPX uni021A ohornacute -50
+KPX uni021A ocircumflexdotbelow -50
+KPX uni021A ohookabove -50
+KPX uni021A ihookabove -15
+KPX uni021A ecircumflexdotbelow -50
+KPX uni021A etilde -50
+KPX uni021A ehookabove -50
+KPX uni021A abrevedotbelow -40
+KPX uni021A acircumflexdotbelow -40
+KPX uni021A ahookabove -40
+KPX uni021A wdieresis -55
+KPX uni021A wacute -80
+KPX uni021A wgrave -55
+KPX uni021A rdotaccent -35
+KPX uni021A uni0219 -70
+KPX uni021A aeacute -75
+KPX uni021A AEacute -115
+KPX uni021A gacute -70
+KPX uni021A Gacute -25
+KPX uni021A oogonek -100
+KPX uni021A Oogonek -20
+KPX uni021A gcaron -50
+KPX uni021A Gcaron -25
+KPX uni021A ycircumflex -55
+KPX uni021A wcircumflex -55
+KPX uni021A uogonek -110
+KPX uni021A uhungarumlaut -55
+KPX uni021A uring -55
+KPX uni021A ubreve -55
+KPX uni021A umacron -55
+KPX uni021A utilde -55
+KPX uni021A scaron -35
+KPX uni021A scedilla -70
+KPX uni021A scircumflex -35
+KPX uni021A sacute -55
+KPX uni021A rcaron -35
+KPX uni021A rcommaaccent -65
+KPX uni021A racute -50
+KPX uni021A oe -70
+KPX uni021A OE -55
+KPX uni021A ohungarumlaut -50
+KPX uni021A Ohungarumlaut -20
+KPX uni021A obreve -50
+KPX uni021A Obreve -20
+KPX uni021A omacron -50
+KPX uni021A Omacron -20
+KPX uni021A jcircumflex -5
+KPX uni021A iogonek -25
+KPX uni021A ibreve -15
+KPX uni021A imacron -15
+KPX uni021A itilde -15
+KPX uni021A gcommaaccent -95
+KPX uni021A Gcommaaccent -25
+KPX uni021A gdotaccent -50
+KPX uni021A Gdotaccent -25
+KPX uni021A gbreve -50
+KPX uni021A Gbreve -25
+KPX uni021A gcircumflex -50
+KPX uni021A Gcircumflex -25
+KPX uni021A ecaron -50
+KPX uni021A eogonek -95
+KPX uni021A edotaccent -50
+KPX uni021A ebreve -50
+KPX uni021A emacron -50
+KPX uni021A ccaron -50
+KPX uni021A Ccaron -25
+KPX uni021A cdotaccent -50
+KPX uni021A Cdotaccent -25
+KPX uni021A ccircumflex -50
+KPX uni021A Ccircumflex -25
+KPX uni021A cacute -70
+KPX uni021A Cacute -25
+KPX uni021A aogonek -80
+KPX uni021A Aogonek -65
+KPX uni021A abreve -40
+KPX uni021A amacron -40
+KPX uni021A Amacron -65
+KPX uni021A ydieresis -55
+KPX uni021A yacute -85
+KPX uni021A udieresis -55
+KPX uni021A ucircumflex -55
+KPX uni021A uacute -85
+KPX uni021A ugrave -55
+KPX uni021A oslash -100
+KPX uni021A odieresis -50
+KPX uni021A otilde -50
+KPX uni021A ocircumflex -50
+KPX uni021A oacute -75
+KPX uni021A ograve -50
+KPX uni021A idieresis -15
+KPX uni021A icircumflex -15
+KPX uni021A iacute -20
+KPX uni021A igrave -15
+KPX uni021A edieresis -50
+KPX uni021A ecircumflex -50
+KPX uni021A eacute -70
+KPX uni021A egrave -50
+KPX uni021A ccedilla -95
+KPX uni021A ae -75
+KPX uni021A aring -40
+KPX uni021A adieresis -40
+KPX uni021A atilde -40
+KPX uni021A acircumflex -40
+KPX uni021A aacute -60
+KPX uni021A agrave -40
+KPX uni021A Oslash -20
+KPX uni021A Odieresis -20
+KPX uni021A Ccedilla -25
+KPX uni021A AE -115
+KPX uni021A Aring -65
+KPX uni021A Adieresis -65
+KPX uni021A guillemotleft -125
+KPX uni021A y -110
+KPX uni021A w -105
+KPX uni021A v -105
+KPX uni021A u -110
+KPX uni021A s -70
+KPX uni021A r -65
+KPX uni021A o -100
+KPX uni021A j -10
+KPX uni021A i -25
+KPX uni021A g -95
+KPX uni021A e -95
+KPX uni021A c -95
+KPX uni021A a -80
+KPX uni021A O -20
+KPX uni021A G -25
+KPX uni021A C -25
+KPX uni021A A -65
+KPX uni021A semicolon -100
+KPX uni021A colon -95
+KPX uni021A period -90
+KPX uni021A hyphen -75
+KPX uni021A comma -100
+KPX uni021B oogonek -10
+KPX uni021B ohungarumlaut -10
+KPX uni021B obreve -10
+KPX uni021B omacron -10
+KPX uni021B hcircumflex 15
+KPX uni021B oslash -10
+KPX uni021B odieresis -10
+KPX uni021B o -10
+KPX uni021B h 15
+KPX uni021B semicolon -25
+KPX ringhalfright a.sc -135
+KPX ringhalfright A -130
+KPX ringhalfleft a.sc -130
+KPX ringhalfleft A -130
+KPX Rdotaccent ydieresis.sc -40
+KPX Rdotaccent udieresis.sc -45
+KPX Rdotaccent ucircumflex.sc -45
+KPX Rdotaccent oslash.sc -35
+KPX Rdotaccent odieresis.sc -35
+KPX Rdotaccent ccedilla.sc -35
+KPX Rdotaccent y.sc -40
+KPX Rdotaccent w.sc -45
+KPX Rdotaccent v.sc -45
+KPX Rdotaccent u.sc -45
+KPX Rdotaccent t.sc -30
+KPX Rdotaccent o.sc -35
+KPX Rdotaccent g.sc -35
+KPX Rdotaccent c.sc -35
+KPX Rdotaccent ycircumflex.sc -40
+KPX Rdotaccent wgrave.sc -45
+KPX Rdotaccent wdieresis.sc -45
+KPX Rdotaccent wcircumflex.sc -45
+KPX Rdotaccent wacute.sc -45
+KPX Rdotaccent uring.sc -45
+KPX Rdotaccent uogonek.sc -45
+KPX Rdotaccent umacron.sc -45
+KPX Rdotaccent uhungarumlaut.sc -45
+KPX Rdotaccent ubreve.sc -45
+KPX Rdotaccent uni021B.sc -30
+KPX Rdotaccent tcaron.sc -30
+KPX Rdotaccent omacron.sc -35
+KPX Rdotaccent ohungarumlaut.sc -35
+KPX Rdotaccent obreve.sc -35
+KPX Rdotaccent gdotaccent.sc -35
+KPX Rdotaccent gcommaaccent.sc -35
+KPX Rdotaccent gcircumflex.sc -35
+KPX Rdotaccent gbreve.sc -35
+KPX Rdotaccent cdotaccent.sc -35
+KPX Rdotaccent ccircumflex.sc -35
+KPX Rdotaccent ccaron.sc -35
+KPX Rdotaccent cacute.sc -35
+KPX Rdotaccent oogonek.sc -35
+KPX Rdotaccent oe.sc -35
+KPX Rdotaccent gcaron.sc -35
+KPX Rdotaccent gacute.sc -35
+KPX Rdotaccent Wdieresis -55
+KPX Rdotaccent Wacute -55
+KPX Rdotaccent Wgrave -55
+KPX Rdotaccent uni021A -35
+KPX Rdotaccent Gacute -40
+KPX Rdotaccent oogonek -25
+KPX Rdotaccent Oogonek -40
+KPX Rdotaccent Gcaron -40
+KPX Rdotaccent Ydieresis -50
+KPX Rdotaccent ycircumflex -35
+KPX Rdotaccent Ycircumflex -50
+KPX Rdotaccent Wcircumflex -55
+KPX Rdotaccent uogonek -35
+KPX Rdotaccent Uogonek -55
+KPX Rdotaccent uhungarumlaut -35
+KPX Rdotaccent Uhungarumlaut -55
+KPX Rdotaccent uring -35
+KPX Rdotaccent Uring -55
+KPX Rdotaccent ubreve -35
+KPX Rdotaccent Ubreve -55
+KPX Rdotaccent umacron -35
+KPX Rdotaccent Umacron -55
+KPX Rdotaccent Tcaron -35
+KPX Rdotaccent oe -25
+KPX Rdotaccent OE -40
+KPX Rdotaccent ohungarumlaut -25
+KPX Rdotaccent Ohungarumlaut -40
+KPX Rdotaccent obreve -25
+KPX Rdotaccent Obreve -40
+KPX Rdotaccent omacron -25
+KPX Rdotaccent Omacron -40
+KPX Rdotaccent Gcommaaccent -40
+KPX Rdotaccent Gdotaccent -40
+KPX Rdotaccent Gbreve -40
+KPX Rdotaccent Gcircumflex -40
+KPX Rdotaccent ecaron -20
+KPX Rdotaccent eogonek -20
+KPX Rdotaccent edotaccent -20
+KPX Rdotaccent ebreve -20
+KPX Rdotaccent emacron -20
+KPX Rdotaccent Ccaron -40
+KPX Rdotaccent Cdotaccent -40
+KPX Rdotaccent Ccircumflex -40
+KPX Rdotaccent Cacute -40
+KPX Rdotaccent ydieresis -35
+KPX Rdotaccent udieresis -35
+KPX Rdotaccent ucircumflex -35
+KPX Rdotaccent oslash -25
+KPX Rdotaccent odieresis -25
+KPX Rdotaccent edieresis -20
+KPX Rdotaccent Udieresis -55
+KPX Rdotaccent Ucircumflex -55
+KPX Rdotaccent Oslash -40
+KPX Rdotaccent Odieresis -40
+KPX Rdotaccent Ccedilla -40
+KPX Rdotaccent y -35
+KPX Rdotaccent u -35
+KPX Rdotaccent o -25
+KPX Rdotaccent e -20
+KPX Rdotaccent Y -50
+KPX Rdotaccent W -55
+KPX Rdotaccent V -55
+KPX Rdotaccent U -55
+KPX Rdotaccent T -35
+KPX Rdotaccent O -40
+KPX Rdotaccent G -40
+KPX Rdotaccent C -40
+KPX Rdotaccent hyphen -50
+KPX Rdotaccent T_h -35
+KPX rdotaccent jacute 25
+KPX rdotaccent wdieresis 20
+KPX rdotaccent wacute 20
+KPX rdotaccent wgrave 20
+KPX rdotaccent aeacute -15
+KPX rdotaccent gacute -10
+KPX rdotaccent gcaron -10
+KPX rdotaccent zcaron -10
+KPX rdotaccent zdotaccent -10
+KPX rdotaccent zacute -10
+KPX rdotaccent ycircumflex 15
+KPX rdotaccent wcircumflex 20
+KPX rdotaccent uogonek 10
+KPX rdotaccent uhungarumlaut 10
+KPX rdotaccent uring 10
+KPX rdotaccent ubreve 10
+KPX rdotaccent umacron 10
+KPX rdotaccent ncaron 15
+KPX rdotaccent ncommaaccent 15
+KPX rdotaccent nacute 15
+KPX rdotaccent lslash -30
+KPX rdotaccent lcaron -30
+KPX rdotaccent lcommaaccent -30
+KPX rdotaccent lacute -30
+KPX rdotaccent kcommaaccent -30
+KPX rdotaccent jcircumflex 25
+KPX rdotaccent hcircumflex -20
+KPX rdotaccent gcommaaccent -10
+KPX rdotaccent gdotaccent -10
+KPX rdotaccent gbreve -10
+KPX rdotaccent gcircumflex -10
+KPX rdotaccent dcaron -15
+KPX rdotaccent aogonek -15
+KPX rdotaccent amacron -15
+KPX rdotaccent ydieresis 15
+KPX rdotaccent udieresis 10
+KPX rdotaccent ucircumflex 10
+KPX rdotaccent ntilde 15
+KPX rdotaccent ae -15
+KPX rdotaccent aring -15
+KPX rdotaccent adieresis -15
+KPX rdotaccent z -10
+KPX rdotaccent y 15
+KPX rdotaccent x 10
+KPX rdotaccent w 20
+KPX rdotaccent v 20
+KPX rdotaccent u 10
+KPX rdotaccent q -15
+KPX rdotaccent p 15
+KPX rdotaccent n 15
+KPX rdotaccent m 10
+KPX rdotaccent l -30
+KPX rdotaccent k -30
+KPX rdotaccent j 25
+KPX rdotaccent h -20
+KPX rdotaccent g -10
+KPX rdotaccent d -15
+KPX rdotaccent a -15
+KPX rdotaccent semicolon -30
+KPX rdotaccent colon -20
+KPX rdotaccent period -60
+KPX rdotaccent hyphen -30
+KPX rdotaccent comma -70
+KPX Wgrave zdotaccent -53
+KPX Wgrave zcaron -53
+KPX Wgrave zacute -53
+KPX Wgrave z -53
+KPX Wgrave scircumflex -60
+KPX Wgrave scedilla -60
+KPX Wgrave scaron -60
+KPX Wgrave sacute -60
+KPX Wgrave s -60
+KPX Wgrave cdotaccent -53
+KPX Wgrave ccircumflex -53
+KPX Wgrave ccedilla -53
+KPX Wgrave ccaron -53
+KPX Wgrave cacute -53
+KPX Wgrave c -53
+KPX Wgrave oslash.sc -45
+KPX Wgrave odieresis.sc -25
+KPX Wgrave otilde.sc -25
+KPX Wgrave ocircumflex.sc -25
+KPX Wgrave oacute.sc -35
+KPX Wgrave ograve.sc -25
+KPX Wgrave ccedilla.sc -45
+KPX Wgrave ae.sc -80
+KPX Wgrave aring.sc -50
+KPX Wgrave adieresis.sc -50
+KPX Wgrave atilde.sc -50
+KPX Wgrave acircumflex.sc -50
+KPX Wgrave aacute.sc -70
+KPX Wgrave agrave.sc -50
+KPX Wgrave s.sc -30
+KPX Wgrave o.sc -45
+KPX Wgrave g.sc -45
+KPX Wgrave c.sc -45
+KPX Wgrave a.sc -95
+KPX Wgrave uni0219.sc -30
+KPX Wgrave scircumflex.sc -15
+KPX Wgrave scedilla.sc -30
+KPX Wgrave sacute.sc -20
+KPX Wgrave omacron.sc -25
+KPX Wgrave ohungarumlaut.sc -25
+KPX Wgrave obreve.sc -25
+KPX Wgrave gdotaccent.sc -25
+KPX Wgrave gcommaaccent.sc -45
+KPX Wgrave gcircumflex.sc -25
+KPX Wgrave gbreve.sc -25
+KPX Wgrave cdotaccent.sc -25
+KPX Wgrave ccircumflex.sc -25
+KPX Wgrave ccaron.sc -25
+KPX Wgrave cacute.sc -35
+KPX Wgrave aeacute.sc -80
+KPX Wgrave aogonek.sc -95
+KPX Wgrave amacron.sc -50
+KPX Wgrave abreve.sc -50
+KPX Wgrave scaron.sc -15
+KPX Wgrave oogonek.sc -45
+KPX Wgrave ohorntilde.sc -25
+KPX Wgrave ohornhookabove.sc -25
+KPX Wgrave ohorngrave.sc -25
+KPX Wgrave ohorndotbelow.sc -25
+KPX Wgrave ohornacute.sc -25
+KPX Wgrave ohookabove.sc -25
+KPX Wgrave oe.sc -40
+KPX Wgrave ocircumflexdotbelow.sc -25
+KPX Wgrave gcaron.sc -25
+KPX Wgrave gacute.sc -35
+KPX Wgrave ahookabove.sc -50
+KPX Wgrave acircumflexdotbelow.sc -50
+KPX Wgrave abrevedotbelow.sc -50
+KPX Wgrave guilsinglleft -100
+KPX Wgrave ytilde -25
+KPX Wgrave yhookabove -25
+KPX Wgrave ygrave -25
+KPX Wgrave uhorndotbelow -25
+KPX Wgrave uhorntilde -25
+KPX Wgrave uhornhookabove -25
+KPX Wgrave uhorngrave -25
+KPX Wgrave uhornacute -25
+KPX Wgrave uhookabove -25
+KPX Wgrave ohorndotbelow -35
+KPX Wgrave ohorntilde -35
+KPX Wgrave ohornhookabove -35
+KPX Wgrave ohorngrave -35
+KPX Wgrave ohornacute -35
+KPX Wgrave ocircumflexdotbelow -35
+KPX Wgrave ohookabove -35
+KPX Wgrave ecircumflexdotbelow -35
+KPX Wgrave etilde -35
+KPX Wgrave ehookabove -35
+KPX Wgrave abrevedotbelow -40
+KPX Wgrave acircumflexdotbelow -40
+KPX Wgrave ahookabove -40
+KPX Wgrave rdotaccent -30
+KPX Wgrave uni0218 -35
+KPX Wgrave aeacute -75
+KPX Wgrave AEacute -115
+KPX Wgrave gacute -60
+KPX Wgrave Gacute -55
+KPX Wgrave oogonek -70
+KPX Wgrave Oogonek -55
+KPX Wgrave gcaron -40
+KPX Wgrave Gcaron -55
+KPX Wgrave ycircumflex -25
+KPX Wgrave uogonek -50
+KPX Wgrave uhungarumlaut -25
+KPX Wgrave uring -25
+KPX Wgrave ubreve -25
+KPX Wgrave umacron -25
+KPX Wgrave utilde -25
+KPX Wgrave Scaron -35
+KPX Wgrave Scedilla -35
+KPX Wgrave Scircumflex -35
+KPX Wgrave Sacute -35
+KPX Wgrave rcaron -30
+KPX Wgrave rcommaaccent -55
+KPX Wgrave racute -40
+KPX Wgrave oe -70
+KPX Wgrave OE -55
+KPX Wgrave ohungarumlaut -35
+KPX Wgrave Ohungarumlaut -55
+KPX Wgrave obreve -35
+KPX Wgrave Obreve -55
+KPX Wgrave omacron -35
+KPX Wgrave Omacron -55
+KPX Wgrave iogonek -25
+KPX Wgrave gcommaaccent -80
+KPX Wgrave Gcommaaccent -55
+KPX Wgrave gdotaccent -40
+KPX Wgrave Gdotaccent -55
+KPX Wgrave gbreve -40
+KPX Wgrave Gbreve -55
+KPX Wgrave gcircumflex -40
+KPX Wgrave Gcircumflex -55
+KPX Wgrave ecaron -35
+KPX Wgrave eogonek -65
+KPX Wgrave edotaccent -35
+KPX Wgrave ebreve -35
+KPX Wgrave emacron -35
+KPX Wgrave Ccaron -55
+KPX Wgrave Cdotaccent -55
+KPX Wgrave Ccircumflex -55
+KPX Wgrave Cacute -55
+KPX Wgrave aogonek -75
+KPX Wgrave Aogonek -115
+KPX Wgrave abreve -40
+KPX Wgrave amacron -40
+KPX Wgrave Amacron -115
+KPX Wgrave ydieresis -25
+KPX Wgrave yacute -35
+KPX Wgrave udieresis -25
+KPX Wgrave ucircumflex -25
+KPX Wgrave uacute -40
+KPX Wgrave ugrave -25
+KPX Wgrave oslash -70
+KPX Wgrave odieresis -35
+KPX Wgrave otilde -35
+KPX Wgrave ocircumflex -35
+KPX Wgrave oacute -55
+KPX Wgrave ograve -35
+KPX Wgrave iacute -10
+KPX Wgrave edieresis -35
+KPX Wgrave ecircumflex -35
+KPX Wgrave eacute -50
+KPX Wgrave egrave -35
+KPX Wgrave ae -75
+KPX Wgrave aring -40
+KPX Wgrave adieresis -40
+KPX Wgrave atilde -40
+KPX Wgrave acircumflex -40
+KPX Wgrave aacute -55
+KPX Wgrave agrave -40
+KPX Wgrave Oslash -55
+KPX Wgrave Odieresis -55
+KPX Wgrave Ccedilla -55
+KPX Wgrave AE -115
+KPX Wgrave Aring -115
+KPX Wgrave Adieresis -115
+KPX Wgrave guillemotleft -95
+KPX Wgrave y -45
+KPX Wgrave u -50
+KPX Wgrave r -55
+KPX Wgrave o -70
+KPX Wgrave i -25
+KPX Wgrave g -80
+KPX Wgrave e -65
+KPX Wgrave a -75
+KPX Wgrave S -35
+KPX Wgrave O -55
+KPX Wgrave G -55
+KPX Wgrave C -55
+KPX Wgrave A -115
+KPX Wgrave semicolon -95
+KPX Wgrave colon -80
+KPX Wgrave period -90
+KPX Wgrave hyphen -45
+KPX Wgrave comma -105
+KPX wgrave uni0219 -15
+KPX wgrave aeacute -30
+KPX wgrave gacute -40
+KPX wgrave oogonek -40
+KPX wgrave gcaron -40
+KPX wgrave scaron -15
+KPX wgrave scedilla -15
+KPX wgrave scircumflex -15
+KPX wgrave sacute -15
+KPX wgrave oe -40
+KPX wgrave ohungarumlaut -40
+KPX wgrave obreve -40
+KPX wgrave omacron -40
+KPX wgrave lslash -35
+KPX wgrave lcaron -35
+KPX wgrave lcommaaccent -35
+KPX wgrave lacute -35
+KPX wgrave gcommaaccent -40
+KPX wgrave gdotaccent -40
+KPX wgrave gbreve -40
+KPX wgrave gcircumflex -40
+KPX wgrave ecaron -40
+KPX wgrave eogonek -40
+KPX wgrave edotaccent -40
+KPX wgrave ebreve -40
+KPX wgrave emacron -40
+KPX wgrave ccaron -50
+KPX wgrave cdotaccent -50
+KPX wgrave ccircumflex -50
+KPX wgrave cacute -50
+KPX wgrave aogonek -30
+KPX wgrave amacron -30
+KPX wgrave oslash -40
+KPX wgrave odieresis -40
+KPX wgrave edieresis -40
+KPX wgrave ccedilla -50
+KPX wgrave ae -30
+KPX wgrave aring -30
+KPX wgrave adieresis -30
+KPX wgrave s -15
+KPX wgrave o -40
+KPX wgrave l -35
+KPX wgrave g -40
+KPX wgrave e -40
+KPX wgrave c -50
+KPX wgrave a -30
+KPX wgrave semicolon -35
+KPX wgrave colon -20
+KPX wgrave period -90
+KPX wgrave hyphen -30
+KPX wgrave comma -105
+KPX Wacute zdotaccent -53
+KPX Wacute zcaron -53
+KPX Wacute zacute -53
+KPX Wacute z -53
+KPX Wacute scircumflex -60
+KPX Wacute scedilla -60
+KPX Wacute scaron -60
+KPX Wacute sacute -60
+KPX Wacute s -60
+KPX Wacute cdotaccent -53
+KPX Wacute ccircumflex -53
+KPX Wacute ccedilla -53
+KPX Wacute ccaron -53
+KPX Wacute cacute -53
+KPX Wacute c -53
+KPX Wacute oslash.sc -45
+KPX Wacute odieresis.sc -25
+KPX Wacute otilde.sc -25
+KPX Wacute ocircumflex.sc -25
+KPX Wacute oacute.sc -35
+KPX Wacute ograve.sc -25
+KPX Wacute ccedilla.sc -45
+KPX Wacute ae.sc -80
+KPX Wacute aring.sc -50
+KPX Wacute adieresis.sc -50
+KPX Wacute atilde.sc -50
+KPX Wacute acircumflex.sc -50
+KPX Wacute aacute.sc -70
+KPX Wacute agrave.sc -50
+KPX Wacute s.sc -30
+KPX Wacute o.sc -45
+KPX Wacute g.sc -45
+KPX Wacute c.sc -45
+KPX Wacute a.sc -95
+KPX Wacute uni0219.sc -30
+KPX Wacute scircumflex.sc -15
+KPX Wacute scedilla.sc -30
+KPX Wacute sacute.sc -20
+KPX Wacute omacron.sc -25
+KPX Wacute ohungarumlaut.sc -25
+KPX Wacute obreve.sc -25
+KPX Wacute gdotaccent.sc -25
+KPX Wacute gcommaaccent.sc -45
+KPX Wacute gcircumflex.sc -25
+KPX Wacute gbreve.sc -25
+KPX Wacute cdotaccent.sc -25
+KPX Wacute ccircumflex.sc -25
+KPX Wacute ccaron.sc -25
+KPX Wacute cacute.sc -35
+KPX Wacute aeacute.sc -80
+KPX Wacute aogonek.sc -95
+KPX Wacute amacron.sc -50
+KPX Wacute abreve.sc -50
+KPX Wacute scaron.sc -15
+KPX Wacute oogonek.sc -45
+KPX Wacute ohorntilde.sc -25
+KPX Wacute ohornhookabove.sc -25
+KPX Wacute ohorngrave.sc -25
+KPX Wacute ohorndotbelow.sc -25
+KPX Wacute ohornacute.sc -25
+KPX Wacute ohookabove.sc -25
+KPX Wacute oe.sc -40
+KPX Wacute ocircumflexdotbelow.sc -25
+KPX Wacute gcaron.sc -25
+KPX Wacute gacute.sc -35
+KPX Wacute ahookabove.sc -50
+KPX Wacute acircumflexdotbelow.sc -50
+KPX Wacute abrevedotbelow.sc -50
+KPX Wacute guilsinglleft -100
+KPX Wacute ytilde -25
+KPX Wacute yhookabove -25
+KPX Wacute ygrave -25
+KPX Wacute uhorndotbelow -25
+KPX Wacute uhorntilde -25
+KPX Wacute uhornhookabove -25
+KPX Wacute uhorngrave -25
+KPX Wacute uhornacute -25
+KPX Wacute uhookabove -25
+KPX Wacute ohorndotbelow -35
+KPX Wacute ohorntilde -35
+KPX Wacute ohornhookabove -35
+KPX Wacute ohorngrave -35
+KPX Wacute ohornacute -35
+KPX Wacute ocircumflexdotbelow -35
+KPX Wacute ohookabove -35
+KPX Wacute ecircumflexdotbelow -35
+KPX Wacute etilde -35
+KPX Wacute ehookabove -35
+KPX Wacute abrevedotbelow -40
+KPX Wacute acircumflexdotbelow -40
+KPX Wacute ahookabove -40
+KPX Wacute rdotaccent -30
+KPX Wacute uni0218 -35
+KPX Wacute aeacute -75
+KPX Wacute AEacute -115
+KPX Wacute gacute -60
+KPX Wacute Gacute -55
+KPX Wacute oogonek -70
+KPX Wacute Oogonek -55
+KPX Wacute gcaron -40
+KPX Wacute Gcaron -55
+KPX Wacute ycircumflex -25
+KPX Wacute uogonek -50
+KPX Wacute uhungarumlaut -25
+KPX Wacute uring -25
+KPX Wacute ubreve -25
+KPX Wacute umacron -25
+KPX Wacute utilde -25
+KPX Wacute Scaron -35
+KPX Wacute Scedilla -35
+KPX Wacute Scircumflex -35
+KPX Wacute Sacute -35
+KPX Wacute rcaron -30
+KPX Wacute rcommaaccent -55
+KPX Wacute racute -40
+KPX Wacute oe -70
+KPX Wacute OE -55
+KPX Wacute ohungarumlaut -35
+KPX Wacute Ohungarumlaut -55
+KPX Wacute obreve -35
+KPX Wacute Obreve -55
+KPX Wacute omacron -35
+KPX Wacute Omacron -55
+KPX Wacute iogonek -25
+KPX Wacute gcommaaccent -80
+KPX Wacute Gcommaaccent -55
+KPX Wacute gdotaccent -40
+KPX Wacute Gdotaccent -55
+KPX Wacute gbreve -40
+KPX Wacute Gbreve -55
+KPX Wacute gcircumflex -40
+KPX Wacute Gcircumflex -55
+KPX Wacute ecaron -35
+KPX Wacute eogonek -65
+KPX Wacute edotaccent -35
+KPX Wacute ebreve -35
+KPX Wacute emacron -35
+KPX Wacute Ccaron -55
+KPX Wacute Cdotaccent -55
+KPX Wacute Ccircumflex -55
+KPX Wacute Cacute -55
+KPX Wacute aogonek -75
+KPX Wacute Aogonek -115
+KPX Wacute abreve -40
+KPX Wacute amacron -40
+KPX Wacute Amacron -115
+KPX Wacute ydieresis -25
+KPX Wacute yacute -35
+KPX Wacute udieresis -25
+KPX Wacute ucircumflex -25
+KPX Wacute uacute -40
+KPX Wacute ugrave -25
+KPX Wacute oslash -70
+KPX Wacute odieresis -35
+KPX Wacute otilde -35
+KPX Wacute ocircumflex -35
+KPX Wacute oacute -55
+KPX Wacute ograve -35
+KPX Wacute iacute -10
+KPX Wacute edieresis -35
+KPX Wacute ecircumflex -35
+KPX Wacute eacute -50
+KPX Wacute egrave -35
+KPX Wacute ae -75
+KPX Wacute aring -40
+KPX Wacute adieresis -40
+KPX Wacute atilde -40
+KPX Wacute acircumflex -40
+KPX Wacute aacute -55
+KPX Wacute agrave -40
+KPX Wacute Oslash -55
+KPX Wacute Odieresis -55
+KPX Wacute Ccedilla -55
+KPX Wacute AE -115
+KPX Wacute Aring -115
+KPX Wacute Adieresis -115
+KPX Wacute guillemotleft -95
+KPX Wacute y -45
+KPX Wacute u -50
+KPX Wacute r -55
+KPX Wacute o -70
+KPX Wacute i -25
+KPX Wacute g -80
+KPX Wacute e -65
+KPX Wacute a -75
+KPX Wacute S -35
+KPX Wacute O -55
+KPX Wacute G -55
+KPX Wacute C -55
+KPX Wacute A -115
+KPX Wacute semicolon -95
+KPX Wacute colon -80
+KPX Wacute period -90
+KPX Wacute hyphen -45
+KPX Wacute comma -105
+KPX wacute uni0219 -15
+KPX wacute aeacute -30
+KPX wacute gacute -40
+KPX wacute oogonek -40
+KPX wacute gcaron -40
+KPX wacute scaron -15
+KPX wacute scedilla -15
+KPX wacute scircumflex -15
+KPX wacute sacute -15
+KPX wacute oe -40
+KPX wacute ohungarumlaut -40
+KPX wacute obreve -40
+KPX wacute omacron -40
+KPX wacute lslash -35
+KPX wacute lcaron -35
+KPX wacute lcommaaccent -35
+KPX wacute lacute -35
+KPX wacute gcommaaccent -40
+KPX wacute gdotaccent -40
+KPX wacute gbreve -40
+KPX wacute gcircumflex -40
+KPX wacute ecaron -40
+KPX wacute eogonek -40
+KPX wacute edotaccent -40
+KPX wacute ebreve -40
+KPX wacute emacron -40
+KPX wacute ccaron -50
+KPX wacute cdotaccent -50
+KPX wacute ccircumflex -50
+KPX wacute cacute -50
+KPX wacute aogonek -30
+KPX wacute amacron -30
+KPX wacute oslash -40
+KPX wacute odieresis -40
+KPX wacute edieresis -40
+KPX wacute ccedilla -50
+KPX wacute ae -30
+KPX wacute aring -30
+KPX wacute adieresis -30
+KPX wacute s -15
+KPX wacute o -40
+KPX wacute l -35
+KPX wacute g -40
+KPX wacute e -40
+KPX wacute c -50
+KPX wacute a -30
+KPX wacute semicolon -35
+KPX wacute colon -20
+KPX wacute period -90
+KPX wacute hyphen -30
+KPX wacute comma -105
+KPX Wdieresis zdotaccent -53
+KPX Wdieresis zcaron -53
+KPX Wdieresis zacute -53
+KPX Wdieresis z -53
+KPX Wdieresis scircumflex -60
+KPX Wdieresis scedilla -60
+KPX Wdieresis scaron -60
+KPX Wdieresis sacute -60
+KPX Wdieresis s -60
+KPX Wdieresis cdotaccent -53
+KPX Wdieresis ccircumflex -53
+KPX Wdieresis ccedilla -53
+KPX Wdieresis ccaron -53
+KPX Wdieresis cacute -53
+KPX Wdieresis c -53
+KPX Wdieresis oslash.sc -45
+KPX Wdieresis odieresis.sc -25
+KPX Wdieresis otilde.sc -25
+KPX Wdieresis ocircumflex.sc -25
+KPX Wdieresis oacute.sc -35
+KPX Wdieresis ograve.sc -25
+KPX Wdieresis ccedilla.sc -45
+KPX Wdieresis ae.sc -80
+KPX Wdieresis aring.sc -50
+KPX Wdieresis adieresis.sc -50
+KPX Wdieresis atilde.sc -50
+KPX Wdieresis acircumflex.sc -50
+KPX Wdieresis aacute.sc -70
+KPX Wdieresis agrave.sc -50
+KPX Wdieresis s.sc -30
+KPX Wdieresis o.sc -45
+KPX Wdieresis g.sc -45
+KPX Wdieresis c.sc -45
+KPX Wdieresis a.sc -95
+KPX Wdieresis uni0219.sc -30
+KPX Wdieresis scircumflex.sc -15
+KPX Wdieresis scedilla.sc -30
+KPX Wdieresis sacute.sc -20
+KPX Wdieresis omacron.sc -25
+KPX Wdieresis ohungarumlaut.sc -25
+KPX Wdieresis obreve.sc -25
+KPX Wdieresis gdotaccent.sc -25
+KPX Wdieresis gcommaaccent.sc -45
+KPX Wdieresis gcircumflex.sc -25
+KPX Wdieresis gbreve.sc -25
+KPX Wdieresis cdotaccent.sc -25
+KPX Wdieresis ccircumflex.sc -25
+KPX Wdieresis ccaron.sc -25
+KPX Wdieresis cacute.sc -35
+KPX Wdieresis aeacute.sc -80
+KPX Wdieresis aogonek.sc -95
+KPX Wdieresis amacron.sc -50
+KPX Wdieresis abreve.sc -50
+KPX Wdieresis scaron.sc -15
+KPX Wdieresis oogonek.sc -45
+KPX Wdieresis ohorntilde.sc -25
+KPX Wdieresis ohornhookabove.sc -25
+KPX Wdieresis ohorngrave.sc -25
+KPX Wdieresis ohorndotbelow.sc -25
+KPX Wdieresis ohornacute.sc -25
+KPX Wdieresis ohookabove.sc -25
+KPX Wdieresis oe.sc -40
+KPX Wdieresis ocircumflexdotbelow.sc -25
+KPX Wdieresis gcaron.sc -25
+KPX Wdieresis gacute.sc -35
+KPX Wdieresis ahookabove.sc -50
+KPX Wdieresis acircumflexdotbelow.sc -50
+KPX Wdieresis abrevedotbelow.sc -50
+KPX Wdieresis guilsinglleft -100
+KPX Wdieresis ytilde -25
+KPX Wdieresis yhookabove -25
+KPX Wdieresis ygrave -25
+KPX Wdieresis uhorndotbelow -25
+KPX Wdieresis uhorntilde -25
+KPX Wdieresis uhornhookabove -25
+KPX Wdieresis uhorngrave -25
+KPX Wdieresis uhornacute -25
+KPX Wdieresis uhookabove -25
+KPX Wdieresis ohorndotbelow -35
+KPX Wdieresis ohorntilde -35
+KPX Wdieresis ohornhookabove -35
+KPX Wdieresis ohorngrave -35
+KPX Wdieresis ohornacute -35
+KPX Wdieresis ocircumflexdotbelow -35
+KPX Wdieresis ohookabove -35
+KPX Wdieresis ecircumflexdotbelow -35
+KPX Wdieresis etilde -35
+KPX Wdieresis ehookabove -35
+KPX Wdieresis abrevedotbelow -40
+KPX Wdieresis acircumflexdotbelow -40
+KPX Wdieresis ahookabove -40
+KPX Wdieresis rdotaccent -30
+KPX Wdieresis uni0218 -35
+KPX Wdieresis aeacute -75
+KPX Wdieresis AEacute -115
+KPX Wdieresis gacute -60
+KPX Wdieresis Gacute -55
+KPX Wdieresis oogonek -70
+KPX Wdieresis Oogonek -55
+KPX Wdieresis gcaron -40
+KPX Wdieresis Gcaron -55
+KPX Wdieresis ycircumflex -25
+KPX Wdieresis uogonek -50
+KPX Wdieresis uhungarumlaut -25
+KPX Wdieresis uring -25
+KPX Wdieresis ubreve -25
+KPX Wdieresis umacron -25
+KPX Wdieresis utilde -25
+KPX Wdieresis Scaron -35
+KPX Wdieresis Scedilla -35
+KPX Wdieresis Scircumflex -35
+KPX Wdieresis Sacute -35
+KPX Wdieresis rcaron -30
+KPX Wdieresis rcommaaccent -55
+KPX Wdieresis racute -40
+KPX Wdieresis oe -70
+KPX Wdieresis OE -55
+KPX Wdieresis ohungarumlaut -35
+KPX Wdieresis Ohungarumlaut -55
+KPX Wdieresis obreve -35
+KPX Wdieresis Obreve -55
+KPX Wdieresis omacron -35
+KPX Wdieresis Omacron -55
+KPX Wdieresis iogonek -25
+KPX Wdieresis gcommaaccent -80
+KPX Wdieresis Gcommaaccent -55
+KPX Wdieresis gdotaccent -40
+KPX Wdieresis Gdotaccent -55
+KPX Wdieresis gbreve -40
+KPX Wdieresis Gbreve -55
+KPX Wdieresis gcircumflex -40
+KPX Wdieresis Gcircumflex -55
+KPX Wdieresis ecaron -35
+KPX Wdieresis eogonek -65
+KPX Wdieresis edotaccent -35
+KPX Wdieresis ebreve -35
+KPX Wdieresis emacron -35
+KPX Wdieresis Ccaron -55
+KPX Wdieresis Cdotaccent -55
+KPX Wdieresis Ccircumflex -55
+KPX Wdieresis Cacute -55
+KPX Wdieresis aogonek -75
+KPX Wdieresis Aogonek -115
+KPX Wdieresis abreve -40
+KPX Wdieresis amacron -40
+KPX Wdieresis Amacron -115
+KPX Wdieresis ydieresis -25
+KPX Wdieresis yacute -35
+KPX Wdieresis udieresis -25
+KPX Wdieresis ucircumflex -25
+KPX Wdieresis uacute -40
+KPX Wdieresis ugrave -25
+KPX Wdieresis oslash -70
+KPX Wdieresis odieresis -35
+KPX Wdieresis otilde -35
+KPX Wdieresis ocircumflex -35
+KPX Wdieresis oacute -55
+KPX Wdieresis ograve -35
+KPX Wdieresis iacute -10
+KPX Wdieresis edieresis -35
+KPX Wdieresis ecircumflex -35
+KPX Wdieresis eacute -50
+KPX Wdieresis egrave -35
+KPX Wdieresis ae -75
+KPX Wdieresis aring -40
+KPX Wdieresis adieresis -40
+KPX Wdieresis atilde -40
+KPX Wdieresis acircumflex -40
+KPX Wdieresis aacute -55
+KPX Wdieresis agrave -40
+KPX Wdieresis Oslash -55
+KPX Wdieresis Odieresis -55
+KPX Wdieresis Ccedilla -55
+KPX Wdieresis AE -115
+KPX Wdieresis Aring -115
+KPX Wdieresis Adieresis -115
+KPX Wdieresis guillemotleft -95
+KPX Wdieresis y -45
+KPX Wdieresis u -50
+KPX Wdieresis r -55
+KPX Wdieresis o -70
+KPX Wdieresis i -25
+KPX Wdieresis g -80
+KPX Wdieresis e -65
+KPX Wdieresis a -75
+KPX Wdieresis S -35
+KPX Wdieresis O -55
+KPX Wdieresis G -55
+KPX Wdieresis C -55
+KPX Wdieresis A -115
+KPX Wdieresis semicolon -95
+KPX Wdieresis colon -80
+KPX Wdieresis period -90
+KPX Wdieresis hyphen -45
+KPX Wdieresis comma -105
+KPX wdieresis uni0219 -15
+KPX wdieresis aeacute -30
+KPX wdieresis gacute -40
+KPX wdieresis oogonek -40
+KPX wdieresis gcaron -40
+KPX wdieresis scaron -15
+KPX wdieresis scedilla -15
+KPX wdieresis scircumflex -15
+KPX wdieresis sacute -15
+KPX wdieresis oe -40
+KPX wdieresis ohungarumlaut -40
+KPX wdieresis obreve -40
+KPX wdieresis omacron -40
+KPX wdieresis lslash -35
+KPX wdieresis lcaron -35
+KPX wdieresis lcommaaccent -35
+KPX wdieresis lacute -35
+KPX wdieresis gcommaaccent -40
+KPX wdieresis gdotaccent -40
+KPX wdieresis gbreve -40
+KPX wdieresis gcircumflex -40
+KPX wdieresis ecaron -40
+KPX wdieresis eogonek -40
+KPX wdieresis edotaccent -40
+KPX wdieresis ebreve -40
+KPX wdieresis emacron -40
+KPX wdieresis ccaron -50
+KPX wdieresis cdotaccent -50
+KPX wdieresis ccircumflex -50
+KPX wdieresis cacute -50
+KPX wdieresis aogonek -30
+KPX wdieresis amacron -30
+KPX wdieresis oslash -40
+KPX wdieresis odieresis -40
+KPX wdieresis edieresis -40
+KPX wdieresis ccedilla -50
+KPX wdieresis ae -30
+KPX wdieresis aring -30
+KPX wdieresis adieresis -30
+KPX wdieresis s -15
+KPX wdieresis o -40
+KPX wdieresis l -35
+KPX wdieresis g -40
+KPX wdieresis e -40
+KPX wdieresis c -50
+KPX wdieresis a -30
+KPX wdieresis semicolon -35
+KPX wdieresis colon -20
+KPX wdieresis period -90
+KPX wdieresis hyphen -30
+KPX wdieresis comma -105
+KPX Adotbelow y.sc -75
+KPX Adotbelow u.sc -60
+KPX Adotbelow t.sc -60
+KPX Adotbelow o.sc -60
+KPX Adotbelow c.sc -60
+KPX Adotbelow y -90
+KPX Adotbelow u -45
+KPX Adotbelow t -40
+KPX Adotbelow o -35
+KPX Adotbelow c -35
+KPX Adotbelow Y -90
+KPX Adotbelow U -75
+KPX Adotbelow T -70
+KPX Adotbelow O -70
+KPX Adotbelow C -70
+KPX Adotbelow T_h -70
+KPX adotbelow y -40
+KPX Ahookabove y.sc -75
+KPX Ahookabove u.sc -60
+KPX Ahookabove o.sc -60
+KPX Ahookabove y -90
+KPX Ahookabove u -45
+KPX Ahookabove o -35
+KPX Ahookabove Y -90
+KPX Ahookabove U -75
+KPX Ahookabove O -70
+KPX ahookabove y -40
+KPX Acircumflexacute y.sc -75
+KPX Acircumflexacute u.sc -60
+KPX Acircumflexacute t.sc -60
+KPX Acircumflexacute c.sc -60
+KPX Acircumflexacute y -90
+KPX Acircumflexacute u -45
+KPX Acircumflexacute t -40
+KPX Acircumflexacute c -35
+KPX Acircumflexacute Y -90
+KPX Acircumflexacute U -75
+KPX Acircumflexacute T -70
+KPX Acircumflexacute C -70
+KPX Acircumflexacute T_h -70
+KPX acircumflexacute y -40
+KPX Acircumflexgrave y.sc -75
+KPX Acircumflexgrave u.sc -60
+KPX Acircumflexgrave y -90
+KPX Acircumflexgrave u -45
+KPX Acircumflexgrave Y -90
+KPX Acircumflexgrave U -75
+KPX acircumflexgrave y -40
+KPX Acircumflexhookabove y.sc -75
+KPX Acircumflexhookabove u.sc -60
+KPX Acircumflexhookabove y -90
+KPX Acircumflexhookabove u -45
+KPX Acircumflexhookabove Y -90
+KPX Acircumflexhookabove U -75
+KPX acircumflexhookabove y -40
+KPX Acircumflextilde y.sc -75
+KPX Acircumflextilde u.sc -60
+KPX Acircumflextilde y -90
+KPX Acircumflextilde u -45
+KPX Acircumflextilde Y -90
+KPX Acircumflextilde U -75
+KPX acircumflextilde y -40
+KPX Acircumflexdotbelow y.sc -75
+KPX Acircumflexdotbelow u.sc -60
+KPX Acircumflexdotbelow t.sc -60
+KPX Acircumflexdotbelow c.sc -60
+KPX Acircumflexdotbelow y -90
+KPX Acircumflexdotbelow u -45
+KPX Acircumflexdotbelow t -40
+KPX Acircumflexdotbelow c -35
+KPX Acircumflexdotbelow Y -90
+KPX Acircumflexdotbelow U -75
+KPX Acircumflexdotbelow T -70
+KPX Acircumflexdotbelow C -70
+KPX Acircumflexdotbelow T_h -70
+KPX acircumflexdotbelow y -40
+KPX Abreveacute t.sc -60
+KPX Abreveacute c.sc -60
+KPX Abreveacute t -40
+KPX Abreveacute c -35
+KPX Abreveacute T -70
+KPX Abreveacute C -70
+KPX Abreveacute T_h -70
+KPX Abrevedotbelow t.sc -60
+KPX Abrevedotbelow c.sc -60
+KPX Abrevedotbelow t -40
+KPX Abrevedotbelow c -35
+KPX Abrevedotbelow T -70
+KPX Abrevedotbelow C -70
+KPX Abrevedotbelow T_h -70
+KPX idotbelow T -30
+KPX idotbelow T_h -30
+KPX Odotbelow t.sc -10
+KPX Odotbelow a.sc -60
+KPX Odotbelow T -15
+KPX Odotbelow A -75
+KPX Odotbelow T_h -15
+KPX odotbelow t -15
+KPX odotbelow T -100
+KPX odotbelow T_h -100
+KPX Ohookabove a.sc -60
+KPX Ohookabove A -75
+KPX Ocircumflexacute t.sc -10
+KPX Ocircumflexacute T -15
+KPX Ocircumflexacute T_h -15
+KPX ocircumflexacute t -15
+KPX ocircumflexacute T -100
+KPX ocircumflexacute T_h -100
+KPX Ocircumflexdotbelow t.sc -10
+KPX Ocircumflexdotbelow T -15
+KPX Ocircumflexdotbelow T_h -15
+KPX ocircumflexdotbelow t -15
+KPX ocircumflexdotbelow T -100
+KPX ocircumflexdotbelow T_h -100
+KPX Ohornacute t.sc -10
+KPX Ohornacute T -15
+KPX Ohornacute T_h -15
+KPX ohornacute t -15
+KPX ohornacute T -100
+KPX ohornacute T_h -100
+KPX Ohorndotbelow t.sc -10
+KPX Ohorndotbelow T -15
+KPX Ohorndotbelow T_h -15
+KPX ohorndotbelow t -15
+KPX ohorndotbelow T -100
+KPX ohorndotbelow T_h -100
+KPX Udotbelow aring.sc -35
+KPX Udotbelow adieresis.sc -35
+KPX Udotbelow atilde.sc -35
+KPX Udotbelow acircumflex.sc -35
+KPX Udotbelow aacute.sc -50
+KPX Udotbelow agrave.sc -35
+KPX Udotbelow a.sc -65
+KPX Udotbelow amacron.sc -35
+KPX Udotbelow abreve.sc -35
+KPX Udotbelow ahookabove.sc -35
+KPX Udotbelow acircumflexdotbelow.sc -35
+KPX Udotbelow abrevedotbelow.sc -35
+KPX Udotbelow rdotaccent -20
+KPX Udotbelow rcaron -20
+KPX Udotbelow racute -30
+KPX Udotbelow ncaron -20
+KPX Udotbelow nacute -25
+KPX Udotbelow ntilde -20
+KPX Udotbelow p -35
+KPX Udotbelow n -35
+KPX Udotbelow m -40
+KPX Udotbelow A -80
+KPX Uhookabove aring.sc -35
+KPX Uhookabove adieresis.sc -35
+KPX Uhookabove atilde.sc -35
+KPX Uhookabove acircumflex.sc -35
+KPX Uhookabove aacute.sc -50
+KPX Uhookabove agrave.sc -35
+KPX Uhookabove a.sc -65
+KPX Uhookabove amacron.sc -35
+KPX Uhookabove abreve.sc -35
+KPX Uhookabove ahookabove.sc -35
+KPX Uhookabove acircumflexdotbelow.sc -35
+KPX Uhookabove abrevedotbelow.sc -35
+KPX Uhookabove rdotaccent -20
+KPX Uhookabove rcaron -20
+KPX Uhookabove racute -30
+KPX Uhookabove ncaron -20
+KPX Uhookabove nacute -25
+KPX Uhookabove ntilde -20
+KPX Uhookabove n -35
+KPX Uhookabove m -40
+KPX Uhookabove A -80
+KPX Uhornacute aring.sc -35
+KPX Uhornacute adieresis.sc -35
+KPX Uhornacute atilde.sc -35
+KPX Uhornacute acircumflex.sc -35
+KPX Uhornacute aacute.sc -50
+KPX Uhornacute agrave.sc -35
+KPX Uhornacute a.sc -65
+KPX Uhornacute amacron.sc -35
+KPX Uhornacute abreve.sc -35
+KPX Uhornacute ahookabove.sc -35
+KPX Uhornacute acircumflexdotbelow.sc -35
+KPX Uhornacute abrevedotbelow.sc -35
+KPX Uhornacute rdotaccent -20
+KPX Uhornacute rcaron -20
+KPX Uhornacute racute -30
+KPX Uhornacute ncaron -20
+KPX Uhornacute nacute -25
+KPX Uhornacute ntilde -20
+KPX Uhornacute n -35
+KPX Uhornacute A -80
+KPX Uhorngrave aring.sc -35
+KPX Uhorngrave adieresis.sc -35
+KPX Uhorngrave atilde.sc -35
+KPX Uhorngrave acircumflex.sc -35
+KPX Uhorngrave aacute.sc -50
+KPX Uhorngrave agrave.sc -35
+KPX Uhorngrave a.sc -65
+KPX Uhorngrave amacron.sc -35
+KPX Uhorngrave abreve.sc -35
+KPX Uhorngrave ahookabove.sc -35
+KPX Uhorngrave acircumflexdotbelow.sc -35
+KPX Uhorngrave abrevedotbelow.sc -35
+KPX Uhorngrave rdotaccent -20
+KPX Uhorngrave rcaron -20
+KPX Uhorngrave racute -30
+KPX Uhorngrave ncaron -20
+KPX Uhorngrave nacute -25
+KPX Uhorngrave ntilde -20
+KPX Uhorngrave n -35
+KPX Uhorngrave m -40
+KPX Uhorngrave A -80
+KPX Uhornhookabove aring.sc -35
+KPX Uhornhookabove adieresis.sc -35
+KPX Uhornhookabove atilde.sc -35
+KPX Uhornhookabove acircumflex.sc -35
+KPX Uhornhookabove aacute.sc -50
+KPX Uhornhookabove agrave.sc -35
+KPX Uhornhookabove a.sc -65
+KPX Uhornhookabove amacron.sc -35
+KPX Uhornhookabove abreve.sc -35
+KPX Uhornhookabove ahookabove.sc -35
+KPX Uhornhookabove acircumflexdotbelow.sc -35
+KPX Uhornhookabove abrevedotbelow.sc -35
+KPX Uhornhookabove rdotaccent -20
+KPX Uhornhookabove rcaron -20
+KPX Uhornhookabove racute -30
+KPX Uhornhookabove ncaron -20
+KPX Uhornhookabove nacute -25
+KPX Uhornhookabove ntilde -20
+KPX Uhornhookabove n -35
+KPX Uhornhookabove A -80
+KPX Uhorntilde aring.sc -35
+KPX Uhorntilde adieresis.sc -35
+KPX Uhorntilde atilde.sc -35
+KPX Uhorntilde acircumflex.sc -35
+KPX Uhorntilde aacute.sc -50
+KPX Uhorntilde agrave.sc -35
+KPX Uhorntilde a.sc -65
+KPX Uhorntilde amacron.sc -35
+KPX Uhorntilde abreve.sc -35
+KPX Uhorntilde ahookabove.sc -35
+KPX Uhorntilde acircumflexdotbelow.sc -35
+KPX Uhorntilde abrevedotbelow.sc -35
+KPX Uhorntilde rdotaccent -20
+KPX Uhorntilde rcaron -20
+KPX Uhorntilde racute -30
+KPX Uhorntilde ncaron -20
+KPX Uhorntilde nacute -25
+KPX Uhorntilde ntilde -20
+KPX Uhorntilde n -35
+KPX Uhorntilde A -80
+KPX Uhorndotbelow aring.sc -35
+KPX Uhorndotbelow adieresis.sc -35
+KPX Uhorndotbelow atilde.sc -35
+KPX Uhorndotbelow acircumflex.sc -35
+KPX Uhorndotbelow aacute.sc -50
+KPX Uhorndotbelow agrave.sc -35
+KPX Uhorndotbelow a.sc -65
+KPX Uhorndotbelow amacron.sc -35
+KPX Uhorndotbelow abreve.sc -35
+KPX Uhorndotbelow ahookabove.sc -35
+KPX Uhorndotbelow acircumflexdotbelow.sc -35
+KPX Uhorndotbelow abrevedotbelow.sc -35
+KPX Uhorndotbelow rdotaccent -20
+KPX Uhorndotbelow rcaron -20
+KPX Uhorndotbelow racute -30
+KPX Uhorndotbelow ncaron -20
+KPX Uhorndotbelow nacute -25
+KPX Uhorndotbelow ntilde -20
+KPX Uhorndotbelow n -35
+KPX Uhorndotbelow A -80
+KPX Ygrave zdotaccent -67
+KPX Ygrave zcaron -67
+KPX Ygrave zacute -67
+KPX Ygrave z -67
+KPX Ygrave scircumflex -67
+KPX Ygrave scedilla -67
+KPX Ygrave scaron -67
+KPX Ygrave sacute -67
+KPX Ygrave s -67
+KPX Ygrave cdotaccent -67
+KPX Ygrave ccircumflex -67
+KPX Ygrave ccedilla -67
+KPX Ygrave ccaron -67
+KPX Ygrave cacute -67
+KPX Ygrave c -67
+KPX Ygrave odieresis.sc -30
+KPX Ygrave otilde.sc -30
+KPX Ygrave ocircumflex.sc -30
+KPX Ygrave oacute.sc -45
+KPX Ygrave ograve.sc -30
+KPX Ygrave ae.sc -80
+KPX Ygrave aring.sc -30
+KPX Ygrave adieresis.sc -30
+KPX Ygrave atilde.sc -30
+KPX Ygrave acircumflex.sc -30
+KPX Ygrave aacute.sc -45
+KPX Ygrave agrave.sc -30
+KPX Ygrave scircumflex.sc -15
+KPX Ygrave sacute.sc -20
+KPX Ygrave omacron.sc -30
+KPX Ygrave ohungarumlaut.sc -30
+KPX Ygrave obreve.sc -30
+KPX Ygrave gdotaccent.sc -30
+KPX Ygrave gcircumflex.sc -30
+KPX Ygrave gbreve.sc -30
+KPX Ygrave cdotaccent.sc -30
+KPX Ygrave ccircumflex.sc -30
+KPX Ygrave ccaron.sc -30
+KPX Ygrave cacute.sc -45
+KPX Ygrave aeacute.sc -80
+KPX Ygrave amacron.sc -30
+KPX Ygrave abreve.sc -30
+KPX Ygrave scaron.sc -15
+KPX Ygrave ohorntilde.sc -30
+KPX Ygrave ohornhookabove.sc -30
+KPX Ygrave ohorngrave.sc -30
+KPX Ygrave ohorndotbelow.sc -30
+KPX Ygrave ohornacute.sc -30
+KPX Ygrave ohookabove.sc -30
+KPX Ygrave oe.sc -40
+KPX Ygrave ocircumflexdotbelow.sc -30
+KPX Ygrave gcaron.sc -30
+KPX Ygrave gacute.sc -45
+KPX Ygrave ahookabove.sc -30
+KPX Ygrave acircumflexdotbelow.sc -30
+KPX Ygrave abrevedotbelow.sc -30
+KPX Ygrave uhorndotbelow -40
+KPX Ygrave uhorntilde -40
+KPX Ygrave uhornhookabove -40
+KPX Ygrave uhorngrave -40
+KPX Ygrave uhornacute -40
+KPX Ygrave uhookabove -40
+KPX Ygrave ohorndotbelow -50
+KPX Ygrave ohorntilde -50
+KPX Ygrave ohornhookabove -50
+KPX Ygrave ohorngrave -50
+KPX Ygrave ohornacute -50
+KPX Ygrave ocircumflexdotbelow -50
+KPX Ygrave ohookabove -50
+KPX Ygrave ecircumflexdotbelow -45
+KPX Ygrave etilde -45
+KPX Ygrave ehookabove -45
+KPX Ygrave abrevedotbelow -45
+KPX Ygrave acircumflexdotbelow -45
+KPX Ygrave ahookabove -45
+KPX Ygrave aeacute -75
+KPX Ygrave AEacute -115
+KPX Ygrave gacute -75
+KPX Ygrave gcaron -50
+KPX Ygrave uhungarumlaut -40
+KPX Ygrave uring -40
+KPX Ygrave ubreve -40
+KPX Ygrave umacron -40
+KPX Ygrave utilde -40
+KPX Ygrave oe -70
+KPX Ygrave OE -55
+KPX Ygrave ohungarumlaut -50
+KPX Ygrave obreve -50
+KPX Ygrave omacron -50
+KPX Ygrave gdotaccent -50
+KPX Ygrave gbreve -50
+KPX Ygrave gcircumflex -50
+KPX Ygrave ecaron -45
+KPX Ygrave edotaccent -45
+KPX Ygrave ebreve -45
+KPX Ygrave emacron -45
+KPX Ygrave abreve -45
+KPX Ygrave amacron -45
+KPX Ygrave udieresis -40
+KPX Ygrave ucircumflex -40
+KPX Ygrave uacute -60
+KPX Ygrave ugrave -40
+KPX Ygrave odieresis -50
+KPX Ygrave otilde -50
+KPX Ygrave ocircumflex -50
+KPX Ygrave oacute -70
+KPX Ygrave ograve -50
+KPX Ygrave iacute -10
+KPX Ygrave edieresis -45
+KPX Ygrave ecircumflex -45
+KPX Ygrave eacute -70
+KPX Ygrave egrave -45
+KPX Ygrave ae -75
+KPX Ygrave aring -45
+KPX Ygrave adieresis -45
+KPX Ygrave atilde -45
+KPX Ygrave acircumflex -45
+KPX Ygrave aacute -65
+KPX Ygrave agrave -45
+KPX Ygrave AE -115
+KPX Ygrave i -25
+KPX ygrave aeacute -30
+KPX ygrave oe -40
+KPX ygrave ae -30
+KPX Ydotbelow zdotaccent -67
+KPX Ydotbelow zcaron -67
+KPX Ydotbelow zacute -67
+KPX Ydotbelow z -67
+KPX Ydotbelow scircumflex -67
+KPX Ydotbelow scedilla -67
+KPX Ydotbelow scaron -67
+KPX Ydotbelow sacute -67
+KPX Ydotbelow s -67
+KPX Ydotbelow cdotaccent -67
+KPX Ydotbelow ccircumflex -67
+KPX Ydotbelow ccedilla -67
+KPX Ydotbelow ccaron -67
+KPX Ydotbelow cacute -67
+KPX Ydotbelow c -67
+KPX Ydotbelow odieresis.sc -30
+KPX Ydotbelow otilde.sc -30
+KPX Ydotbelow ocircumflex.sc -30
+KPX Ydotbelow oacute.sc -45
+KPX Ydotbelow ograve.sc -30
+KPX Ydotbelow ae.sc -80
+KPX Ydotbelow aring.sc -30
+KPX Ydotbelow adieresis.sc -30
+KPX Ydotbelow atilde.sc -30
+KPX Ydotbelow acircumflex.sc -30
+KPX Ydotbelow aacute.sc -45
+KPX Ydotbelow agrave.sc -30
+KPX Ydotbelow c.sc -60
+KPX Ydotbelow scircumflex.sc -15
+KPX Ydotbelow sacute.sc -20
+KPX Ydotbelow omacron.sc -30
+KPX Ydotbelow ohungarumlaut.sc -30
+KPX Ydotbelow obreve.sc -30
+KPX Ydotbelow gdotaccent.sc -30
+KPX Ydotbelow gcircumflex.sc -30
+KPX Ydotbelow gbreve.sc -30
+KPX Ydotbelow cdotaccent.sc -30
+KPX Ydotbelow ccircumflex.sc -30
+KPX Ydotbelow ccaron.sc -30
+KPX Ydotbelow cacute.sc -45
+KPX Ydotbelow aeacute.sc -80
+KPX Ydotbelow amacron.sc -30
+KPX Ydotbelow abreve.sc -30
+KPX Ydotbelow scaron.sc -15
+KPX Ydotbelow ohorntilde.sc -30
+KPX Ydotbelow ohornhookabove.sc -30
+KPX Ydotbelow ohorngrave.sc -30
+KPX Ydotbelow ohorndotbelow.sc -30
+KPX Ydotbelow ohornacute.sc -30
+KPX Ydotbelow ohookabove.sc -30
+KPX Ydotbelow oe.sc -40
+KPX Ydotbelow ocircumflexdotbelow.sc -30
+KPX Ydotbelow gcaron.sc -30
+KPX Ydotbelow gacute.sc -45
+KPX Ydotbelow ahookabove.sc -30
+KPX Ydotbelow acircumflexdotbelow.sc -30
+KPX Ydotbelow abrevedotbelow.sc -30
+KPX Ydotbelow uhorndotbelow -40
+KPX Ydotbelow uhorntilde -40
+KPX Ydotbelow uhornhookabove -40
+KPX Ydotbelow uhorngrave -40
+KPX Ydotbelow uhornacute -40
+KPX Ydotbelow uhookabove -40
+KPX Ydotbelow ohorndotbelow -50
+KPX Ydotbelow ohorntilde -50
+KPX Ydotbelow ohornhookabove -50
+KPX Ydotbelow ohorngrave -50
+KPX Ydotbelow ohornacute -50
+KPX Ydotbelow ocircumflexdotbelow -50
+KPX Ydotbelow ohookabove -50
+KPX Ydotbelow ecircumflexdotbelow -45
+KPX Ydotbelow etilde -45
+KPX Ydotbelow ehookabove -45
+KPX Ydotbelow abrevedotbelow -45
+KPX Ydotbelow acircumflexdotbelow -45
+KPX Ydotbelow ahookabove -45
+KPX Ydotbelow aeacute -75
+KPX Ydotbelow AEacute -115
+KPX Ydotbelow gacute -75
+KPX Ydotbelow gcaron -50
+KPX Ydotbelow uhungarumlaut -40
+KPX Ydotbelow uring -40
+KPX Ydotbelow ubreve -40
+KPX Ydotbelow umacron -40
+KPX Ydotbelow utilde -40
+KPX Ydotbelow oe -70
+KPX Ydotbelow OE -55
+KPX Ydotbelow ohungarumlaut -50
+KPX Ydotbelow obreve -50
+KPX Ydotbelow omacron -50
+KPX Ydotbelow gdotaccent -50
+KPX Ydotbelow gbreve -50
+KPX Ydotbelow gcircumflex -50
+KPX Ydotbelow ecaron -45
+KPX Ydotbelow edotaccent -45
+KPX Ydotbelow ebreve -45
+KPX Ydotbelow emacron -45
+KPX Ydotbelow abreve -45
+KPX Ydotbelow amacron -45
+KPX Ydotbelow udieresis -40
+KPX Ydotbelow ucircumflex -40
+KPX Ydotbelow uacute -60
+KPX Ydotbelow ugrave -40
+KPX Ydotbelow odieresis -50
+KPX Ydotbelow otilde -50
+KPX Ydotbelow ocircumflex -50
+KPX Ydotbelow oacute -70
+KPX Ydotbelow ograve -50
+KPX Ydotbelow iacute -10
+KPX Ydotbelow edieresis -45
+KPX Ydotbelow ecircumflex -45
+KPX Ydotbelow eacute -70
+KPX Ydotbelow egrave -45
+KPX Ydotbelow ae -75
+KPX Ydotbelow aring -45
+KPX Ydotbelow adieresis -45
+KPX Ydotbelow atilde -45
+KPX Ydotbelow acircumflex -45
+KPX Ydotbelow aacute -65
+KPX Ydotbelow agrave -45
+KPX Ydotbelow AE -115
+KPX Ydotbelow u -80
+KPX Ydotbelow i -25
+KPX Ydotbelow C -70
+KPX ydotbelow aeacute -30
+KPX ydotbelow oe -40
+KPX ydotbelow ae -30
+KPX ydotbelow c -45
+KPX Yhookabove zdotaccent -67
+KPX Yhookabove zcaron -67
+KPX Yhookabove zacute -67
+KPX Yhookabove z -67
+KPX Yhookabove scircumflex -67
+KPX Yhookabove scedilla -67
+KPX Yhookabove scaron -67
+KPX Yhookabove sacute -67
+KPX Yhookabove s -67
+KPX Yhookabove cdotaccent -67
+KPX Yhookabove ccircumflex -67
+KPX Yhookabove ccedilla -67
+KPX Yhookabove ccaron -67
+KPX Yhookabove cacute -67
+KPX Yhookabove c -67
+KPX Yhookabove odieresis.sc -30
+KPX Yhookabove otilde.sc -30
+KPX Yhookabove ocircumflex.sc -30
+KPX Yhookabove oacute.sc -45
+KPX Yhookabove ograve.sc -30
+KPX Yhookabove ae.sc -80
+KPX Yhookabove aring.sc -30
+KPX Yhookabove adieresis.sc -30
+KPX Yhookabove atilde.sc -30
+KPX Yhookabove acircumflex.sc -30
+KPX Yhookabove aacute.sc -45
+KPX Yhookabove agrave.sc -30
+KPX Yhookabove scircumflex.sc -15
+KPX Yhookabove sacute.sc -20
+KPX Yhookabove omacron.sc -30
+KPX Yhookabove ohungarumlaut.sc -30
+KPX Yhookabove obreve.sc -30
+KPX Yhookabove gdotaccent.sc -30
+KPX Yhookabove gcircumflex.sc -30
+KPX Yhookabove gbreve.sc -30
+KPX Yhookabove cdotaccent.sc -30
+KPX Yhookabove ccircumflex.sc -30
+KPX Yhookabove ccaron.sc -30
+KPX Yhookabove cacute.sc -45
+KPX Yhookabove aeacute.sc -80
+KPX Yhookabove amacron.sc -30
+KPX Yhookabove abreve.sc -30
+KPX Yhookabove scaron.sc -15
+KPX Yhookabove ohorntilde.sc -30
+KPX Yhookabove ohornhookabove.sc -30
+KPX Yhookabove ohorngrave.sc -30
+KPX Yhookabove ohorndotbelow.sc -30
+KPX Yhookabove ohornacute.sc -30
+KPX Yhookabove ohookabove.sc -30
+KPX Yhookabove oe.sc -40
+KPX Yhookabove ocircumflexdotbelow.sc -30
+KPX Yhookabove gcaron.sc -30
+KPX Yhookabove gacute.sc -45
+KPX Yhookabove ahookabove.sc -30
+KPX Yhookabove acircumflexdotbelow.sc -30
+KPX Yhookabove abrevedotbelow.sc -30
+KPX Yhookabove uhorndotbelow -40
+KPX Yhookabove uhorntilde -40
+KPX Yhookabove uhornhookabove -40
+KPX Yhookabove uhorngrave -40
+KPX Yhookabove uhornacute -40
+KPX Yhookabove uhookabove -40
+KPX Yhookabove ohorndotbelow -50
+KPX Yhookabove ohorntilde -50
+KPX Yhookabove ohornhookabove -50
+KPX Yhookabove ohorngrave -50
+KPX Yhookabove ohornacute -50
+KPX Yhookabove ocircumflexdotbelow -50
+KPX Yhookabove ohookabove -50
+KPX Yhookabove ecircumflexdotbelow -45
+KPX Yhookabove etilde -45
+KPX Yhookabove ehookabove -45
+KPX Yhookabove abrevedotbelow -45
+KPX Yhookabove acircumflexdotbelow -45
+KPX Yhookabove ahookabove -45
+KPX Yhookabove aeacute -75
+KPX Yhookabove AEacute -115
+KPX Yhookabove gacute -75
+KPX Yhookabove gcaron -50
+KPX Yhookabove uhungarumlaut -40
+KPX Yhookabove uring -40
+KPX Yhookabove ubreve -40
+KPX Yhookabove umacron -40
+KPX Yhookabove utilde -40
+KPX Yhookabove oe -70
+KPX Yhookabove OE -55
+KPX Yhookabove ohungarumlaut -50
+KPX Yhookabove obreve -50
+KPX Yhookabove omacron -50
+KPX Yhookabove gdotaccent -50
+KPX Yhookabove gbreve -50
+KPX Yhookabove gcircumflex -50
+KPX Yhookabove ecaron -45
+KPX Yhookabove edotaccent -45
+KPX Yhookabove ebreve -45
+KPX Yhookabove emacron -45
+KPX Yhookabove abreve -45
+KPX Yhookabove amacron -45
+KPX Yhookabove udieresis -40
+KPX Yhookabove ucircumflex -40
+KPX Yhookabove uacute -60
+KPX Yhookabove ugrave -40
+KPX Yhookabove odieresis -50
+KPX Yhookabove otilde -50
+KPX Yhookabove ocircumflex -50
+KPX Yhookabove oacute -70
+KPX Yhookabove ograve -50
+KPX Yhookabove iacute -10
+KPX Yhookabove edieresis -45
+KPX Yhookabove ecircumflex -45
+KPX Yhookabove eacute -70
+KPX Yhookabove egrave -45
+KPX Yhookabove ae -75
+KPX Yhookabove aring -45
+KPX Yhookabove adieresis -45
+KPX Yhookabove atilde -45
+KPX Yhookabove acircumflex -45
+KPX Yhookabove aacute -65
+KPX Yhookabove agrave -45
+KPX Yhookabove AE -115
+KPX Yhookabove u -80
+KPX Yhookabove i -25
+KPX yhookabove aeacute -30
+KPX yhookabove oe -40
+KPX yhookabove ae -30
+KPX Ytilde zdotaccent -67
+KPX Ytilde zcaron -67
+KPX Ytilde zacute -67
+KPX Ytilde z -67
+KPX Ytilde scircumflex -67
+KPX Ytilde scedilla -67
+KPX Ytilde scaron -67
+KPX Ytilde sacute -67
+KPX Ytilde s -67
+KPX Ytilde cdotaccent -67
+KPX Ytilde ccircumflex -67
+KPX Ytilde ccedilla -67
+KPX Ytilde ccaron -67
+KPX Ytilde cacute -67
+KPX Ytilde c -67
+KPX Ytilde odieresis.sc -30
+KPX Ytilde otilde.sc -30
+KPX Ytilde ocircumflex.sc -30
+KPX Ytilde oacute.sc -45
+KPX Ytilde ograve.sc -30
+KPX Ytilde ae.sc -80
+KPX Ytilde aring.sc -30
+KPX Ytilde adieresis.sc -30
+KPX Ytilde atilde.sc -30
+KPX Ytilde acircumflex.sc -30
+KPX Ytilde aacute.sc -45
+KPX Ytilde agrave.sc -30
+KPX Ytilde scircumflex.sc -15
+KPX Ytilde sacute.sc -20
+KPX Ytilde omacron.sc -30
+KPX Ytilde ohungarumlaut.sc -30
+KPX Ytilde obreve.sc -30
+KPX Ytilde gdotaccent.sc -30
+KPX Ytilde gcircumflex.sc -30
+KPX Ytilde gbreve.sc -30
+KPX Ytilde cdotaccent.sc -30
+KPX Ytilde ccircumflex.sc -30
+KPX Ytilde ccaron.sc -30
+KPX Ytilde cacute.sc -45
+KPX Ytilde aeacute.sc -80
+KPX Ytilde amacron.sc -30
+KPX Ytilde abreve.sc -30
+KPX Ytilde scaron.sc -15
+KPX Ytilde ohorntilde.sc -30
+KPX Ytilde ohornhookabove.sc -30
+KPX Ytilde ohorngrave.sc -30
+KPX Ytilde ohorndotbelow.sc -30
+KPX Ytilde ohornacute.sc -30
+KPX Ytilde ohookabove.sc -30
+KPX Ytilde oe.sc -40
+KPX Ytilde ocircumflexdotbelow.sc -30
+KPX Ytilde gcaron.sc -30
+KPX Ytilde gacute.sc -45
+KPX Ytilde ahookabove.sc -30
+KPX Ytilde acircumflexdotbelow.sc -30
+KPX Ytilde abrevedotbelow.sc -30
+KPX Ytilde uhorndotbelow -40
+KPX Ytilde uhorntilde -40
+KPX Ytilde uhornhookabove -40
+KPX Ytilde uhorngrave -40
+KPX Ytilde uhornacute -40
+KPX Ytilde uhookabove -40
+KPX Ytilde ohorndotbelow -50
+KPX Ytilde ohorntilde -50
+KPX Ytilde ohornhookabove -50
+KPX Ytilde ohorngrave -50
+KPX Ytilde ohornacute -50
+KPX Ytilde ocircumflexdotbelow -50
+KPX Ytilde ohookabove -50
+KPX Ytilde ecircumflexdotbelow -45
+KPX Ytilde etilde -45
+KPX Ytilde ehookabove -45
+KPX Ytilde abrevedotbelow -45
+KPX Ytilde acircumflexdotbelow -45
+KPX Ytilde ahookabove -45
+KPX Ytilde aeacute -75
+KPX Ytilde AEacute -115
+KPX Ytilde gacute -75
+KPX Ytilde gcaron -50
+KPX Ytilde uhungarumlaut -40
+KPX Ytilde uring -40
+KPX Ytilde ubreve -40
+KPX Ytilde umacron -40
+KPX Ytilde utilde -40
+KPX Ytilde oe -70
+KPX Ytilde OE -55
+KPX Ytilde ohungarumlaut -50
+KPX Ytilde obreve -50
+KPX Ytilde omacron -50
+KPX Ytilde gdotaccent -50
+KPX Ytilde gbreve -50
+KPX Ytilde gcircumflex -50
+KPX Ytilde ecaron -45
+KPX Ytilde edotaccent -45
+KPX Ytilde ebreve -45
+KPX Ytilde emacron -45
+KPX Ytilde abreve -45
+KPX Ytilde amacron -45
+KPX Ytilde udieresis -40
+KPX Ytilde ucircumflex -40
+KPX Ytilde uacute -60
+KPX Ytilde ugrave -40
+KPX Ytilde odieresis -50
+KPX Ytilde otilde -50
+KPX Ytilde ocircumflex -50
+KPX Ytilde oacute -70
+KPX Ytilde ograve -50
+KPX Ytilde iacute -10
+KPX Ytilde edieresis -45
+KPX Ytilde ecircumflex -45
+KPX Ytilde eacute -70
+KPX Ytilde egrave -45
+KPX Ytilde ae -75
+KPX Ytilde aring -45
+KPX Ytilde adieresis -45
+KPX Ytilde atilde -45
+KPX Ytilde acircumflex -45
+KPX Ytilde aacute -65
+KPX Ytilde agrave -45
+KPX Ytilde AE -115
+KPX Ytilde i -25
+KPX ytilde aeacute -30
+KPX ytilde oe -40
+KPX ytilde ae -30
+KPX quoteleft ae.sc -130
+KPX quoteleft aring.sc -130
+KPX quoteleft adieresis.sc -130
+KPX quoteleft t.sc -10
+KPX quoteleft a.sc -130
+KPX quoteleft uni021B.sc -10
+KPX quoteleft tcaron.sc -10
+KPX quoteleft aeacute.sc -130
+KPX quoteleft aogonek.sc -130
+KPX quoteleft amacron.sc -130
+KPX quoteleft quoteleft -35
+KPX quoteleft uni021A -10
+KPX quoteleft AEacute -130
+KPX quoteleft Tcaron -10
+KPX quoteleft Aogonek -130
+KPX quoteleft Amacron -130
+KPX quoteleft AE -130
+KPX quoteleft Aring -130
+KPX quoteleft Adieresis -130
+KPX quoteleft T -10
+KPX quoteleft A -130
+KPX quoteleft T_h -10
+KPX quoteright ae.sc -130
+KPX quoteright aring.sc -125
+KPX quoteright adieresis.sc -125
+KPX quoteright a.sc -125
+KPX quoteright aeacute.sc -130
+KPX quoteright aogonek.sc -125
+KPX quoteright amacron.sc -125
+KPX quoteright wdieresis -20
+KPX quoteright wacute -20
+KPX quoteright wgrave -20
+KPX quoteright rdotaccent -30
+KPX quoteright uni021B -30
+KPX quoteright uni0219 -25
+KPX quoteright AEacute -130
+KPX quoteright oogonek -45
+KPX quoteright ycircumflex -25
+KPX quoteright wcircumflex -20
+KPX quoteright tcaron -30
+KPX quoteright scaron -25
+KPX quoteright scedilla -25
+KPX quoteright scircumflex -25
+KPX quoteright sacute -25
+KPX quoteright rcaron -30
+KPX quoteright rcommaaccent -30
+KPX quoteright racute -30
+KPX quoteright ohungarumlaut -45
+KPX quoteright obreve -45
+KPX quoteright omacron -45
+KPX quoteright dcaron -60
+KPX quoteright Aogonek -125
+KPX quoteright Amacron -125
+KPX quoteright ydieresis -25
+KPX quoteright oslash -45
+KPX quoteright odieresis -45
+KPX quoteright AE -130
+KPX quoteright Aring -125
+KPX quoteright Adieresis -125
+KPX quoteright y -25
+KPX quoteright w -20
+KPX quoteright v -20
+KPX quoteright t -30
+KPX quoteright s -25
+KPX quoteright r -30
+KPX quoteright o -45
+KPX quoteright d -60
+KPX quoteright A -125
+KPX quoteright period -65
+KPX quoteright comma -80
+KPX quotedblleft ae.sc -135
+KPX quotedblleft aring.sc -130
+KPX quotedblleft adieresis.sc -130
+KPX quotedblleft t.sc -15
+KPX quotedblleft a.sc -130
+KPX quotedblleft uni021B.sc -15
+KPX quotedblleft tcaron.sc -15
+KPX quotedblleft aeacute.sc -135
+KPX quotedblleft aogonek.sc -130
+KPX quotedblleft amacron.sc -130
+KPX quotedblleft uni021A -15
+KPX quotedblleft AEacute -135
+KPX quotedblleft Tcaron -15
+KPX quotedblleft Aogonek -130
+KPX quotedblleft Amacron -130
+KPX quotedblleft AE -135
+KPX quotedblleft Aring -130
+KPX quotedblleft Adieresis -130
+KPX quotedblleft T -15
+KPX quotedblleft A -130
+KPX quotedblleft T_h -15
+KPX quotedblright ae.sc -135
+KPX quotedblright aring.sc -130
+KPX quotedblright adieresis.sc -130
+KPX quotedblright t.sc -15
+KPX quotedblright a.sc -130
+KPX quotedblright uni021B.sc -15
+KPX quotedblright tcaron.sc -15
+KPX quotedblright aeacute.sc -135
+KPX quotedblright aogonek.sc -130
+KPX quotedblright amacron.sc -130
+KPX quotedblright uni021A -15
+KPX quotedblright AEacute -135
+KPX quotedblright Tcaron -15
+KPX quotedblright Aogonek -130
+KPX quotedblright Amacron -130
+KPX quotedblright AE -135
+KPX quotedblright Aring -130
+KPX quotedblright Adieresis -130
+KPX quotedblright T -15
+KPX quotedblright A -130
+KPX quotedblright T_h -15
+KPX quotedblbase ydieresis.sc -110
+KPX quotedblbase aring.sc -15
+KPX quotedblbase adieresis.sc -15
+KPX quotedblbase y.sc -110
+KPX quotedblbase w.sc -65
+KPX quotedblbase v.sc -110
+KPX quotedblbase t.sc -90
+KPX quotedblbase a.sc -15
+KPX quotedblbase ycircumflex.sc -110
+KPX quotedblbase wgrave.sc -65
+KPX quotedblbase wdieresis.sc -65
+KPX quotedblbase wcircumflex.sc -65
+KPX quotedblbase wacute.sc -65
+KPX quotedblbase uni021B.sc -90
+KPX quotedblbase tcaron.sc -90
+KPX quotedblbase aogonek.sc -15
+KPX quotedblbase amacron.sc -15
+KPX quotedblbase Wdieresis -65
+KPX quotedblbase Wacute -65
+KPX quotedblbase Wgrave -65
+KPX quotedblbase uni021A -90
+KPX quotedblbase Ydieresis -110
+KPX quotedblbase Ycircumflex -110
+KPX quotedblbase Wcircumflex -65
+KPX quotedblbase Tcaron -90
+KPX quotedblbase Aogonek -15
+KPX quotedblbase Amacron -15
+KPX quotedblbase Aring -15
+KPX quotedblbase Adieresis -15
+KPX quotedblbase Y -110
+KPX quotedblbase W -65
+KPX quotedblbase V -110
+KPX quotedblbase T -90
+KPX quotedblbase A -15
+KPX quotedblbase T_h -90
+KPX guilsinglright Wdieresis -90
+KPX guilsinglright Wacute -90
+KPX guilsinglright Wgrave -90
+KPX guilsinglright uni021A -135
+KPX guilsinglright AEacute -85
+KPX guilsinglright Ydieresis -145
+KPX guilsinglright Ycircumflex -145
+KPX guilsinglright Wcircumflex -90
+KPX guilsinglright Tcaron -135
+KPX guilsinglright Aogonek -95
+KPX guilsinglright Amacron -95
+KPX guilsinglright AE -85
+KPX guilsinglright Aring -95
+KPX guilsinglright Adieresis -95
+KPX guilsinglright Y -145
+KPX guilsinglright W -90
+KPX guilsinglright V -120
+KPX guilsinglright T -135
+KPX guilsinglright A -95
+KPX guilsinglright T_h -135
+KPX abreveacute.sc t.sc -45
+KPX abreveacute.sc c.sc -45
+KPX abrevedotbelow.sc t.sc -45
+KPX abrevedotbelow.sc c.sc -45
+KPX acircumflexacute.sc y.sc -60
+KPX acircumflexacute.sc u.sc -50
+KPX acircumflexacute.sc t.sc -45
+KPX acircumflexacute.sc c.sc -45
+KPX acircumflexdotbelow.sc y.sc -60
+KPX acircumflexdotbelow.sc u.sc -50
+KPX acircumflexdotbelow.sc t.sc -45
+KPX acircumflexdotbelow.sc c.sc -45
+KPX acircumflexgrave.sc y.sc -60
+KPX acircumflexgrave.sc u.sc -50
+KPX acircumflexhookabove.sc y.sc -60
+KPX acircumflexhookabove.sc u.sc -50
+KPX acircumflextilde.sc y.sc -60
+KPX acircumflextilde.sc u.sc -50
+KPX adotbelow.sc y.sc -60
+KPX adotbelow.sc u.sc -50
+KPX adotbelow.sc t.sc -45
+KPX adotbelow.sc o.sc -45
+KPX adotbelow.sc c.sc -45
+KPX ahookabove.sc y.sc -60
+KPX ahookabove.sc u.sc -50
+KPX ahookabove.sc o.sc -45
+KPX dcroat.sc atilde.sc -55
+KPX dcroat.sc acircumflex.sc -55
+KPX dcroat.sc aacute.sc -55
+KPX dcroat.sc agrave.sc -55
+KPX dcroat.sc a.sc -55
+KPX dcroat.sc abreve.sc -55
+KPX dcroat.sc ahookabove.sc -55
+KPX dcroat.sc adotbelow.sc -55
+KPX dcroat.sc acircumflextilde.sc -55
+KPX dcroat.sc acircumflexhookabove.sc -55
+KPX dcroat.sc acircumflexgrave.sc -55
+KPX dcroat.sc acircumflexdotbelow.sc -55
+KPX dcroat.sc acircumflexacute.sc -55
+KPX dcroat.sc abrevetilde.sc -55
+KPX dcroat.sc abrevehookabove.sc -55
+KPX dcroat.sc abrevegrave.sc -55
+KPX dcroat.sc abrevedotbelow.sc -55
+KPX dcroat.sc abreveacute.sc -55
+KPX gacute.sc ydieresis.sc -15
+KPX gacute.sc aring.sc -15
+KPX gacute.sc adieresis.sc -15
+KPX gacute.sc y.sc -15
+KPX gacute.sc w.sc -10
+KPX gacute.sc v.sc -10
+KPX gacute.sc t.sc -15
+KPX gacute.sc a.sc -15
+KPX gacute.sc ycircumflex.sc -15
+KPX gacute.sc wgrave.sc -10
+KPX gacute.sc wdieresis.sc -10
+KPX gacute.sc wcircumflex.sc -10
+KPX gacute.sc wacute.sc -10
+KPX gacute.sc uni021B.sc -15
+KPX gacute.sc tcaron.sc -15
+KPX gacute.sc aogonek.sc -15
+KPX gacute.sc amacron.sc -15
+KPX gcaron.sc ydieresis.sc -15
+KPX gcaron.sc aring.sc -15
+KPX gcaron.sc adieresis.sc -15
+KPX gcaron.sc y.sc -15
+KPX gcaron.sc w.sc -10
+KPX gcaron.sc v.sc -10
+KPX gcaron.sc t.sc -15
+KPX gcaron.sc a.sc -15
+KPX gcaron.sc ycircumflex.sc -15
+KPX gcaron.sc wgrave.sc -10
+KPX gcaron.sc wdieresis.sc -10
+KPX gcaron.sc wcircumflex.sc -10
+KPX gcaron.sc wacute.sc -10
+KPX gcaron.sc uni021B.sc -15
+KPX gcaron.sc tcaron.sc -15
+KPX gcaron.sc aogonek.sc -15
+KPX gcaron.sc amacron.sc -15
+KPX jacute.sc ae.sc -25
+KPX jacute.sc aring.sc -35
+KPX jacute.sc adieresis.sc -35
+KPX jacute.sc a.sc -35
+KPX jacute.sc aeacute.sc -25
+KPX jacute.sc aogonek.sc -35
+KPX jacute.sc amacron.sc -35
+KPX lslash.sc ydieresis.sc -55
+KPX lslash.sc yacute.sc -55
+KPX lslash.sc udieresis.sc -25
+KPX lslash.sc ucircumflex.sc -25
+KPX lslash.sc uacute.sc -25
+KPX lslash.sc ugrave.sc -25
+KPX lslash.sc oslash.sc -15
+KPX lslash.sc odieresis.sc -15
+KPX lslash.sc ccedilla.sc -15
+KPX lslash.sc y.sc -55
+KPX lslash.sc w.sc -45
+KPX lslash.sc v.sc -65
+KPX lslash.sc u.sc -25
+KPX lslash.sc t.sc -45
+KPX lslash.sc o.sc -15
+KPX lslash.sc g.sc -15
+KPX lslash.sc c.sc -15
+KPX lslash.sc ygrave.sc -55
+KPX lslash.sc ycircumflex.sc -55
+KPX lslash.sc wgrave.sc -45
+KPX lslash.sc wdieresis.sc -45
+KPX lslash.sc wcircumflex.sc -45
+KPX lslash.sc wacute.sc -45
+KPX lslash.sc utilde.sc -25
+KPX lslash.sc uring.sc -25
+KPX lslash.sc uogonek.sc -25
+KPX lslash.sc umacron.sc -25
+KPX lslash.sc uhungarumlaut.sc -25
+KPX lslash.sc ubreve.sc -25
+KPX lslash.sc uni021B.sc -45
+KPX lslash.sc tcaron.sc -45
+KPX lslash.sc omacron.sc -15
+KPX lslash.sc ohungarumlaut.sc -15
+KPX lslash.sc obreve.sc -15
+KPX lslash.sc gdotaccent.sc -15
+KPX lslash.sc gcommaaccent.sc -15
+KPX lslash.sc gcircumflex.sc -15
+KPX lslash.sc gbreve.sc -15
+KPX lslash.sc cdotaccent.sc -15
+KPX lslash.sc ccircumflex.sc -15
+KPX lslash.sc ccaron.sc -15
+KPX lslash.sc cacute.sc -15
+KPX lslash.sc ytilde.sc -55
+KPX lslash.sc yhookabove.sc -55
+KPX lslash.sc ydotbelow.sc -55
+KPX lslash.sc uhorntilde.sc -25
+KPX lslash.sc uhornhookabove.sc -25
+KPX lslash.sc uhorngrave.sc -25
+KPX lslash.sc uhorndotbelow.sc -25
+KPX lslash.sc uhornacute.sc -25
+KPX lslash.sc uhookabove.sc -25
+KPX lslash.sc udotbelow.sc -25
+KPX lslash.sc oogonek.sc -15
+KPX lslash.sc gcaron.sc -15
+KPX lslash.sc gacute.sc -15
+KPX lslash.sc quotedblright -130
+KPX lslash.sc quoteright -125
+KPX ocircumflexacute.sc t.sc -10
+KPX ocircumflexdotbelow.sc t.sc -10
+KPX odotbelow.sc t.sc -10
+KPX odotbelow.sc a.sc -50
+KPX ohookabove.sc a.sc -50
+KPX ohornacute.sc t.sc -10
+KPX ohorndotbelow.sc t.sc -10
+KPX oogonek.sc ydieresis.sc -35
+KPX oogonek.sc ae.sc -45
+KPX oogonek.sc aring.sc -50
+KPX oogonek.sc adieresis.sc -50
+KPX oogonek.sc y.sc -35
+KPX oogonek.sc x.sc -40
+KPX oogonek.sc w.sc -30
+KPX oogonek.sc v.sc -35
+KPX oogonek.sc t.sc -10
+KPX oogonek.sc a.sc -50
+KPX oogonek.sc ycircumflex.sc -35
+KPX oogonek.sc wgrave.sc -30
+KPX oogonek.sc wdieresis.sc -30
+KPX oogonek.sc wcircumflex.sc -30
+KPX oogonek.sc wacute.sc -30
+KPX oogonek.sc uni021B.sc -10
+KPX oogonek.sc tcaron.sc -10
+KPX oogonek.sc aeacute.sc -45
+KPX oogonek.sc aogonek.sc -50
+KPX oogonek.sc amacron.sc -50
+KPX rdotaccent.sc ydieresis.sc -35
+KPX rdotaccent.sc udieresis.sc -35
+KPX rdotaccent.sc ucircumflex.sc -35
+KPX rdotaccent.sc oslash.sc -25
+KPX rdotaccent.sc odieresis.sc -25
+KPX rdotaccent.sc ccedilla.sc -25
+KPX rdotaccent.sc y.sc -35
+KPX rdotaccent.sc w.sc -35
+KPX rdotaccent.sc v.sc -35
+KPX rdotaccent.sc u.sc -35
+KPX rdotaccent.sc t.sc -25
+KPX rdotaccent.sc o.sc -25
+KPX rdotaccent.sc g.sc -25
+KPX rdotaccent.sc c.sc -25
+KPX rdotaccent.sc ycircumflex.sc -35
+KPX rdotaccent.sc wgrave.sc -35
+KPX rdotaccent.sc wdieresis.sc -35
+KPX rdotaccent.sc wcircumflex.sc -35
+KPX rdotaccent.sc wacute.sc -35
+KPX rdotaccent.sc uring.sc -35
+KPX rdotaccent.sc uogonek.sc -35
+KPX rdotaccent.sc umacron.sc -35
+KPX rdotaccent.sc uhungarumlaut.sc -35
+KPX rdotaccent.sc ubreve.sc -35
+KPX rdotaccent.sc uni021B.sc -25
+KPX rdotaccent.sc tcaron.sc -25
+KPX rdotaccent.sc omacron.sc -25
+KPX rdotaccent.sc ohungarumlaut.sc -25
+KPX rdotaccent.sc obreve.sc -25
+KPX rdotaccent.sc gdotaccent.sc -25
+KPX rdotaccent.sc gcommaaccent.sc -25
+KPX rdotaccent.sc gcircumflex.sc -25
+KPX rdotaccent.sc gbreve.sc -25
+KPX rdotaccent.sc cdotaccent.sc -25
+KPX rdotaccent.sc ccircumflex.sc -25
+KPX rdotaccent.sc ccaron.sc -25
+KPX rdotaccent.sc cacute.sc -25
+KPX rdotaccent.sc oogonek.sc -25
+KPX rdotaccent.sc oe.sc -25
+KPX rdotaccent.sc gcaron.sc -25
+KPX rdotaccent.sc gacute.sc -25
+KPX rdotaccent.sc hyphen -50
+KPX scaron.sc ydieresis.sc -10
+KPX scaron.sc ae.sc -20
+KPX scaron.sc aring.sc -25
+KPX scaron.sc adieresis.sc -25
+KPX scaron.sc y.sc -10
+KPX scaron.sc w.sc -10
+KPX scaron.sc v.sc -10
+KPX scaron.sc t.sc -15
+KPX scaron.sc a.sc -25
+KPX scaron.sc ycircumflex.sc -10
+KPX scaron.sc wgrave.sc -10
+KPX scaron.sc wdieresis.sc -10
+KPX scaron.sc wcircumflex.sc -10
+KPX scaron.sc wacute.sc -10
+KPX scaron.sc uni021B.sc -15
+KPX scaron.sc tcaron.sc -15
+KPX scaron.sc aeacute.sc -20
+KPX scaron.sc aogonek.sc -25
+KPX scaron.sc amacron.sc -25
+KPX udotbelow.sc a.sc -55
+KPX uhookabove.sc a.sc -55
+KPX uhorn.sc a.sc -55
+KPX uhornacute.sc a.sc -55
+KPX uhorndotbelow.sc a.sc -55
+KPX uhorngrave.sc a.sc -55
+KPX uhornhookabove.sc a.sc -55
+KPX uhorntilde.sc a.sc -55
+KPX ydotbelow.sc c.sc -45
+KPX f_k ecircumflexdotbelow -10
+KPX f_k ecircumflexhookabove -10
+KPX f_k ecircumflexgrave -10
+KPX f_k ecircumflexacute -10
+KPX f_k etilde -10
+KPX f_k ehookabove -10
+KPX f_k edotbelow -10
+KPX f_k uni0219 10
+KPX f_k gacute -10
+KPX f_k oogonek -20
+KPX f_k gcaron -10
+KPX f_k scaron 10
+KPX f_k scedilla 10
+KPX f_k scircumflex 10
+KPX f_k sacute 10
+KPX f_k ohungarumlaut -20
+KPX f_k obreve -20
+KPX f_k omacron -20
+KPX f_k gcommaaccent -10
+KPX f_k gdotaccent -10
+KPX f_k gbreve -10
+KPX f_k gcircumflex -10
+KPX f_k ecaron -10
+KPX f_k eogonek -10
+KPX f_k edotaccent -10
+KPX f_k ebreve -10
+KPX f_k emacron -10
+KPX f_k oslash -20
+KPX f_k odieresis -20
+KPX f_k edieresis -10
+KPX f_k ecircumflex -10
+KPX f_k eacute -10
+KPX f_k egrave -10
+KPX f_k s 10
+KPX f_k o -20
+KPX f_k g -10
+KPX f_k e -10
+KPX f_k W -35
+KPX f_k V -45
+KPX f_k hyphen -65
+KPX f_k comma -20
+KPX hyphen.prop one.prop -20
+KPX hyphen.prop seven.prop -30
+KPX hyphen.prop two.prop -10
+KPX Jacute ae.sc -30
+KPX Jacute aring.sc -40
+KPX Jacute adieresis.sc -40
+KPX Jacute a.sc -40
+KPX Jacute aeacute.sc -30
+KPX Jacute aogonek.sc -40
+KPX Jacute amacron.sc -40
+KPX Jacute AEacute -35
+KPX Jacute Aogonek -50
+KPX Jacute Amacron -50
+KPX Jacute AE -35
+KPX Jacute Aring -50
+KPX Jacute Adieresis -50
+KPX Jacute A -50
+KPX seven.prop six.prop -10
+KPX seven.prop four.prop -20
+KPX seven.prop hyphen.prop -20
+KPX amacron.sc ydieresis.sc -60
+KPX amacron.sc udieresis.sc -50
+KPX amacron.sc ucircumflex.sc -50
+KPX amacron.sc oslash.sc -45
+KPX amacron.sc odieresis.sc -45
+KPX amacron.sc ccedilla.sc -45
+KPX amacron.sc y.sc -60
+KPX amacron.sc w.sc -65
+KPX amacron.sc v.sc -95
+KPX amacron.sc u.sc -50
+KPX amacron.sc t.sc -45
+KPX amacron.sc q.sc -45
+KPX amacron.sc o.sc -45
+KPX amacron.sc g.sc -45
+KPX amacron.sc c.sc -45
+KPX amacron.sc ycircumflex.sc -60
+KPX amacron.sc wgrave.sc -65
+KPX amacron.sc wdieresis.sc -65
+KPX amacron.sc wcircumflex.sc -65
+KPX amacron.sc wacute.sc -65
+KPX amacron.sc uring.sc -50
+KPX amacron.sc uogonek.sc -50
+KPX amacron.sc umacron.sc -50
+KPX amacron.sc uhungarumlaut.sc -50
+KPX amacron.sc ubreve.sc -50
+KPX amacron.sc uni021B.sc -45
+KPX amacron.sc tcaron.sc -45
+KPX amacron.sc omacron.sc -45
+KPX amacron.sc ohungarumlaut.sc -45
+KPX amacron.sc obreve.sc -45
+KPX amacron.sc gdotaccent.sc -45
+KPX amacron.sc gcommaaccent.sc -45
+KPX amacron.sc gcircumflex.sc -45
+KPX amacron.sc gbreve.sc -45
+KPX amacron.sc cdotaccent.sc -45
+KPX amacron.sc ccircumflex.sc -45
+KPX amacron.sc ccaron.sc -45
+KPX amacron.sc cacute.sc -45
+KPX amacron.sc oogonek.sc -45
+KPX amacron.sc gcaron.sc -45
+KPX amacron.sc gacute.sc -45
+KPX amacron.sc quotedblright -125
+KPX amacron.sc quoteright -120
+KPX amacron.sc period -25
+KPX amacron.sc hyphen -35
+KPX amacron.sc comma -35
+KPX aogonek.sc ydieresis.sc -60
+KPX aogonek.sc udieresis.sc -50
+KPX aogonek.sc ucircumflex.sc -50
+KPX aogonek.sc oslash.sc -45
+KPX aogonek.sc odieresis.sc -45
+KPX aogonek.sc ccedilla.sc -45
+KPX aogonek.sc y.sc -60
+KPX aogonek.sc w.sc -65
+KPX aogonek.sc v.sc -95
+KPX aogonek.sc u.sc -50
+KPX aogonek.sc t.sc -45
+KPX aogonek.sc q.sc -45
+KPX aogonek.sc o.sc -45
+KPX aogonek.sc g.sc -45
+KPX aogonek.sc c.sc -45
+KPX aogonek.sc ycircumflex.sc -60
+KPX aogonek.sc wgrave.sc -65
+KPX aogonek.sc wdieresis.sc -65
+KPX aogonek.sc wcircumflex.sc -65
+KPX aogonek.sc wacute.sc -65
+KPX aogonek.sc uring.sc -50
+KPX aogonek.sc uogonek.sc -50
+KPX aogonek.sc umacron.sc -50
+KPX aogonek.sc uhungarumlaut.sc -50
+KPX aogonek.sc ubreve.sc -50
+KPX aogonek.sc uni021B.sc -45
+KPX aogonek.sc tcaron.sc -45
+KPX aogonek.sc omacron.sc -45
+KPX aogonek.sc ohungarumlaut.sc -45
+KPX aogonek.sc obreve.sc -45
+KPX aogonek.sc gdotaccent.sc -45
+KPX aogonek.sc gcommaaccent.sc -45
+KPX aogonek.sc gcircumflex.sc -45
+KPX aogonek.sc gbreve.sc -45
+KPX aogonek.sc cdotaccent.sc -45
+KPX aogonek.sc ccircumflex.sc -45
+KPX aogonek.sc ccaron.sc -45
+KPX aogonek.sc cacute.sc -45
+KPX aogonek.sc oogonek.sc -45
+KPX aogonek.sc gcaron.sc -45
+KPX aogonek.sc gacute.sc -45
+KPX aogonek.sc quotedblright -125
+KPX aogonek.sc quoteright -120
+KPX aogonek.sc period -25
+KPX aogonek.sc hyphen -35
+KPX aogonek.sc comma -35
+KPX cacute.sc oslash.sc -25
+KPX cacute.sc odieresis.sc -25
+KPX cacute.sc aring.sc -10
+KPX cacute.sc adieresis.sc -10
+KPX cacute.sc o.sc -25
+KPX cacute.sc k.sc -5
+KPX cacute.sc h.sc -5
+KPX cacute.sc a.sc -10
+KPX cacute.sc omacron.sc -25
+KPX cacute.sc ohungarumlaut.sc -25
+KPX cacute.sc obreve.sc -25
+KPX cacute.sc kcommaaccent.sc -5
+KPX cacute.sc hcircumflex.sc -5
+KPX cacute.sc aogonek.sc -10
+KPX cacute.sc amacron.sc -10
+KPX cacute.sc oogonek.sc -25
+KPX ccaron.sc oslash.sc -25
+KPX ccaron.sc odieresis.sc -25
+KPX ccaron.sc aring.sc -10
+KPX ccaron.sc adieresis.sc -10
+KPX ccaron.sc o.sc -25
+KPX ccaron.sc k.sc -5
+KPX ccaron.sc h.sc -5
+KPX ccaron.sc a.sc -10
+KPX ccaron.sc omacron.sc -25
+KPX ccaron.sc ohungarumlaut.sc -25
+KPX ccaron.sc obreve.sc -25
+KPX ccaron.sc kcommaaccent.sc -5
+KPX ccaron.sc hcircumflex.sc -5
+KPX ccaron.sc aogonek.sc -10
+KPX ccaron.sc amacron.sc -10
+KPX ccaron.sc oogonek.sc -25
+KPX ccircumflex.sc oslash.sc -25
+KPX ccircumflex.sc odieresis.sc -25
+KPX ccircumflex.sc aring.sc -10
+KPX ccircumflex.sc adieresis.sc -10
+KPX ccircumflex.sc o.sc -25
+KPX ccircumflex.sc k.sc -5
+KPX ccircumflex.sc h.sc -5
+KPX ccircumflex.sc a.sc -10
+KPX ccircumflex.sc omacron.sc -25
+KPX ccircumflex.sc ohungarumlaut.sc -25
+KPX ccircumflex.sc obreve.sc -25
+KPX ccircumflex.sc kcommaaccent.sc -5
+KPX ccircumflex.sc hcircumflex.sc -5
+KPX ccircumflex.sc aogonek.sc -10
+KPX ccircumflex.sc amacron.sc -10
+KPX ccircumflex.sc oogonek.sc -25
+KPX cdotaccent.sc oslash.sc -25
+KPX cdotaccent.sc odieresis.sc -25
+KPX cdotaccent.sc aring.sc -10
+KPX cdotaccent.sc adieresis.sc -10
+KPX cdotaccent.sc o.sc -25
+KPX cdotaccent.sc k.sc -5
+KPX cdotaccent.sc h.sc -5
+KPX cdotaccent.sc a.sc -10
+KPX cdotaccent.sc omacron.sc -25
+KPX cdotaccent.sc ohungarumlaut.sc -25
+KPX cdotaccent.sc obreve.sc -25
+KPX cdotaccent.sc kcommaaccent.sc -5
+KPX cdotaccent.sc hcircumflex.sc -5
+KPX cdotaccent.sc aogonek.sc -10
+KPX cdotaccent.sc amacron.sc -10
+KPX cdotaccent.sc oogonek.sc -25
+KPX dcaron.sc ydieresis.sc -35
+KPX dcaron.sc aring.sc -55
+KPX dcaron.sc adieresis.sc -55
+KPX dcaron.sc y.sc -35
+KPX dcaron.sc x.sc -40
+KPX dcaron.sc w.sc -30
+KPX dcaron.sc v.sc -40
+KPX dcaron.sc t.sc -10
+KPX dcaron.sc j.sc -20
+KPX dcaron.sc a.sc -55
+KPX dcaron.sc ycircumflex.sc -35
+KPX dcaron.sc wgrave.sc -30
+KPX dcaron.sc wdieresis.sc -30
+KPX dcaron.sc wcircumflex.sc -30
+KPX dcaron.sc wacute.sc -30
+KPX dcaron.sc uni021B.sc -10
+KPX dcaron.sc tcaron.sc -10
+KPX dcaron.sc jcircumflex.sc -20
+KPX dcaron.sc aogonek.sc -55
+KPX dcaron.sc amacron.sc -55
+KPX dcaron.sc jacute.sc -20
+KPX gbreve.sc ydieresis.sc -15
+KPX gbreve.sc aring.sc -15
+KPX gbreve.sc adieresis.sc -15
+KPX gbreve.sc y.sc -15
+KPX gbreve.sc w.sc -10
+KPX gbreve.sc v.sc -10
+KPX gbreve.sc t.sc -15
+KPX gbreve.sc a.sc -15
+KPX gbreve.sc ycircumflex.sc -15
+KPX gbreve.sc wgrave.sc -10
+KPX gbreve.sc wdieresis.sc -10
+KPX gbreve.sc wcircumflex.sc -10
+KPX gbreve.sc wacute.sc -10
+KPX gbreve.sc uni021B.sc -15
+KPX gbreve.sc tcaron.sc -15
+KPX gbreve.sc aogonek.sc -15
+KPX gbreve.sc amacron.sc -15
+KPX gcircumflex.sc ydieresis.sc -15
+KPX gcircumflex.sc aring.sc -15
+KPX gcircumflex.sc adieresis.sc -15
+KPX gcircumflex.sc y.sc -15
+KPX gcircumflex.sc w.sc -10
+KPX gcircumflex.sc v.sc -10
+KPX gcircumflex.sc t.sc -15
+KPX gcircumflex.sc a.sc -15
+KPX gcircumflex.sc ycircumflex.sc -15
+KPX gcircumflex.sc wgrave.sc -10
+KPX gcircumflex.sc wdieresis.sc -10
+KPX gcircumflex.sc wcircumflex.sc -10
+KPX gcircumflex.sc wacute.sc -10
+KPX gcircumflex.sc uni021B.sc -15
+KPX gcircumflex.sc tcaron.sc -15
+KPX gcircumflex.sc aogonek.sc -15
+KPX gcircumflex.sc amacron.sc -15
+KPX gcommaaccent.sc ydieresis.sc -15
+KPX gcommaaccent.sc aring.sc -15
+KPX gcommaaccent.sc adieresis.sc -15
+KPX gcommaaccent.sc y.sc -15
+KPX gcommaaccent.sc w.sc -10
+KPX gcommaaccent.sc v.sc -10
+KPX gcommaaccent.sc t.sc -15
+KPX gcommaaccent.sc a.sc -15
+KPX gcommaaccent.sc ycircumflex.sc -15
+KPX gcommaaccent.sc wgrave.sc -10
+KPX gcommaaccent.sc wdieresis.sc -10
+KPX gcommaaccent.sc wcircumflex.sc -10
+KPX gcommaaccent.sc wacute.sc -10
+KPX gcommaaccent.sc uni021B.sc -15
+KPX gcommaaccent.sc tcaron.sc -15
+KPX gcommaaccent.sc aogonek.sc -15
+KPX gcommaaccent.sc amacron.sc -15
+KPX gdotaccent.sc ydieresis.sc -15
+KPX gdotaccent.sc aring.sc -15
+KPX gdotaccent.sc adieresis.sc -15
+KPX gdotaccent.sc y.sc -15
+KPX gdotaccent.sc w.sc -10
+KPX gdotaccent.sc v.sc -10
+KPX gdotaccent.sc t.sc -15
+KPX gdotaccent.sc a.sc -15
+KPX gdotaccent.sc ycircumflex.sc -15
+KPX gdotaccent.sc wgrave.sc -10
+KPX gdotaccent.sc wdieresis.sc -10
+KPX gdotaccent.sc wcircumflex.sc -10
+KPX gdotaccent.sc wacute.sc -10
+KPX gdotaccent.sc uni021B.sc -15
+KPX gdotaccent.sc tcaron.sc -15
+KPX gdotaccent.sc aogonek.sc -15
+KPX gdotaccent.sc amacron.sc -15
+KPX jcircumflex.sc ae.sc -25
+KPX jcircumflex.sc aring.sc -35
+KPX jcircumflex.sc adieresis.sc -35
+KPX jcircumflex.sc a.sc -35
+KPX jcircumflex.sc aeacute.sc -25
+KPX jcircumflex.sc aogonek.sc -35
+KPX jcircumflex.sc amacron.sc -35
+KPX kcommaaccent.sc oslash.sc -40
+KPX kcommaaccent.sc odieresis.sc -40
+KPX kcommaaccent.sc ccedilla.sc -45
+KPX kcommaaccent.sc o.sc -40
+KPX kcommaaccent.sc g.sc -45
+KPX kcommaaccent.sc c.sc -45
+KPX kcommaaccent.sc omacron.sc -40
+KPX kcommaaccent.sc ohungarumlaut.sc -40
+KPX kcommaaccent.sc obreve.sc -40
+KPX kcommaaccent.sc gdotaccent.sc -45
+KPX kcommaaccent.sc gcommaaccent.sc -45
+KPX kcommaaccent.sc gcircumflex.sc -45
+KPX kcommaaccent.sc gbreve.sc -45
+KPX kcommaaccent.sc cdotaccent.sc -45
+KPX kcommaaccent.sc ccircumflex.sc -45
+KPX kcommaaccent.sc ccaron.sc -45
+KPX kcommaaccent.sc cacute.sc -45
+KPX kcommaaccent.sc oogonek.sc -40
+KPX kcommaaccent.sc oe.sc -40
+KPX kcommaaccent.sc gcaron.sc -45
+KPX kcommaaccent.sc gacute.sc -45
+KPX kcommaaccent.sc hyphen -75
+KPX lacute.sc ydieresis.sc -65
+KPX lacute.sc udieresis.sc -30
+KPX lacute.sc ucircumflex.sc -30
+KPX lacute.sc oslash.sc -15
+KPX lacute.sc odieresis.sc -15
+KPX lacute.sc ccedilla.sc -15
+KPX lacute.sc y.sc -65
+KPX lacute.sc w.sc -55
+KPX lacute.sc v.sc -85
+KPX lacute.sc u.sc -30
+KPX lacute.sc t.sc -55
+KPX lacute.sc o.sc -15
+KPX lacute.sc g.sc -15
+KPX lacute.sc c.sc -15
+KPX lacute.sc ycircumflex.sc -65
+KPX lacute.sc wgrave.sc -55
+KPX lacute.sc wdieresis.sc -55
+KPX lacute.sc wcircumflex.sc -55
+KPX lacute.sc wacute.sc -55
+KPX lacute.sc uring.sc -30
+KPX lacute.sc uogonek.sc -30
+KPX lacute.sc umacron.sc -30
+KPX lacute.sc uhungarumlaut.sc -30
+KPX lacute.sc ubreve.sc -30
+KPX lacute.sc uni021B.sc -55
+KPX lacute.sc tcaron.sc -55
+KPX lacute.sc omacron.sc -15
+KPX lacute.sc ohungarumlaut.sc -15
+KPX lacute.sc obreve.sc -15
+KPX lacute.sc gdotaccent.sc -15
+KPX lacute.sc gcommaaccent.sc -15
+KPX lacute.sc gcircumflex.sc -15
+KPX lacute.sc gbreve.sc -15
+KPX lacute.sc cdotaccent.sc -15
+KPX lacute.sc ccircumflex.sc -15
+KPX lacute.sc ccaron.sc -15
+KPX lacute.sc cacute.sc -15
+KPX lacute.sc oogonek.sc -15
+KPX lacute.sc gcaron.sc -15
+KPX lacute.sc gacute.sc -15
+KPX lacute.sc quotedblright -130
+KPX lacute.sc quoteright -125
+KPX lcaron.sc ydieresis.sc -35
+KPX lcaron.sc yacute.sc -35
+KPX lcaron.sc udieresis.sc -15
+KPX lcaron.sc ucircumflex.sc -15
+KPX lcaron.sc uacute.sc -15
+KPX lcaron.sc ugrave.sc -15
+KPX lcaron.sc oslash.sc -15
+KPX lcaron.sc odieresis.sc -15
+KPX lcaron.sc ccedilla.sc -15
+KPX lcaron.sc y.sc -35
+KPX lcaron.sc w.sc -30
+KPX lcaron.sc v.sc -40
+KPX lcaron.sc u.sc -15
+KPX lcaron.sc t.sc -25
+KPX lcaron.sc o.sc -15
+KPX lcaron.sc g.sc -15
+KPX lcaron.sc c.sc -15
+KPX lcaron.sc ygrave.sc -35
+KPX lcaron.sc ycircumflex.sc -35
+KPX lcaron.sc wgrave.sc -30
+KPX lcaron.sc wdieresis.sc -30
+KPX lcaron.sc wcircumflex.sc -30
+KPX lcaron.sc wacute.sc -30
+KPX lcaron.sc utilde.sc -15
+KPX lcaron.sc uring.sc -15
+KPX lcaron.sc uogonek.sc -15
+KPX lcaron.sc umacron.sc -15
+KPX lcaron.sc uhungarumlaut.sc -15
+KPX lcaron.sc ubreve.sc -15
+KPX lcaron.sc uni021B.sc -25
+KPX lcaron.sc tcaron.sc -25
+KPX lcaron.sc omacron.sc -15
+KPX lcaron.sc ohungarumlaut.sc -15
+KPX lcaron.sc obreve.sc -15
+KPX lcaron.sc gdotaccent.sc -15
+KPX lcaron.sc gcommaaccent.sc -15
+KPX lcaron.sc gcircumflex.sc -15
+KPX lcaron.sc gbreve.sc -15
+KPX lcaron.sc cdotaccent.sc -15
+KPX lcaron.sc ccircumflex.sc -15
+KPX lcaron.sc ccaron.sc -15
+KPX lcaron.sc cacute.sc -15
+KPX lcaron.sc ytilde.sc -35
+KPX lcaron.sc yhookabove.sc -35
+KPX lcaron.sc ydotbelow.sc -35
+KPX lcaron.sc uhorntilde.sc -15
+KPX lcaron.sc uhornhookabove.sc -15
+KPX lcaron.sc uhorngrave.sc -15
+KPX lcaron.sc uhorndotbelow.sc -15
+KPX lcaron.sc uhornacute.sc -15
+KPX lcaron.sc uhookabove.sc -15
+KPX lcaron.sc udotbelow.sc -15
+KPX lcaron.sc oogonek.sc -15
+KPX lcaron.sc gcaron.sc -15
+KPX lcaron.sc gacute.sc -15
+KPX lcaron.sc quotedblright -130
+KPX lcaron.sc quoteright -125
+KPX lcommaaccent.sc ydieresis.sc -65
+KPX lcommaaccent.sc udieresis.sc -30
+KPX lcommaaccent.sc ucircumflex.sc -30
+KPX lcommaaccent.sc oslash.sc -15
+KPX lcommaaccent.sc odieresis.sc -15
+KPX lcommaaccent.sc ccedilla.sc -15
+KPX lcommaaccent.sc y.sc -65
+KPX lcommaaccent.sc w.sc -55
+KPX lcommaaccent.sc v.sc -85
+KPX lcommaaccent.sc u.sc -30
+KPX lcommaaccent.sc t.sc -55
+KPX lcommaaccent.sc o.sc -15
+KPX lcommaaccent.sc g.sc -15
+KPX lcommaaccent.sc c.sc -15
+KPX lcommaaccent.sc ycircumflex.sc -65
+KPX lcommaaccent.sc wgrave.sc -55
+KPX lcommaaccent.sc wdieresis.sc -55
+KPX lcommaaccent.sc wcircumflex.sc -55
+KPX lcommaaccent.sc wacute.sc -55
+KPX lcommaaccent.sc uring.sc -30
+KPX lcommaaccent.sc uogonek.sc -30
+KPX lcommaaccent.sc umacron.sc -30
+KPX lcommaaccent.sc uhungarumlaut.sc -30
+KPX lcommaaccent.sc ubreve.sc -30
+KPX lcommaaccent.sc uni021B.sc -55
+KPX lcommaaccent.sc tcaron.sc -55
+KPX lcommaaccent.sc omacron.sc -15
+KPX lcommaaccent.sc ohungarumlaut.sc -15
+KPX lcommaaccent.sc obreve.sc -15
+KPX lcommaaccent.sc gdotaccent.sc -15
+KPX lcommaaccent.sc gcommaaccent.sc -15
+KPX lcommaaccent.sc gcircumflex.sc -15
+KPX lcommaaccent.sc gbreve.sc -15
+KPX lcommaaccent.sc cdotaccent.sc -15
+KPX lcommaaccent.sc ccircumflex.sc -15
+KPX lcommaaccent.sc ccaron.sc -15
+KPX lcommaaccent.sc cacute.sc -15
+KPX lcommaaccent.sc oogonek.sc -15
+KPX lcommaaccent.sc gcaron.sc -15
+KPX lcommaaccent.sc gacute.sc -15
+KPX lcommaaccent.sc quotedblright -130
+KPX lcommaaccent.sc quoteright -125
+KPX nacute.sc oslash.sc -15
+KPX nacute.sc odieresis.sc -15
+KPX nacute.sc ccedilla.sc -20
+KPX nacute.sc ae.sc -20
+KPX nacute.sc aring.sc -25
+KPX nacute.sc adieresis.sc -25
+KPX nacute.sc o.sc -15
+KPX nacute.sc g.sc -20
+KPX nacute.sc c.sc -20
+KPX nacute.sc a.sc -25
+KPX nacute.sc omacron.sc -15
+KPX nacute.sc ohungarumlaut.sc -15
+KPX nacute.sc obreve.sc -15
+KPX nacute.sc gdotaccent.sc -20
+KPX nacute.sc gcommaaccent.sc -20
+KPX nacute.sc gcircumflex.sc -20
+KPX nacute.sc gbreve.sc -20
+KPX nacute.sc cdotaccent.sc -20
+KPX nacute.sc ccircumflex.sc -20
+KPX nacute.sc ccaron.sc -20
+KPX nacute.sc cacute.sc -20
+KPX nacute.sc aeacute.sc -20
+KPX nacute.sc aogonek.sc -25
+KPX nacute.sc amacron.sc -25
+KPX nacute.sc oogonek.sc -15
+KPX nacute.sc gcaron.sc -20
+KPX nacute.sc gacute.sc -20
+KPX nacute.sc period -30
+KPX nacute.sc comma -45
+KPX ncaron.sc oslash.sc -15
+KPX ncaron.sc odieresis.sc -15
+KPX ncaron.sc ccedilla.sc -20
+KPX ncaron.sc ae.sc -20
+KPX ncaron.sc aring.sc -25
+KPX ncaron.sc adieresis.sc -25
+KPX ncaron.sc o.sc -15
+KPX ncaron.sc g.sc -20
+KPX ncaron.sc c.sc -20
+KPX ncaron.sc a.sc -25
+KPX ncaron.sc omacron.sc -15
+KPX ncaron.sc ohungarumlaut.sc -15
+KPX ncaron.sc obreve.sc -15
+KPX ncaron.sc gdotaccent.sc -20
+KPX ncaron.sc gcommaaccent.sc -20
+KPX ncaron.sc gcircumflex.sc -20
+KPX ncaron.sc gbreve.sc -20
+KPX ncaron.sc cdotaccent.sc -20
+KPX ncaron.sc ccircumflex.sc -20
+KPX ncaron.sc ccaron.sc -20
+KPX ncaron.sc cacute.sc -20
+KPX ncaron.sc aeacute.sc -20
+KPX ncaron.sc aogonek.sc -25
+KPX ncaron.sc amacron.sc -25
+KPX ncaron.sc oogonek.sc -15
+KPX ncaron.sc gcaron.sc -20
+KPX ncaron.sc gacute.sc -20
+KPX ncaron.sc period -30
+KPX ncaron.sc comma -45
+KPX ncommaaccent.sc oslash.sc -15
+KPX ncommaaccent.sc odieresis.sc -15
+KPX ncommaaccent.sc ccedilla.sc -20
+KPX ncommaaccent.sc ae.sc -20
+KPX ncommaaccent.sc aring.sc -25
+KPX ncommaaccent.sc adieresis.sc -25
+KPX ncommaaccent.sc o.sc -15
+KPX ncommaaccent.sc g.sc -20
+KPX ncommaaccent.sc c.sc -20
+KPX ncommaaccent.sc a.sc -25
+KPX ncommaaccent.sc omacron.sc -15
+KPX ncommaaccent.sc ohungarumlaut.sc -15
+KPX ncommaaccent.sc obreve.sc -15
+KPX ncommaaccent.sc gdotaccent.sc -20
+KPX ncommaaccent.sc gcommaaccent.sc -20
+KPX ncommaaccent.sc gcircumflex.sc -20
+KPX ncommaaccent.sc gbreve.sc -20
+KPX ncommaaccent.sc cdotaccent.sc -20
+KPX ncommaaccent.sc ccircumflex.sc -20
+KPX ncommaaccent.sc ccaron.sc -20
+KPX ncommaaccent.sc cacute.sc -20
+KPX ncommaaccent.sc aeacute.sc -20
+KPX ncommaaccent.sc aogonek.sc -25
+KPX ncommaaccent.sc amacron.sc -25
+KPX ncommaaccent.sc oogonek.sc -15
+KPX ncommaaccent.sc gcaron.sc -20
+KPX ncommaaccent.sc gacute.sc -20
+KPX ncommaaccent.sc period -30
+KPX ncommaaccent.sc comma -45
+KPX obreve.sc ydieresis.sc -35
+KPX obreve.sc ae.sc -45
+KPX obreve.sc aring.sc -50
+KPX obreve.sc adieresis.sc -50
+KPX obreve.sc y.sc -35
+KPX obreve.sc x.sc -40
+KPX obreve.sc w.sc -30
+KPX obreve.sc v.sc -35
+KPX obreve.sc t.sc -10
+KPX obreve.sc a.sc -50
+KPX obreve.sc ycircumflex.sc -35
+KPX obreve.sc wgrave.sc -30
+KPX obreve.sc wdieresis.sc -30
+KPX obreve.sc wcircumflex.sc -30
+KPX obreve.sc wacute.sc -30
+KPX obreve.sc uni021B.sc -10
+KPX obreve.sc tcaron.sc -10
+KPX obreve.sc aeacute.sc -45
+KPX obreve.sc aogonek.sc -50
+KPX obreve.sc amacron.sc -50
+KPX ohungarumlaut.sc ydieresis.sc -35
+KPX ohungarumlaut.sc ae.sc -45
+KPX ohungarumlaut.sc aring.sc -50
+KPX ohungarumlaut.sc adieresis.sc -50
+KPX ohungarumlaut.sc y.sc -35
+KPX ohungarumlaut.sc x.sc -40
+KPX ohungarumlaut.sc w.sc -30
+KPX ohungarumlaut.sc v.sc -35
+KPX ohungarumlaut.sc t.sc -10
+KPX ohungarumlaut.sc a.sc -50
+KPX ohungarumlaut.sc ycircumflex.sc -35
+KPX ohungarumlaut.sc wgrave.sc -30
+KPX ohungarumlaut.sc wdieresis.sc -30
+KPX ohungarumlaut.sc wcircumflex.sc -30
+KPX ohungarumlaut.sc wacute.sc -30
+KPX ohungarumlaut.sc uni021B.sc -10
+KPX ohungarumlaut.sc tcaron.sc -10
+KPX ohungarumlaut.sc aeacute.sc -45
+KPX ohungarumlaut.sc aogonek.sc -50
+KPX ohungarumlaut.sc amacron.sc -50
+KPX omacron.sc ydieresis.sc -35
+KPX omacron.sc ae.sc -45
+KPX omacron.sc aring.sc -50
+KPX omacron.sc adieresis.sc -50
+KPX omacron.sc y.sc -35
+KPX omacron.sc x.sc -40
+KPX omacron.sc w.sc -30
+KPX omacron.sc v.sc -35
+KPX omacron.sc t.sc -10
+KPX omacron.sc a.sc -50
+KPX omacron.sc ycircumflex.sc -35
+KPX omacron.sc wgrave.sc -30
+KPX omacron.sc wdieresis.sc -30
+KPX omacron.sc wcircumflex.sc -30
+KPX omacron.sc wacute.sc -30
+KPX omacron.sc uni021B.sc -10
+KPX omacron.sc tcaron.sc -10
+KPX omacron.sc aeacute.sc -45
+KPX omacron.sc aogonek.sc -50
+KPX omacron.sc amacron.sc -50
+KPX racute.sc ydieresis.sc -35
+KPX racute.sc udieresis.sc -35
+KPX racute.sc ucircumflex.sc -35
+KPX racute.sc oslash.sc -25
+KPX racute.sc odieresis.sc -25
+KPX racute.sc ccedilla.sc -25
+KPX racute.sc y.sc -35
+KPX racute.sc w.sc -35
+KPX racute.sc v.sc -35
+KPX racute.sc u.sc -35
+KPX racute.sc t.sc -25
+KPX racute.sc o.sc -25
+KPX racute.sc g.sc -25
+KPX racute.sc c.sc -25
+KPX racute.sc ycircumflex.sc -35
+KPX racute.sc wgrave.sc -35
+KPX racute.sc wdieresis.sc -35
+KPX racute.sc wcircumflex.sc -35
+KPX racute.sc wacute.sc -35
+KPX racute.sc uring.sc -35
+KPX racute.sc uogonek.sc -35
+KPX racute.sc umacron.sc -35
+KPX racute.sc uhungarumlaut.sc -35
+KPX racute.sc ubreve.sc -35
+KPX racute.sc uni021B.sc -25
+KPX racute.sc tcaron.sc -25
+KPX racute.sc omacron.sc -25
+KPX racute.sc ohungarumlaut.sc -25
+KPX racute.sc obreve.sc -25
+KPX racute.sc gdotaccent.sc -25
+KPX racute.sc gcommaaccent.sc -25
+KPX racute.sc gcircumflex.sc -25
+KPX racute.sc gbreve.sc -25
+KPX racute.sc cdotaccent.sc -25
+KPX racute.sc ccircumflex.sc -25
+KPX racute.sc ccaron.sc -25
+KPX racute.sc cacute.sc -25
+KPX racute.sc oogonek.sc -25
+KPX racute.sc oe.sc -25
+KPX racute.sc gcaron.sc -25
+KPX racute.sc gacute.sc -25
+KPX racute.sc hyphen -50
+KPX rcaron.sc ydieresis.sc -35
+KPX rcaron.sc udieresis.sc -35
+KPX rcaron.sc ucircumflex.sc -35
+KPX rcaron.sc oslash.sc -25
+KPX rcaron.sc odieresis.sc -25
+KPX rcaron.sc ccedilla.sc -25
+KPX rcaron.sc y.sc -35
+KPX rcaron.sc w.sc -35
+KPX rcaron.sc v.sc -35
+KPX rcaron.sc u.sc -35
+KPX rcaron.sc t.sc -25
+KPX rcaron.sc o.sc -25
+KPX rcaron.sc g.sc -25
+KPX rcaron.sc c.sc -25
+KPX rcaron.sc ycircumflex.sc -35
+KPX rcaron.sc wgrave.sc -35
+KPX rcaron.sc wdieresis.sc -35
+KPX rcaron.sc wcircumflex.sc -35
+KPX rcaron.sc wacute.sc -35
+KPX rcaron.sc uring.sc -35
+KPX rcaron.sc uogonek.sc -35
+KPX rcaron.sc umacron.sc -35
+KPX rcaron.sc uhungarumlaut.sc -35
+KPX rcaron.sc ubreve.sc -35
+KPX rcaron.sc uni021B.sc -25
+KPX rcaron.sc tcaron.sc -25
+KPX rcaron.sc omacron.sc -25
+KPX rcaron.sc ohungarumlaut.sc -25
+KPX rcaron.sc obreve.sc -25
+KPX rcaron.sc gdotaccent.sc -25
+KPX rcaron.sc gcommaaccent.sc -25
+KPX rcaron.sc gcircumflex.sc -25
+KPX rcaron.sc gbreve.sc -25
+KPX rcaron.sc cdotaccent.sc -25
+KPX rcaron.sc ccircumflex.sc -25
+KPX rcaron.sc ccaron.sc -25
+KPX rcaron.sc cacute.sc -25
+KPX rcaron.sc oogonek.sc -25
+KPX rcaron.sc oe.sc -25
+KPX rcaron.sc gcaron.sc -25
+KPX rcaron.sc gacute.sc -25
+KPX rcaron.sc hyphen -50
+KPX rcommaaccent.sc ydieresis.sc -35
+KPX rcommaaccent.sc udieresis.sc -35
+KPX rcommaaccent.sc ucircumflex.sc -35
+KPX rcommaaccent.sc oslash.sc -25
+KPX rcommaaccent.sc odieresis.sc -25
+KPX rcommaaccent.sc ccedilla.sc -25
+KPX rcommaaccent.sc y.sc -35
+KPX rcommaaccent.sc w.sc -35
+KPX rcommaaccent.sc v.sc -35
+KPX rcommaaccent.sc u.sc -35
+KPX rcommaaccent.sc t.sc -25
+KPX rcommaaccent.sc o.sc -25
+KPX rcommaaccent.sc g.sc -25
+KPX rcommaaccent.sc c.sc -25
+KPX rcommaaccent.sc ycircumflex.sc -35
+KPX rcommaaccent.sc wgrave.sc -35
+KPX rcommaaccent.sc wdieresis.sc -35
+KPX rcommaaccent.sc wcircumflex.sc -35
+KPX rcommaaccent.sc wacute.sc -35
+KPX rcommaaccent.sc uring.sc -35
+KPX rcommaaccent.sc uogonek.sc -35
+KPX rcommaaccent.sc umacron.sc -35
+KPX rcommaaccent.sc uhungarumlaut.sc -35
+KPX rcommaaccent.sc ubreve.sc -35
+KPX rcommaaccent.sc uni021B.sc -25
+KPX rcommaaccent.sc tcaron.sc -25
+KPX rcommaaccent.sc omacron.sc -25
+KPX rcommaaccent.sc ohungarumlaut.sc -25
+KPX rcommaaccent.sc obreve.sc -25
+KPX rcommaaccent.sc gdotaccent.sc -25
+KPX rcommaaccent.sc gcommaaccent.sc -25
+KPX rcommaaccent.sc gcircumflex.sc -25
+KPX rcommaaccent.sc gbreve.sc -25
+KPX rcommaaccent.sc cdotaccent.sc -25
+KPX rcommaaccent.sc ccircumflex.sc -25
+KPX rcommaaccent.sc ccaron.sc -25
+KPX rcommaaccent.sc cacute.sc -25
+KPX rcommaaccent.sc oogonek.sc -25
+KPX rcommaaccent.sc oe.sc -25
+KPX rcommaaccent.sc gcaron.sc -25
+KPX rcommaaccent.sc gacute.sc -25
+KPX rcommaaccent.sc hyphen -50
+KPX sacute.sc ydieresis.sc -10
+KPX sacute.sc ae.sc -20
+KPX sacute.sc aring.sc -25
+KPX sacute.sc adieresis.sc -25
+KPX sacute.sc y.sc -10
+KPX sacute.sc w.sc -10
+KPX sacute.sc v.sc -10
+KPX sacute.sc t.sc -15
+KPX sacute.sc a.sc -25
+KPX sacute.sc ycircumflex.sc -10
+KPX sacute.sc wgrave.sc -10
+KPX sacute.sc wdieresis.sc -10
+KPX sacute.sc wcircumflex.sc -10
+KPX sacute.sc wacute.sc -10
+KPX sacute.sc uni021B.sc -15
+KPX sacute.sc tcaron.sc -15
+KPX sacute.sc aeacute.sc -20
+KPX sacute.sc aogonek.sc -25
+KPX sacute.sc amacron.sc -25
+KPX scedilla.sc ydieresis.sc -10
+KPX scedilla.sc ae.sc -20
+KPX scedilla.sc aring.sc -25
+KPX scedilla.sc adieresis.sc -25
+KPX scedilla.sc y.sc -10
+KPX scedilla.sc w.sc -10
+KPX scedilla.sc v.sc -10
+KPX scedilla.sc t.sc -15
+KPX scedilla.sc a.sc -25
+KPX scedilla.sc ycircumflex.sc -10
+KPX scedilla.sc wgrave.sc -10
+KPX scedilla.sc wdieresis.sc -10
+KPX scedilla.sc wcircumflex.sc -10
+KPX scedilla.sc wacute.sc -10
+KPX scedilla.sc uni021B.sc -15
+KPX scedilla.sc tcaron.sc -15
+KPX scedilla.sc aeacute.sc -20
+KPX scedilla.sc aogonek.sc -25
+KPX scedilla.sc amacron.sc -25
+KPX scircumflex.sc ydieresis.sc -10
+KPX scircumflex.sc ae.sc -20
+KPX scircumflex.sc aring.sc -25
+KPX scircumflex.sc adieresis.sc -25
+KPX scircumflex.sc y.sc -10
+KPX scircumflex.sc w.sc -10
+KPX scircumflex.sc v.sc -10
+KPX scircumflex.sc t.sc -15
+KPX scircumflex.sc a.sc -25
+KPX scircumflex.sc ycircumflex.sc -10
+KPX scircumflex.sc wgrave.sc -10
+KPX scircumflex.sc wdieresis.sc -10
+KPX scircumflex.sc wcircumflex.sc -10
+KPX scircumflex.sc wacute.sc -10
+KPX scircumflex.sc uni021B.sc -15
+KPX scircumflex.sc tcaron.sc -15
+KPX scircumflex.sc aeacute.sc -20
+KPX scircumflex.sc aogonek.sc -25
+KPX scircumflex.sc amacron.sc -25
+KPX uni0219.sc ydieresis.sc -10
+KPX uni0219.sc ae.sc -20
+KPX uni0219.sc aring.sc -25
+KPX uni0219.sc adieresis.sc -25
+KPX uni0219.sc y.sc -10
+KPX uni0219.sc w.sc -10
+KPX uni0219.sc v.sc -10
+KPX uni0219.sc t.sc -15
+KPX uni0219.sc a.sc -25
+KPX uni0219.sc ycircumflex.sc -10
+KPX uni0219.sc wgrave.sc -10
+KPX uni0219.sc wdieresis.sc -10
+KPX uni0219.sc wcircumflex.sc -10
+KPX uni0219.sc wacute.sc -10
+KPX uni0219.sc uni021B.sc -15
+KPX uni0219.sc tcaron.sc -15
+KPX uni0219.sc aeacute.sc -20
+KPX uni0219.sc aogonek.sc -25
+KPX uni0219.sc amacron.sc -25
+KPX tcaron.sc oslash.sc -15
+KPX tcaron.sc odieresis.sc -15
+KPX tcaron.sc ccedilla.sc -15
+KPX tcaron.sc ae.sc -35
+KPX tcaron.sc aring.sc -45
+KPX tcaron.sc adieresis.sc -45
+KPX tcaron.sc o.sc -15
+KPX tcaron.sc g.sc -15
+KPX tcaron.sc c.sc -15
+KPX tcaron.sc a.sc -45
+KPX tcaron.sc omacron.sc -15
+KPX tcaron.sc ohungarumlaut.sc -15
+KPX tcaron.sc obreve.sc -15
+KPX tcaron.sc gdotaccent.sc -15
+KPX tcaron.sc gcommaaccent.sc -15
+KPX tcaron.sc gcircumflex.sc -15
+KPX tcaron.sc gbreve.sc -15
+KPX tcaron.sc cdotaccent.sc -15
+KPX tcaron.sc ccircumflex.sc -15
+KPX tcaron.sc ccaron.sc -15
+KPX tcaron.sc cacute.sc -15
+KPX tcaron.sc aeacute.sc -35
+KPX tcaron.sc aogonek.sc -45
+KPX tcaron.sc amacron.sc -45
+KPX tcaron.sc oogonek.sc -15
+KPX tcaron.sc oe.sc -15
+KPX tcaron.sc gcaron.sc -15
+KPX tcaron.sc gacute.sc -15
+KPX tcaron.sc semicolon -60
+KPX tcaron.sc colon -45
+KPX tcaron.sc period -90
+KPX tcaron.sc hyphen -75
+KPX tcaron.sc comma -100
+KPX uni021B.sc oslash.sc -15
+KPX uni021B.sc odieresis.sc -15
+KPX uni021B.sc ccedilla.sc -15
+KPX uni021B.sc ae.sc -35
+KPX uni021B.sc aring.sc -45
+KPX uni021B.sc adieresis.sc -45
+KPX uni021B.sc o.sc -15
+KPX uni021B.sc g.sc -15
+KPX uni021B.sc c.sc -15
+KPX uni021B.sc a.sc -45
+KPX uni021B.sc omacron.sc -15
+KPX uni021B.sc ohungarumlaut.sc -15
+KPX uni021B.sc obreve.sc -15
+KPX uni021B.sc gdotaccent.sc -15
+KPX uni021B.sc gcommaaccent.sc -15
+KPX uni021B.sc gcircumflex.sc -15
+KPX uni021B.sc gbreve.sc -15
+KPX uni021B.sc cdotaccent.sc -15
+KPX uni021B.sc ccircumflex.sc -15
+KPX uni021B.sc ccaron.sc -15
+KPX uni021B.sc cacute.sc -15
+KPX uni021B.sc aeacute.sc -35
+KPX uni021B.sc aogonek.sc -45
+KPX uni021B.sc amacron.sc -45
+KPX uni021B.sc oogonek.sc -15
+KPX uni021B.sc oe.sc -15
+KPX uni021B.sc gcaron.sc -15
+KPX uni021B.sc gacute.sc -15
+KPX uni021B.sc semicolon -100
+KPX uni021B.sc colon -95
+KPX uni021B.sc period -90
+KPX uni021B.sc hyphen -75
+KPX uni021B.sc comma -100
+KPX ubreve.sc ae.sc -45
+KPX ubreve.sc aring.sc -55
+KPX ubreve.sc adieresis.sc -55
+KPX ubreve.sc a.sc -55
+KPX ubreve.sc aeacute.sc -45
+KPX ubreve.sc aogonek.sc -55
+KPX ubreve.sc amacron.sc -55
+KPX ubreve.sc period -50
+KPX ubreve.sc comma -65
+KPX uhungarumlaut.sc ae.sc -45
+KPX uhungarumlaut.sc aring.sc -55
+KPX uhungarumlaut.sc adieresis.sc -55
+KPX uhungarumlaut.sc a.sc -55
+KPX uhungarumlaut.sc aeacute.sc -45
+KPX uhungarumlaut.sc aogonek.sc -55
+KPX uhungarumlaut.sc amacron.sc -55
+KPX uhungarumlaut.sc period -50
+KPX uhungarumlaut.sc comma -65
+KPX umacron.sc ae.sc -45
+KPX umacron.sc aring.sc -55
+KPX umacron.sc adieresis.sc -55
+KPX umacron.sc a.sc -55
+KPX umacron.sc aeacute.sc -45
+KPX umacron.sc aogonek.sc -55
+KPX umacron.sc amacron.sc -55
+KPX umacron.sc period -50
+KPX umacron.sc comma -65
+KPX uogonek.sc ae.sc -45
+KPX uogonek.sc aring.sc -55
+KPX uogonek.sc adieresis.sc -55
+KPX uogonek.sc a.sc -55
+KPX uogonek.sc aeacute.sc -45
+KPX uogonek.sc aogonek.sc -55
+KPX uogonek.sc amacron.sc -55
+KPX uogonek.sc period -50
+KPX uogonek.sc comma -65
+KPX uring.sc ae.sc -45
+KPX uring.sc aring.sc -55
+KPX uring.sc adieresis.sc -55
+KPX uring.sc a.sc -55
+KPX uring.sc aeacute.sc -45
+KPX uring.sc aogonek.sc -55
+KPX uring.sc amacron.sc -55
+KPX uring.sc period -50
+KPX uring.sc comma -65
+KPX utilde.sc a.sc -55
+KPX wacute.sc oslash.sc -35
+KPX wacute.sc odieresis.sc -35
+KPX wacute.sc ccedilla.sc -35
+KPX wacute.sc ae.sc -65
+KPX wacute.sc aring.sc -75
+KPX wacute.sc adieresis.sc -75
+KPX wacute.sc s.sc -25
+KPX wacute.sc o.sc -35
+KPX wacute.sc g.sc -35
+KPX wacute.sc c.sc -35
+KPX wacute.sc a.sc -75
+KPX wacute.sc uni0219.sc -25
+KPX wacute.sc scircumflex.sc -25
+KPX wacute.sc scedilla.sc -25
+KPX wacute.sc sacute.sc -25
+KPX wacute.sc omacron.sc -35
+KPX wacute.sc ohungarumlaut.sc -35
+KPX wacute.sc obreve.sc -35
+KPX wacute.sc gdotaccent.sc -35
+KPX wacute.sc gcommaaccent.sc -35
+KPX wacute.sc gcircumflex.sc -35
+KPX wacute.sc gbreve.sc -35
+KPX wacute.sc cdotaccent.sc -35
+KPX wacute.sc ccircumflex.sc -35
+KPX wacute.sc ccaron.sc -35
+KPX wacute.sc cacute.sc -35
+KPX wacute.sc aeacute.sc -65
+KPX wacute.sc aogonek.sc -75
+KPX wacute.sc amacron.sc -75
+KPX wacute.sc scaron.sc -25
+KPX wacute.sc oogonek.sc -35
+KPX wacute.sc gcaron.sc -35
+KPX wacute.sc gacute.sc -35
+KPX wacute.sc semicolon -95
+KPX wacute.sc colon -80
+KPX wacute.sc period -90
+KPX wacute.sc hyphen -45
+KPX wacute.sc comma -105
+KPX wcircumflex.sc oslash.sc -35
+KPX wcircumflex.sc odieresis.sc -35
+KPX wcircumflex.sc ccedilla.sc -35
+KPX wcircumflex.sc ae.sc -65
+KPX wcircumflex.sc aring.sc -75
+KPX wcircumflex.sc adieresis.sc -75
+KPX wcircumflex.sc s.sc -25
+KPX wcircumflex.sc o.sc -35
+KPX wcircumflex.sc g.sc -35
+KPX wcircumflex.sc c.sc -35
+KPX wcircumflex.sc a.sc -75
+KPX wcircumflex.sc uni0219.sc -25
+KPX wcircumflex.sc scircumflex.sc -25
+KPX wcircumflex.sc scedilla.sc -25
+KPX wcircumflex.sc sacute.sc -25
+KPX wcircumflex.sc omacron.sc -35
+KPX wcircumflex.sc ohungarumlaut.sc -35
+KPX wcircumflex.sc obreve.sc -35
+KPX wcircumflex.sc gdotaccent.sc -35
+KPX wcircumflex.sc gcommaaccent.sc -35
+KPX wcircumflex.sc gcircumflex.sc -35
+KPX wcircumflex.sc gbreve.sc -35
+KPX wcircumflex.sc cdotaccent.sc -35
+KPX wcircumflex.sc ccircumflex.sc -35
+KPX wcircumflex.sc ccaron.sc -35
+KPX wcircumflex.sc cacute.sc -35
+KPX wcircumflex.sc aeacute.sc -65
+KPX wcircumflex.sc aogonek.sc -75
+KPX wcircumflex.sc amacron.sc -75
+KPX wcircumflex.sc scaron.sc -25
+KPX wcircumflex.sc oogonek.sc -35
+KPX wcircumflex.sc gcaron.sc -35
+KPX wcircumflex.sc gacute.sc -35
+KPX wcircumflex.sc semicolon -95
+KPX wcircumflex.sc colon -80
+KPX wcircumflex.sc period -90
+KPX wcircumflex.sc hyphen -45
+KPX wcircumflex.sc comma -105
+KPX wdieresis.sc oslash.sc -35
+KPX wdieresis.sc odieresis.sc -35
+KPX wdieresis.sc ccedilla.sc -35
+KPX wdieresis.sc ae.sc -65
+KPX wdieresis.sc aring.sc -75
+KPX wdieresis.sc adieresis.sc -75
+KPX wdieresis.sc s.sc -25
+KPX wdieresis.sc o.sc -35
+KPX wdieresis.sc g.sc -35
+KPX wdieresis.sc c.sc -35
+KPX wdieresis.sc a.sc -75
+KPX wdieresis.sc uni0219.sc -25
+KPX wdieresis.sc scircumflex.sc -25
+KPX wdieresis.sc scedilla.sc -25
+KPX wdieresis.sc sacute.sc -25
+KPX wdieresis.sc omacron.sc -35
+KPX wdieresis.sc ohungarumlaut.sc -35
+KPX wdieresis.sc obreve.sc -35
+KPX wdieresis.sc gdotaccent.sc -35
+KPX wdieresis.sc gcommaaccent.sc -35
+KPX wdieresis.sc gcircumflex.sc -35
+KPX wdieresis.sc gbreve.sc -35
+KPX wdieresis.sc cdotaccent.sc -35
+KPX wdieresis.sc ccircumflex.sc -35
+KPX wdieresis.sc ccaron.sc -35
+KPX wdieresis.sc cacute.sc -35
+KPX wdieresis.sc aeacute.sc -65
+KPX wdieresis.sc aogonek.sc -75
+KPX wdieresis.sc amacron.sc -75
+KPX wdieresis.sc scaron.sc -25
+KPX wdieresis.sc oogonek.sc -35
+KPX wdieresis.sc gcaron.sc -35
+KPX wdieresis.sc gacute.sc -35
+KPX wdieresis.sc semicolon -95
+KPX wdieresis.sc colon -80
+KPX wdieresis.sc period -90
+KPX wdieresis.sc hyphen -45
+KPX wdieresis.sc comma -105
+KPX wgrave.sc oslash.sc -35
+KPX wgrave.sc odieresis.sc -35
+KPX wgrave.sc ccedilla.sc -35
+KPX wgrave.sc ae.sc -65
+KPX wgrave.sc aring.sc -75
+KPX wgrave.sc adieresis.sc -75
+KPX wgrave.sc s.sc -25
+KPX wgrave.sc o.sc -35
+KPX wgrave.sc g.sc -35
+KPX wgrave.sc c.sc -35
+KPX wgrave.sc a.sc -75
+KPX wgrave.sc uni0219.sc -25
+KPX wgrave.sc scircumflex.sc -25
+KPX wgrave.sc scedilla.sc -25
+KPX wgrave.sc sacute.sc -25
+KPX wgrave.sc omacron.sc -35
+KPX wgrave.sc ohungarumlaut.sc -35
+KPX wgrave.sc obreve.sc -35
+KPX wgrave.sc gdotaccent.sc -35
+KPX wgrave.sc gcommaaccent.sc -35
+KPX wgrave.sc gcircumflex.sc -35
+KPX wgrave.sc gbreve.sc -35
+KPX wgrave.sc cdotaccent.sc -35
+KPX wgrave.sc ccircumflex.sc -35
+KPX wgrave.sc ccaron.sc -35
+KPX wgrave.sc cacute.sc -35
+KPX wgrave.sc aeacute.sc -65
+KPX wgrave.sc aogonek.sc -75
+KPX wgrave.sc amacron.sc -75
+KPX wgrave.sc scaron.sc -25
+KPX wgrave.sc oogonek.sc -35
+KPX wgrave.sc gcaron.sc -35
+KPX wgrave.sc gacute.sc -35
+KPX wgrave.sc semicolon -95
+KPX wgrave.sc colon -80
+KPX wgrave.sc period -90
+KPX wgrave.sc hyphen -45
+KPX wgrave.sc comma -105
+KPX ycircumflex.sc oslash.sc -45
+KPX ycircumflex.sc odieresis.sc -45
+KPX ycircumflex.sc ccedilla.sc -45
+KPX ycircumflex.sc ae.sc -40
+KPX ycircumflex.sc aring.sc -45
+KPX ycircumflex.sc adieresis.sc -45
+KPX ycircumflex.sc s.sc -25
+KPX ycircumflex.sc o.sc -45
+KPX ycircumflex.sc g.sc -45
+KPX ycircumflex.sc c.sc -45
+KPX ycircumflex.sc a.sc -45
+KPX ycircumflex.sc uni0219.sc -25
+KPX ycircumflex.sc scircumflex.sc -25
+KPX ycircumflex.sc scedilla.sc -25
+KPX ycircumflex.sc sacute.sc -25
+KPX ycircumflex.sc omacron.sc -45
+KPX ycircumflex.sc ohungarumlaut.sc -45
+KPX ycircumflex.sc obreve.sc -45
+KPX ycircumflex.sc gdotaccent.sc -45
+KPX ycircumflex.sc gcommaaccent.sc -45
+KPX ycircumflex.sc gcircumflex.sc -45
+KPX ycircumflex.sc gbreve.sc -45
+KPX ycircumflex.sc cdotaccent.sc -45
+KPX ycircumflex.sc ccircumflex.sc -45
+KPX ycircumflex.sc ccaron.sc -45
+KPX ycircumflex.sc cacute.sc -45
+KPX ycircumflex.sc aeacute.sc -40
+KPX ycircumflex.sc aogonek.sc -45
+KPX ycircumflex.sc amacron.sc -45
+KPX ycircumflex.sc scaron.sc -25
+KPX ycircumflex.sc oogonek.sc -45
+KPX ycircumflex.sc gcaron.sc -45
+KPX ycircumflex.sc gacute.sc -45
+KPX ycircumflex.sc semicolon -110
+KPX ycircumflex.sc colon -100
+KPX ycircumflex.sc period -100
+KPX ycircumflex.sc hyphen -80
+KPX ycircumflex.sc comma -110
+KPX a.sc ydieresis.sc -60
+KPX a.sc udieresis.sc -50
+KPX a.sc ucircumflex.sc -50
+KPX a.sc oslash.sc -45
+KPX a.sc odieresis.sc -45
+KPX a.sc ograve.sc -45
+KPX a.sc ccedilla.sc -45
+KPX a.sc y.sc -60
+KPX a.sc w.sc -65
+KPX a.sc v.sc -95
+KPX a.sc u.sc -50
+KPX a.sc t.sc -45
+KPX a.sc q.sc -45
+KPX a.sc o.sc -45
+KPX a.sc g.sc -45
+KPX a.sc c.sc -45
+KPX a.sc ycircumflex.sc -60
+KPX a.sc wgrave.sc -65
+KPX a.sc wdieresis.sc -65
+KPX a.sc wcircumflex.sc -65
+KPX a.sc wacute.sc -65
+KPX a.sc uring.sc -50
+KPX a.sc uogonek.sc -50
+KPX a.sc umacron.sc -50
+KPX a.sc uhungarumlaut.sc -50
+KPX a.sc ubreve.sc -50
+KPX a.sc uni021B.sc -45
+KPX a.sc tcaron.sc -45
+KPX a.sc omacron.sc -45
+KPX a.sc ohungarumlaut.sc -45
+KPX a.sc obreve.sc -45
+KPX a.sc gdotaccent.sc -45
+KPX a.sc gcommaaccent.sc -45
+KPX a.sc gcircumflex.sc -45
+KPX a.sc gbreve.sc -45
+KPX a.sc cdotaccent.sc -45
+KPX a.sc ccircumflex.sc -45
+KPX a.sc ccaron.sc -45
+KPX a.sc cacute.sc -45
+KPX a.sc oogonek.sc -45
+KPX a.sc gcaron.sc -45
+KPX a.sc gacute.sc -45
+KPX a.sc quotedblright -125
+KPX a.sc quoteright -120
+KPX a.sc ringhalfleft -130
+KPX a.sc ringhalfright -135
+KPX a.sc period -25
+KPX a.sc hyphen -35
+KPX a.sc comma -35
+KPX b.sc ydieresis.sc -25
+KPX b.sc ae.sc -25
+KPX b.sc aring.sc -35
+KPX b.sc adieresis.sc -35
+KPX b.sc atilde.sc -35
+KPX b.sc acircumflex.sc -35
+KPX b.sc aacute.sc -35
+KPX b.sc agrave.sc -35
+KPX b.sc y.sc -25
+KPX b.sc w.sc -25
+KPX b.sc v.sc -25
+KPX b.sc a.sc -35
+KPX b.sc ycircumflex.sc -25
+KPX b.sc wgrave.sc -25
+KPX b.sc wdieresis.sc -25
+KPX b.sc wcircumflex.sc -25
+KPX b.sc wacute.sc -25
+KPX b.sc aeacute.sc -25
+KPX b.sc aogonek.sc -35
+KPX b.sc amacron.sc -35
+KPX b.sc abreve.sc -35
+KPX b.sc ahookabove.sc -35
+KPX b.sc adotbelow.sc -35
+KPX b.sc acircumflextilde.sc -35
+KPX b.sc acircumflexhookabove.sc -35
+KPX b.sc acircumflexgrave.sc -35
+KPX b.sc acircumflexdotbelow.sc -35
+KPX b.sc acircumflexacute.sc -35
+KPX b.sc abrevetilde.sc -35
+KPX b.sc abrevehookabove.sc -35
+KPX b.sc abrevegrave.sc -35
+KPX b.sc abrevedotbelow.sc -35
+KPX b.sc abreveacute.sc -35
+KPX c.sc oslash.sc -25
+KPX c.sc odieresis.sc -25
+KPX c.sc otilde.sc -25
+KPX c.sc ocircumflex.sc -25
+KPX c.sc oacute.sc -25
+KPX c.sc ograve.sc -25
+KPX c.sc aring.sc -10
+KPX c.sc adieresis.sc -10
+KPX c.sc atilde.sc -10
+KPX c.sc acircumflex.sc -10
+KPX c.sc aacute.sc -10
+KPX c.sc agrave.sc -10
+KPX c.sc o.sc -25
+KPX c.sc k.sc -5
+KPX c.sc h.sc -5
+KPX c.sc a.sc -10
+KPX c.sc omacron.sc -25
+KPX c.sc ohungarumlaut.sc -25
+KPX c.sc obreve.sc -25
+KPX c.sc kcommaaccent.sc -5
+KPX c.sc hcircumflex.sc -5
+KPX c.sc aogonek.sc -10
+KPX c.sc amacron.sc -10
+KPX c.sc abreve.sc -10
+KPX c.sc oogonek.sc -25
+KPX c.sc ohorntilde.sc -25
+KPX c.sc ohornhookabove.sc -25
+KPX c.sc ohorngrave.sc -25
+KPX c.sc ohorndotbelow.sc -25
+KPX c.sc ohornacute.sc -25
+KPX c.sc ohookabove.sc -25
+KPX c.sc odotbelow.sc -25
+KPX c.sc ocircumflextilde.sc -25
+KPX c.sc ocircumflexhookabove.sc -25
+KPX c.sc ocircumflexgrave.sc -25
+KPX c.sc ocircumflexdotbelow.sc -25
+KPX c.sc ocircumflexacute.sc -25
+KPX c.sc ahookabove.sc -10
+KPX c.sc adotbelow.sc -10
+KPX c.sc acircumflextilde.sc -10
+KPX c.sc acircumflexhookabove.sc -10
+KPX c.sc acircumflexgrave.sc -10
+KPX c.sc acircumflexdotbelow.sc -10
+KPX c.sc acircumflexacute.sc -10
+KPX c.sc abrevetilde.sc -10
+KPX c.sc abrevehookabove.sc -10
+KPX c.sc abrevegrave.sc -10
+KPX c.sc abrevedotbelow.sc -10
+KPX c.sc abreveacute.sc -10
+KPX d.sc ydieresis.sc -35
+KPX d.sc aring.sc -55
+KPX d.sc adieresis.sc -55
+KPX d.sc atilde.sc -55
+KPX d.sc acircumflex.sc -55
+KPX d.sc aacute.sc -55
+KPX d.sc agrave.sc -55
+KPX d.sc y.sc -35
+KPX d.sc x.sc -40
+KPX d.sc w.sc -30
+KPX d.sc v.sc -40
+KPX d.sc t.sc -10
+KPX d.sc j.sc -20
+KPX d.sc a.sc -55
+KPX d.sc ycircumflex.sc -35
+KPX d.sc wgrave.sc -30
+KPX d.sc wdieresis.sc -30
+KPX d.sc wcircumflex.sc -30
+KPX d.sc wacute.sc -30
+KPX d.sc uni021B.sc -10
+KPX d.sc tcaron.sc -10
+KPX d.sc jcircumflex.sc -20
+KPX d.sc aogonek.sc -55
+KPX d.sc amacron.sc -55
+KPX d.sc abreve.sc -55
+KPX d.sc jacute.sc -20
+KPX d.sc ahookabove.sc -55
+KPX d.sc adotbelow.sc -55
+KPX d.sc acircumflextilde.sc -55
+KPX d.sc acircumflexhookabove.sc -55
+KPX d.sc acircumflexgrave.sc -55
+KPX d.sc acircumflexdotbelow.sc -55
+KPX d.sc acircumflexacute.sc -55
+KPX d.sc abrevehookabove.sc -55
+KPX d.sc abrevegrave.sc -55
+KPX d.sc abrevedotbelow.sc -55
+KPX d.sc abreveacute.sc -55
+KPX f.sc oslash.sc -15
+KPX f.sc odieresis.sc -15
+KPX f.sc aring.sc -65
+KPX f.sc adieresis.sc -65
+KPX f.sc o.sc -15
+KPX f.sc a.sc -65
+KPX f.sc omacron.sc -15
+KPX f.sc ohungarumlaut.sc -15
+KPX f.sc obreve.sc -15
+KPX f.sc aogonek.sc -65
+KPX f.sc amacron.sc -65
+KPX f.sc oogonek.sc -15
+KPX f.sc period -65
+KPX f.sc comma -80
+KPX g.sc ydieresis.sc -15
+KPX g.sc aring.sc -15
+KPX g.sc adieresis.sc -15
+KPX g.sc atilde.sc -15
+KPX g.sc acircumflex.sc -15
+KPX g.sc aacute.sc -15
+KPX g.sc agrave.sc -15
+KPX g.sc y.sc -15
+KPX g.sc w.sc -10
+KPX g.sc v.sc -10
+KPX g.sc t.sc -15
+KPX g.sc a.sc -15
+KPX g.sc ycircumflex.sc -15
+KPX g.sc wgrave.sc -10
+KPX g.sc wdieresis.sc -10
+KPX g.sc wcircumflex.sc -10
+KPX g.sc wacute.sc -10
+KPX g.sc uni021B.sc -15
+KPX g.sc tcaron.sc -15
+KPX g.sc aogonek.sc -15
+KPX g.sc amacron.sc -15
+KPX g.sc abreve.sc -15
+KPX g.sc ahookabove.sc -15
+KPX g.sc adotbelow.sc -15
+KPX g.sc acircumflextilde.sc -15
+KPX g.sc acircumflexhookabove.sc -15
+KPX g.sc acircumflexgrave.sc -15
+KPX g.sc acircumflexdotbelow.sc -15
+KPX g.sc acircumflexacute.sc -15
+KPX g.sc abrevetilde.sc -15
+KPX g.sc abrevehookabove.sc -15
+KPX g.sc abrevegrave.sc -15
+KPX g.sc abrevedotbelow.sc -15
+KPX g.sc abreveacute.sc -15
+KPX j.sc ae.sc -25
+KPX j.sc aring.sc -35
+KPX j.sc adieresis.sc -35
+KPX j.sc a.sc -35
+KPX j.sc aeacute.sc -25
+KPX j.sc aogonek.sc -35
+KPX j.sc amacron.sc -35
+KPX k.sc oslash.sc -40
+KPX k.sc odieresis.sc -40
+KPX k.sc ccedilla.sc -45
+KPX k.sc o.sc -40
+KPX k.sc g.sc -45
+KPX k.sc c.sc -45
+KPX k.sc omacron.sc -40
+KPX k.sc ohungarumlaut.sc -40
+KPX k.sc obreve.sc -40
+KPX k.sc gdotaccent.sc -45
+KPX k.sc gcommaaccent.sc -45
+KPX k.sc gcircumflex.sc -45
+KPX k.sc gbreve.sc -45
+KPX k.sc cdotaccent.sc -45
+KPX k.sc ccircumflex.sc -45
+KPX k.sc ccaron.sc -45
+KPX k.sc cacute.sc -45
+KPX k.sc oogonek.sc -40
+KPX k.sc oe.sc -40
+KPX k.sc gcaron.sc -45
+KPX k.sc gacute.sc -45
+KPX k.sc hyphen -75
+KPX l.sc ydieresis.sc -65
+KPX l.sc yacute.sc -65
+KPX l.sc udieresis.sc -30
+KPX l.sc ucircumflex.sc -30
+KPX l.sc uacute.sc -30
+KPX l.sc ugrave.sc -30
+KPX l.sc oslash.sc -15
+KPX l.sc odieresis.sc -15
+KPX l.sc otilde.sc -15
+KPX l.sc ocircumflex.sc -15
+KPX l.sc oacute.sc -15
+KPX l.sc ograve.sc -15
+KPX l.sc ccedilla.sc -15
+KPX l.sc y.sc -65
+KPX l.sc w.sc -55
+KPX l.sc v.sc -85
+KPX l.sc u.sc -30
+KPX l.sc t.sc -55
+KPX l.sc o.sc -15
+KPX l.sc g.sc -15
+KPX l.sc c.sc -15
+KPX l.sc ycircumflex.sc -65
+KPX l.sc wgrave.sc -55
+KPX l.sc wdieresis.sc -55
+KPX l.sc wcircumflex.sc -55
+KPX l.sc wacute.sc -55
+KPX l.sc utilde.sc -30
+KPX l.sc uring.sc -30
+KPX l.sc uogonek.sc -30
+KPX l.sc umacron.sc -30
+KPX l.sc uhungarumlaut.sc -30
+KPX l.sc ubreve.sc -30
+KPX l.sc uni021B.sc -55
+KPX l.sc tcaron.sc -55
+KPX l.sc omacron.sc -15
+KPX l.sc ohungarumlaut.sc -15
+KPX l.sc obreve.sc -15
+KPX l.sc gdotaccent.sc -15
+KPX l.sc gcommaaccent.sc -15
+KPX l.sc gcircumflex.sc -15
+KPX l.sc gbreve.sc -15
+KPX l.sc cdotaccent.sc -15
+KPX l.sc ccircumflex.sc -15
+KPX l.sc ccaron.sc -15
+KPX l.sc cacute.sc -15
+KPX l.sc uhorntilde.sc -30
+KPX l.sc uhornhookabove.sc -30
+KPX l.sc uhorngrave.sc -30
+KPX l.sc uhorndotbelow.sc -30
+KPX l.sc uhornacute.sc -30
+KPX l.sc uhookabove.sc -30
+KPX l.sc udotbelow.sc -30
+KPX l.sc oogonek.sc -15
+KPX l.sc ohorntilde.sc -15
+KPX l.sc ohornhookabove.sc -15
+KPX l.sc ohorngrave.sc -15
+KPX l.sc ohorndotbelow.sc -15
+KPX l.sc ohornacute.sc -15
+KPX l.sc ohookabove.sc -15
+KPX l.sc odotbelow.sc -15
+KPX l.sc ocircumflextilde.sc -15
+KPX l.sc ocircumflexhookabove.sc -15
+KPX l.sc ocircumflexgrave.sc -15
+KPX l.sc ocircumflexdotbelow.sc -15
+KPX l.sc ocircumflexacute.sc -15
+KPX l.sc gcaron.sc -15
+KPX l.sc gacute.sc -15
+KPX l.sc quotedblright -130
+KPX l.sc quoteright -125
+KPX n.sc oslash.sc -15
+KPX n.sc odieresis.sc -15
+KPX n.sc otilde.sc -15
+KPX n.sc ocircumflex.sc -15
+KPX n.sc oacute.sc -15
+KPX n.sc ograve.sc -15
+KPX n.sc ccedilla.sc -20
+KPX n.sc ae.sc -20
+KPX n.sc aring.sc -25
+KPX n.sc adieresis.sc -25
+KPX n.sc atilde.sc -25
+KPX n.sc acircumflex.sc -25
+KPX n.sc aacute.sc -25
+KPX n.sc agrave.sc -25
+KPX n.sc o.sc -15
+KPX n.sc g.sc -20
+KPX n.sc c.sc -20
+KPX n.sc a.sc -25
+KPX n.sc omacron.sc -15
+KPX n.sc ohungarumlaut.sc -15
+KPX n.sc obreve.sc -15
+KPX n.sc gdotaccent.sc -20
+KPX n.sc gcommaaccent.sc -20
+KPX n.sc gcircumflex.sc -20
+KPX n.sc gbreve.sc -20
+KPX n.sc cdotaccent.sc -20
+KPX n.sc ccircumflex.sc -20
+KPX n.sc ccaron.sc -20
+KPX n.sc cacute.sc -20
+KPX n.sc aeacute.sc -20
+KPX n.sc aogonek.sc -25
+KPX n.sc amacron.sc -25
+KPX n.sc abreve.sc -25
+KPX n.sc oogonek.sc -15
+KPX n.sc ohorntilde.sc -15
+KPX n.sc ohornhookabove.sc -15
+KPX n.sc ohorngrave.sc -15
+KPX n.sc ohorndotbelow.sc -15
+KPX n.sc ohornacute.sc -15
+KPX n.sc ohookabove.sc -15
+KPX n.sc odotbelow.sc -15
+KPX n.sc ocircumflextilde.sc -15
+KPX n.sc ocircumflexhookabove.sc -15
+KPX n.sc ocircumflexgrave.sc -15
+KPX n.sc ocircumflexdotbelow.sc -15
+KPX n.sc ocircumflexacute.sc -15
+KPX n.sc gcaron.sc -20
+KPX n.sc gacute.sc -20
+KPX n.sc ahookabove.sc -25
+KPX n.sc adotbelow.sc -25
+KPX n.sc acircumflextilde.sc -25
+KPX n.sc acircumflexhookabove.sc -25
+KPX n.sc acircumflexgrave.sc -25
+KPX n.sc acircumflexdotbelow.sc -25
+KPX n.sc acircumflexacute.sc -25
+KPX n.sc abrevegrave.sc -25
+KPX n.sc abrevedotbelow.sc -25
+KPX n.sc abreveacute.sc -25
+KPX n.sc period -30
+KPX n.sc comma -45
+KPX o.sc ydieresis.sc -35
+KPX o.sc ae.sc -45
+KPX o.sc aring.sc -50
+KPX o.sc adieresis.sc -50
+KPX o.sc atilde.sc -50
+KPX o.sc aacute.sc -50
+KPX o.sc agrave.sc -50
+KPX o.sc y.sc -35
+KPX o.sc x.sc -40
+KPX o.sc w.sc -30
+KPX o.sc v.sc -35
+KPX o.sc t.sc -10
+KPX o.sc a.sc -50
+KPX o.sc ycircumflex.sc -35
+KPX o.sc wgrave.sc -30
+KPX o.sc wdieresis.sc -30
+KPX o.sc wcircumflex.sc -30
+KPX o.sc wacute.sc -30
+KPX o.sc uni021B.sc -10
+KPX o.sc tcaron.sc -10
+KPX o.sc aeacute.sc -45
+KPX o.sc aogonek.sc -50
+KPX o.sc amacron.sc -50
+KPX o.sc abreve.sc -50
+KPX o.sc ahookabove.sc -50
+KPX o.sc adotbelow.sc -50
+KPX o.sc abrevetilde.sc -50
+KPX o.sc abrevehookabove.sc -50
+KPX o.sc abrevegrave.sc -50
+KPX o.sc abrevedotbelow.sc -50
+KPX o.sc abreveacute.sc -50
+KPX p.sc ae.sc -75
+KPX p.sc aring.sc -85
+KPX p.sc adieresis.sc -85
+KPX p.sc aacute.sc -85
+KPX p.sc j.sc -20
+KPX p.sc a.sc -85
+KPX p.sc jcircumflex.sc -20
+KPX p.sc aeacute.sc -75
+KPX p.sc aogonek.sc -85
+KPX p.sc amacron.sc -85
+KPX p.sc jacute.sc -20
+KPX p.sc period -130
+KPX p.sc hyphen -50
+KPX p.sc comma -140
+KPX r.sc ydieresis.sc -35
+KPX r.sc udieresis.sc -35
+KPX r.sc ucircumflex.sc -35
+KPX r.sc uacute.sc -35
+KPX r.sc ugrave.sc -35
+KPX r.sc oslash.sc -25
+KPX r.sc odieresis.sc -25
+KPX r.sc otilde.sc -25
+KPX r.sc ocircumflex.sc -25
+KPX r.sc oacute.sc -25
+KPX r.sc ograve.sc -25
+KPX r.sc ccedilla.sc -25
+KPX r.sc y.sc -35
+KPX r.sc w.sc -35
+KPX r.sc v.sc -35
+KPX r.sc u.sc -35
+KPX r.sc t.sc -25
+KPX r.sc o.sc -25
+KPX r.sc g.sc -25
+KPX r.sc c.sc -25
+KPX r.sc ycircumflex.sc -35
+KPX r.sc wgrave.sc -35
+KPX r.sc wdieresis.sc -35
+KPX r.sc wcircumflex.sc -35
+KPX r.sc wacute.sc -35
+KPX r.sc utilde.sc -35
+KPX r.sc uring.sc -35
+KPX r.sc uogonek.sc -35
+KPX r.sc umacron.sc -35
+KPX r.sc uhungarumlaut.sc -35
+KPX r.sc ubreve.sc -35
+KPX r.sc uni021B.sc -25
+KPX r.sc tcaron.sc -25
+KPX r.sc omacron.sc -25
+KPX r.sc ohungarumlaut.sc -25
+KPX r.sc obreve.sc -25
+KPX r.sc gdotaccent.sc -25
+KPX r.sc gcommaaccent.sc -25
+KPX r.sc gcircumflex.sc -25
+KPX r.sc gbreve.sc -25
+KPX r.sc cdotaccent.sc -25
+KPX r.sc ccircumflex.sc -25
+KPX r.sc ccaron.sc -25
+KPX r.sc cacute.sc -25
+KPX r.sc uhorntilde.sc -35
+KPX r.sc uhornhookabove.sc -35
+KPX r.sc uhorngrave.sc -35
+KPX r.sc uhorndotbelow.sc -35
+KPX r.sc uhornacute.sc -35
+KPX r.sc uhookabove.sc -35
+KPX r.sc udotbelow.sc -35
+KPX r.sc oogonek.sc -25
+KPX r.sc ohorntilde.sc -25
+KPX r.sc ohornhookabove.sc -25
+KPX r.sc ohorngrave.sc -25
+KPX r.sc ohorndotbelow.sc -25
+KPX r.sc ohornacute.sc -25
+KPX r.sc ohookabove.sc -25
+KPX r.sc oe.sc -25
+KPX r.sc odotbelow.sc -25
+KPX r.sc ocircumflextilde.sc -25
+KPX r.sc ocircumflexhookabove.sc -25
+KPX r.sc ocircumflexgrave.sc -25
+KPX r.sc ocircumflexdotbelow.sc -25
+KPX r.sc ocircumflexacute.sc -25
+KPX r.sc gcaron.sc -25
+KPX r.sc gacute.sc -25
+KPX r.sc hyphen -50
+KPX s.sc ydieresis.sc -10
+KPX s.sc ae.sc -20
+KPX s.sc aring.sc -25
+KPX s.sc adieresis.sc -25
+KPX s.sc atilde.sc -25
+KPX s.sc acircumflex.sc -25
+KPX s.sc aacute.sc -25
+KPX s.sc agrave.sc -25
+KPX s.sc y.sc -10
+KPX s.sc w.sc -10
+KPX s.sc v.sc -10
+KPX s.sc t.sc -15
+KPX s.sc a.sc -25
+KPX s.sc ycircumflex.sc -10
+KPX s.sc wgrave.sc -10
+KPX s.sc wdieresis.sc -10
+KPX s.sc wcircumflex.sc -10
+KPX s.sc wacute.sc -10
+KPX s.sc uni021B.sc -15
+KPX s.sc tcaron.sc -15
+KPX s.sc aeacute.sc -20
+KPX s.sc aogonek.sc -25
+KPX s.sc amacron.sc -25
+KPX s.sc abreve.sc -25
+KPX s.sc ahookabove.sc -25
+KPX s.sc adotbelow.sc -25
+KPX s.sc acircumflextilde.sc -25
+KPX s.sc acircumflexhookabove.sc -25
+KPX s.sc acircumflexgrave.sc -25
+KPX s.sc acircumflexdotbelow.sc -25
+KPX s.sc acircumflexacute.sc -25
+KPX s.sc abrevetilde.sc -25
+KPX s.sc abrevegrave.sc -25
+KPX s.sc abrevedotbelow.sc -25
+KPX s.sc abreveacute.sc -25
+KPX t.sc oslash.sc -15
+KPX t.sc odieresis.sc -15
+KPX t.sc otilde.sc -15
+KPX t.sc ocircumflex.sc -15
+KPX t.sc oacute.sc -15
+KPX t.sc ograve.sc -15
+KPX t.sc ccedilla.sc -15
+KPX t.sc ae.sc -35
+KPX t.sc aring.sc -45
+KPX t.sc adieresis.sc -45
+KPX t.sc atilde.sc -45
+KPX t.sc acircumflex.sc -45
+KPX t.sc aacute.sc -45
+KPX t.sc agrave.sc -45
+KPX t.sc o.sc -15
+KPX t.sc g.sc -15
+KPX t.sc c.sc -15
+KPX t.sc a.sc -45
+KPX t.sc omacron.sc -15
+KPX t.sc ohungarumlaut.sc -15
+KPX t.sc obreve.sc -15
+KPX t.sc gdotaccent.sc -15
+KPX t.sc gcommaaccent.sc -15
+KPX t.sc gcircumflex.sc -15
+KPX t.sc gbreve.sc -15
+KPX t.sc cdotaccent.sc -15
+KPX t.sc ccircumflex.sc -15
+KPX t.sc ccaron.sc -15
+KPX t.sc cacute.sc -15
+KPX t.sc aeacute.sc -35
+KPX t.sc aogonek.sc -45
+KPX t.sc amacron.sc -45
+KPX t.sc abreve.sc -45
+KPX t.sc oogonek.sc -15
+KPX t.sc ohornhookabove.sc -15
+KPX t.sc ohorngrave.sc -15
+KPX t.sc ohorndotbelow.sc -15
+KPX t.sc ohornacute.sc -15
+KPX t.sc ohookabove.sc -15
+KPX t.sc oe.sc -15
+KPX t.sc odotbelow.sc -15
+KPX t.sc ocircumflexhookabove.sc -15
+KPX t.sc ocircumflexgrave.sc -15
+KPX t.sc ocircumflexdotbelow.sc -15
+KPX t.sc ocircumflexacute.sc -15
+KPX t.sc gcaron.sc -15
+KPX t.sc gacute.sc -15
+KPX t.sc ahookabove.sc -45
+KPX t.sc adotbelow.sc -45
+KPX t.sc acircumflexhookabove.sc -45
+KPX t.sc acircumflexgrave.sc -45
+KPX t.sc acircumflexdotbelow.sc -45
+KPX t.sc acircumflexacute.sc -45
+KPX t.sc abrevehookabove.sc -45
+KPX t.sc abrevegrave.sc -45
+KPX t.sc abrevedotbelow.sc -45
+KPX t.sc abreveacute.sc -45
+KPX t.sc semicolon -67
+KPX t.sc colon -45
+KPX t.sc period -90
+KPX t.sc hyphen -75
+KPX t.sc comma -100
+KPX u.sc ae.sc -45
+KPX u.sc aring.sc -55
+KPX u.sc adieresis.sc -55
+KPX u.sc atilde.sc -55
+KPX u.sc acircumflex.sc -55
+KPX u.sc aacute.sc -55
+KPX u.sc agrave.sc -55
+KPX u.sc a.sc -55
+KPX u.sc aeacute.sc -45
+KPX u.sc aogonek.sc -55
+KPX u.sc amacron.sc -55
+KPX u.sc abreve.sc -55
+KPX u.sc ahookabove.sc -55
+KPX u.sc adotbelow.sc -55
+KPX u.sc acircumflextilde.sc -55
+KPX u.sc acircumflexhookabove.sc -55
+KPX u.sc acircumflexgrave.sc -55
+KPX u.sc acircumflexdotbelow.sc -55
+KPX u.sc acircumflexacute.sc -55
+KPX u.sc abrevehookabove.sc -55
+KPX u.sc abrevegrave.sc -55
+KPX u.sc abrevedotbelow.sc -55
+KPX u.sc abreveacute.sc -55
+KPX u.sc period -50
+KPX u.sc comma -65
+KPX v.sc oslash.sc -45
+KPX v.sc odieresis.sc -45
+KPX v.sc otilde.sc -45
+KPX v.sc ocircumflex.sc -45
+KPX v.sc oacute.sc -45
+KPX v.sc ograve.sc -45
+KPX v.sc ccedilla.sc -45
+KPX v.sc ae.sc -85
+KPX v.sc aring.sc -95
+KPX v.sc adieresis.sc -95
+KPX v.sc atilde.sc -95
+KPX v.sc acircumflex.sc -95
+KPX v.sc aacute.sc -95
+KPX v.sc agrave.sc -95
+KPX v.sc s.sc -25
+KPX v.sc o.sc -45
+KPX v.sc g.sc -45
+KPX v.sc c.sc -45
+KPX v.sc a.sc -95
+KPX v.sc uni0219.sc -25
+KPX v.sc scircumflex.sc -25
+KPX v.sc scedilla.sc -25
+KPX v.sc sacute.sc -25
+KPX v.sc omacron.sc -45
+KPX v.sc ohungarumlaut.sc -45
+KPX v.sc obreve.sc -45
+KPX v.sc gdotaccent.sc -45
+KPX v.sc gcommaaccent.sc -45
+KPX v.sc gcircumflex.sc -45
+KPX v.sc gbreve.sc -45
+KPX v.sc cdotaccent.sc -45
+KPX v.sc ccircumflex.sc -45
+KPX v.sc ccaron.sc -45
+KPX v.sc cacute.sc -45
+KPX v.sc aeacute.sc -85
+KPX v.sc aogonek.sc -95
+KPX v.sc amacron.sc -95
+KPX v.sc abreve.sc -95
+KPX v.sc scaron.sc -25
+KPX v.sc oogonek.sc -45
+KPX v.sc ohorntilde.sc -45
+KPX v.sc ohornhookabove.sc -45
+KPX v.sc ohorngrave.sc -45
+KPX v.sc ohorndotbelow.sc -45
+KPX v.sc ohornacute.sc -45
+KPX v.sc ohookabove.sc -45
+KPX v.sc odotbelow.sc -45
+KPX v.sc ocircumflextilde.sc -45
+KPX v.sc ocircumflexhookabove.sc -45
+KPX v.sc ocircumflexgrave.sc -45
+KPX v.sc ocircumflexdotbelow.sc -45
+KPX v.sc ocircumflexacute.sc -45
+KPX v.sc gcaron.sc -45
+KPX v.sc gacute.sc -45
+KPX v.sc ahookabove.sc -95
+KPX v.sc adotbelow.sc -95
+KPX v.sc acircumflextilde.sc -95
+KPX v.sc acircumflexhookabove.sc -95
+KPX v.sc acircumflexgrave.sc -95
+KPX v.sc acircumflexdotbelow.sc -95
+KPX v.sc acircumflexacute.sc -95
+KPX v.sc abrevehookabove.sc -95
+KPX v.sc abrevegrave.sc -95
+KPX v.sc abrevedotbelow.sc -95
+KPX v.sc abreveacute.sc -95
+KPX v.sc semicolon -110
+KPX v.sc colon -90
+KPX v.sc period -120
+KPX v.sc hyphen -65
+KPX v.sc comma -135
+KPX w.sc oslash.sc -35
+KPX w.sc odieresis.sc -35
+KPX w.sc ccedilla.sc -35
+KPX w.sc ae.sc -65
+KPX w.sc aring.sc -75
+KPX w.sc adieresis.sc -75
+KPX w.sc s.sc -25
+KPX w.sc o.sc -35
+KPX w.sc g.sc -35
+KPX w.sc c.sc -35
+KPX w.sc a.sc -75
+KPX w.sc uni0219.sc -25
+KPX w.sc scircumflex.sc -25
+KPX w.sc scedilla.sc -25
+KPX w.sc sacute.sc -25
+KPX w.sc omacron.sc -35
+KPX w.sc ohungarumlaut.sc -35
+KPX w.sc obreve.sc -35
+KPX w.sc gdotaccent.sc -35
+KPX w.sc gcommaaccent.sc -35
+KPX w.sc gcircumflex.sc -35
+KPX w.sc gbreve.sc -35
+KPX w.sc cdotaccent.sc -35
+KPX w.sc ccircumflex.sc -35
+KPX w.sc ccaron.sc -35
+KPX w.sc cacute.sc -35
+KPX w.sc aeacute.sc -65
+KPX w.sc aogonek.sc -75
+KPX w.sc amacron.sc -75
+KPX w.sc scaron.sc -25
+KPX w.sc oogonek.sc -35
+KPX w.sc gcaron.sc -35
+KPX w.sc gacute.sc -35
+KPX w.sc semicolon -95
+KPX w.sc colon -80
+KPX w.sc period -90
+KPX w.sc hyphen -45
+KPX w.sc comma -105
+KPX x.sc oslash.sc -35
+KPX x.sc odieresis.sc -35
+KPX x.sc otilde.sc -35
+KPX x.sc ocircumflex.sc -35
+KPX x.sc oacute.sc -35
+KPX x.sc ograve.sc -35
+KPX x.sc ccedilla.sc -40
+KPX x.sc q.sc -35
+KPX x.sc o.sc -35
+KPX x.sc c.sc -40
+KPX x.sc omacron.sc -35
+KPX x.sc ohungarumlaut.sc -35
+KPX x.sc obreve.sc -35
+KPX x.sc cdotaccent.sc -40
+KPX x.sc ccircumflex.sc -40
+KPX x.sc ccaron.sc -40
+KPX x.sc cacute.sc -40
+KPX x.sc oogonek.sc -35
+KPX x.sc ohorntilde.sc -35
+KPX x.sc ohornhookabove.sc -35
+KPX x.sc ohorngrave.sc -35
+KPX x.sc ohorndotbelow.sc -35
+KPX x.sc ohornacute.sc -35
+KPX x.sc ohookabove.sc -35
+KPX x.sc odotbelow.sc -35
+KPX x.sc ocircumflexhookabove.sc -35
+KPX x.sc ocircumflexgrave.sc -35
+KPX x.sc ocircumflexdotbelow.sc -35
+KPX x.sc ocircumflexacute.sc -35
+KPX x.sc hyphen -50
+KPX y.sc oslash.sc -45
+KPX y.sc odieresis.sc -45
+KPX y.sc ccedilla.sc -45
+KPX y.sc ae.sc -40
+KPX y.sc aring.sc -45
+KPX y.sc adieresis.sc -45
+KPX y.sc s.sc -25
+KPX y.sc o.sc -45
+KPX y.sc g.sc -45
+KPX y.sc c.sc -45
+KPX y.sc a.sc -45
+KPX y.sc uni0219.sc -25
+KPX y.sc scircumflex.sc -25
+KPX y.sc scedilla.sc -25
+KPX y.sc sacute.sc -25
+KPX y.sc omacron.sc -45
+KPX y.sc ohungarumlaut.sc -45
+KPX y.sc obreve.sc -45
+KPX y.sc gdotaccent.sc -45
+KPX y.sc gcommaaccent.sc -45
+KPX y.sc gcircumflex.sc -45
+KPX y.sc gbreve.sc -45
+KPX y.sc cdotaccent.sc -45
+KPX y.sc ccircumflex.sc -45
+KPX y.sc ccaron.sc -45
+KPX y.sc cacute.sc -45
+KPX y.sc aeacute.sc -40
+KPX y.sc aogonek.sc -45
+KPX y.sc amacron.sc -45
+KPX y.sc scaron.sc -25
+KPX y.sc oogonek.sc -45
+KPX y.sc gcaron.sc -45
+KPX y.sc gacute.sc -45
+KPX y.sc semicolon -110
+KPX y.sc colon -100
+KPX y.sc period -100
+KPX y.sc hyphen -80
+KPX y.sc comma -110
+KPX agrave.sc y.sc -60
+KPX agrave.sc u.sc -50
+KPX agrave.sc o.sc -45
+KPX aacute.sc y.sc -60
+KPX aacute.sc u.sc -50
+KPX aacute.sc t.sc -45
+KPX aacute.sc o.sc -45
+KPX aacute.sc c.sc -45
+KPX acircumflex.sc y.sc -60
+KPX acircumflex.sc u.sc -50
+KPX atilde.sc y.sc -60
+KPX atilde.sc o.sc -45
+KPX adieresis.sc ydieresis.sc -60
+KPX adieresis.sc udieresis.sc -50
+KPX adieresis.sc ucircumflex.sc -50
+KPX adieresis.sc oslash.sc -45
+KPX adieresis.sc odieresis.sc -45
+KPX adieresis.sc ccedilla.sc -45
+KPX adieresis.sc y.sc -60
+KPX adieresis.sc w.sc -65
+KPX adieresis.sc v.sc -95
+KPX adieresis.sc u.sc -50
+KPX adieresis.sc t.sc -45
+KPX adieresis.sc q.sc -45
+KPX adieresis.sc o.sc -45
+KPX adieresis.sc g.sc -45
+KPX adieresis.sc c.sc -45
+KPX adieresis.sc ycircumflex.sc -60
+KPX adieresis.sc wgrave.sc -65
+KPX adieresis.sc wdieresis.sc -65
+KPX adieresis.sc wcircumflex.sc -65
+KPX adieresis.sc wacute.sc -65
+KPX adieresis.sc uring.sc -50
+KPX adieresis.sc uogonek.sc -50
+KPX adieresis.sc umacron.sc -50
+KPX adieresis.sc uhungarumlaut.sc -50
+KPX adieresis.sc ubreve.sc -50
+KPX adieresis.sc uni021B.sc -45
+KPX adieresis.sc tcaron.sc -45
+KPX adieresis.sc omacron.sc -45
+KPX adieresis.sc ohungarumlaut.sc -45
+KPX adieresis.sc obreve.sc -45
+KPX adieresis.sc gdotaccent.sc -45
+KPX adieresis.sc gcommaaccent.sc -45
+KPX adieresis.sc gcircumflex.sc -45
+KPX adieresis.sc gbreve.sc -45
+KPX adieresis.sc cdotaccent.sc -45
+KPX adieresis.sc ccircumflex.sc -45
+KPX adieresis.sc ccaron.sc -45
+KPX adieresis.sc cacute.sc -45
+KPX adieresis.sc oogonek.sc -45
+KPX adieresis.sc gcaron.sc -45
+KPX adieresis.sc gacute.sc -45
+KPX adieresis.sc quotedblright -125
+KPX adieresis.sc quoteright -120
+KPX adieresis.sc period -25
+KPX adieresis.sc hyphen -35
+KPX adieresis.sc comma -35
+KPX aring.sc ydieresis.sc -60
+KPX aring.sc udieresis.sc -50
+KPX aring.sc ucircumflex.sc -50
+KPX aring.sc oslash.sc -45
+KPX aring.sc odieresis.sc -45
+KPX aring.sc ccedilla.sc -45
+KPX aring.sc y.sc -60
+KPX aring.sc w.sc -65
+KPX aring.sc v.sc -95
+KPX aring.sc u.sc -50
+KPX aring.sc t.sc -45
+KPX aring.sc q.sc -45
+KPX aring.sc o.sc -45
+KPX aring.sc g.sc -45
+KPX aring.sc c.sc -45
+KPX aring.sc ycircumflex.sc -60
+KPX aring.sc wgrave.sc -65
+KPX aring.sc wdieresis.sc -65
+KPX aring.sc wcircumflex.sc -65
+KPX aring.sc wacute.sc -65
+KPX aring.sc uring.sc -50
+KPX aring.sc uogonek.sc -50
+KPX aring.sc umacron.sc -50
+KPX aring.sc uhungarumlaut.sc -50
+KPX aring.sc ubreve.sc -50
+KPX aring.sc uni021B.sc -45
+KPX aring.sc tcaron.sc -45
+KPX aring.sc omacron.sc -45
+KPX aring.sc ohungarumlaut.sc -45
+KPX aring.sc obreve.sc -45
+KPX aring.sc gdotaccent.sc -45
+KPX aring.sc gcommaaccent.sc -45
+KPX aring.sc gcircumflex.sc -45
+KPX aring.sc gbreve.sc -45
+KPX aring.sc cdotaccent.sc -45
+KPX aring.sc ccircumflex.sc -45
+KPX aring.sc ccaron.sc -45
+KPX aring.sc cacute.sc -45
+KPX aring.sc oogonek.sc -45
+KPX aring.sc gcaron.sc -45
+KPX aring.sc gacute.sc -45
+KPX aring.sc quotedblright -125
+KPX aring.sc quoteright -120
+KPX aring.sc period -25
+KPX aring.sc hyphen -35
+KPX aring.sc comma -35
+KPX ccedilla.sc oslash.sc -25
+KPX ccedilla.sc odieresis.sc -25
+KPX ccedilla.sc aring.sc -10
+KPX ccedilla.sc adieresis.sc -10
+KPX ccedilla.sc o.sc -25
+KPX ccedilla.sc k.sc -5
+KPX ccedilla.sc h.sc -5
+KPX ccedilla.sc a.sc -10
+KPX ccedilla.sc omacron.sc -25
+KPX ccedilla.sc ohungarumlaut.sc -25
+KPX ccedilla.sc obreve.sc -25
+KPX ccedilla.sc kcommaaccent.sc -5
+KPX ccedilla.sc hcircumflex.sc -5
+KPX ccedilla.sc aogonek.sc -10
+KPX ccedilla.sc amacron.sc -10
+KPX ccedilla.sc oogonek.sc -25
+KPX ntilde.sc oslash.sc -15
+KPX ntilde.sc odieresis.sc -15
+KPX ntilde.sc ccedilla.sc -20
+KPX ntilde.sc ae.sc -20
+KPX ntilde.sc aring.sc -25
+KPX ntilde.sc adieresis.sc -25
+KPX ntilde.sc o.sc -15
+KPX ntilde.sc g.sc -20
+KPX ntilde.sc c.sc -20
+KPX ntilde.sc a.sc -25
+KPX ntilde.sc omacron.sc -15
+KPX ntilde.sc ohungarumlaut.sc -15
+KPX ntilde.sc obreve.sc -15
+KPX ntilde.sc gdotaccent.sc -20
+KPX ntilde.sc gcommaaccent.sc -20
+KPX ntilde.sc gcircumflex.sc -20
+KPX ntilde.sc gbreve.sc -20
+KPX ntilde.sc cdotaccent.sc -20
+KPX ntilde.sc ccircumflex.sc -20
+KPX ntilde.sc ccaron.sc -20
+KPX ntilde.sc cacute.sc -20
+KPX ntilde.sc aeacute.sc -20
+KPX ntilde.sc aogonek.sc -25
+KPX ntilde.sc amacron.sc -25
+KPX ntilde.sc oogonek.sc -15
+KPX ntilde.sc gcaron.sc -20
+KPX ntilde.sc gacute.sc -20
+KPX ntilde.sc period -30
+KPX ntilde.sc comma -45
+KPX ograve.sc a.sc -50
+KPX oacute.sc t.sc -10
+KPX oacute.sc a.sc -50
+KPX odieresis.sc ydieresis.sc -35
+KPX odieresis.sc ae.sc -45
+KPX odieresis.sc aring.sc -50
+KPX odieresis.sc adieresis.sc -50
+KPX odieresis.sc y.sc -35
+KPX odieresis.sc x.sc -40
+KPX odieresis.sc w.sc -30
+KPX odieresis.sc v.sc -35
+KPX odieresis.sc t.sc -10
+KPX odieresis.sc a.sc -50
+KPX odieresis.sc ycircumflex.sc -35
+KPX odieresis.sc wgrave.sc -30
+KPX odieresis.sc wdieresis.sc -30
+KPX odieresis.sc wcircumflex.sc -30
+KPX odieresis.sc wacute.sc -30
+KPX odieresis.sc uni021B.sc -10
+KPX odieresis.sc tcaron.sc -10
+KPX odieresis.sc aeacute.sc -45
+KPX odieresis.sc aogonek.sc -50
+KPX odieresis.sc amacron.sc -50
+KPX oslash.sc ydieresis.sc -35
+KPX oslash.sc ae.sc -45
+KPX oslash.sc aring.sc -50
+KPX oslash.sc adieresis.sc -50
+KPX oslash.sc y.sc -35
+KPX oslash.sc x.sc -40
+KPX oslash.sc w.sc -30
+KPX oslash.sc v.sc -35
+KPX oslash.sc t.sc -10
+KPX oslash.sc a.sc -50
+KPX oslash.sc ycircumflex.sc -35
+KPX oslash.sc wgrave.sc -30
+KPX oslash.sc wdieresis.sc -30
+KPX oslash.sc wcircumflex.sc -30
+KPX oslash.sc wacute.sc -30
+KPX oslash.sc uni021B.sc -10
+KPX oslash.sc tcaron.sc -10
+KPX oslash.sc aeacute.sc -45
+KPX oslash.sc aogonek.sc -50
+KPX oslash.sc amacron.sc -50
+KPX ugrave.sc a.sc -55
+KPX uacute.sc a.sc -55
+KPX ucircumflex.sc ae.sc -45
+KPX ucircumflex.sc aring.sc -55
+KPX ucircumflex.sc adieresis.sc -55
+KPX ucircumflex.sc a.sc -55
+KPX ucircumflex.sc aeacute.sc -45
+KPX ucircumflex.sc aogonek.sc -55
+KPX ucircumflex.sc amacron.sc -55
+KPX ucircumflex.sc period -50
+KPX ucircumflex.sc comma -65
+KPX udieresis.sc ae.sc -45
+KPX udieresis.sc aring.sc -55
+KPX udieresis.sc adieresis.sc -55
+KPX udieresis.sc a.sc -55
+KPX udieresis.sc aeacute.sc -45
+KPX udieresis.sc aogonek.sc -55
+KPX udieresis.sc amacron.sc -55
+KPX udieresis.sc period -50
+KPX udieresis.sc comma -65
+KPX yacute.sc c.sc -45
+KPX ydieresis.sc oslash.sc -45
+KPX ydieresis.sc odieresis.sc -45
+KPX ydieresis.sc ccedilla.sc -45
+KPX ydieresis.sc ae.sc -40
+KPX ydieresis.sc aring.sc -45
+KPX ydieresis.sc adieresis.sc -45
+KPX ydieresis.sc s.sc -25
+KPX ydieresis.sc o.sc -45
+KPX ydieresis.sc g.sc -45
+KPX ydieresis.sc c.sc -45
+KPX ydieresis.sc a.sc -45
+KPX ydieresis.sc uni0219.sc -25
+KPX ydieresis.sc scircumflex.sc -25
+KPX ydieresis.sc scedilla.sc -25
+KPX ydieresis.sc sacute.sc -25
+KPX ydieresis.sc omacron.sc -45
+KPX ydieresis.sc ohungarumlaut.sc -45
+KPX ydieresis.sc obreve.sc -45
+KPX ydieresis.sc gdotaccent.sc -45
+KPX ydieresis.sc gcommaaccent.sc -45
+KPX ydieresis.sc gcircumflex.sc -45
+KPX ydieresis.sc gbreve.sc -45
+KPX ydieresis.sc cdotaccent.sc -45
+KPX ydieresis.sc ccircumflex.sc -45
+KPX ydieresis.sc ccaron.sc -45
+KPX ydieresis.sc cacute.sc -45
+KPX ydieresis.sc aeacute.sc -40
+KPX ydieresis.sc aogonek.sc -45
+KPX ydieresis.sc amacron.sc -45
+KPX ydieresis.sc scaron.sc -25
+KPX ydieresis.sc oogonek.sc -45
+KPX ydieresis.sc gcaron.sc -45
+KPX ydieresis.sc gacute.sc -45
+KPX ydieresis.sc semicolon -110
+KPX ydieresis.sc colon -100
+KPX ydieresis.sc period -100
+KPX ydieresis.sc hyphen -80
+KPX ydieresis.sc comma -110
+KPX ff ohorndotbelow -10
+KPX ff ohorntilde -10
+KPX ff ohornhookabove -10
+KPX ff ohorngrave -10
+KPX ff ohornacute -10
+KPX ff ocircumflexdotbelow -10
+KPX ff ohookabove -10
+KPX ff ihookabove 10
+KPX ff ecircumflexdotbelow -10
+KPX ff etilde -10
+KPX ff ehookabove -10
+KPX ff abrevedotbelow -5
+KPX ff acircumflexdotbelow -5
+KPX ff ahookabove -5
+KPX ff uni021B 10
+KPX ff oogonek -15
+KPX ff tcaron 5
+KPX ff oe -15
+KPX ff ohungarumlaut -10
+KPX ff obreve -10
+KPX ff omacron -10
+KPX ff lslash 25
+KPX ff lcaron 15
+KPX ff lcommaaccent 25
+KPX ff lacute 20
+KPX ff jcircumflex 15
+KPX ff iogonek 15
+KPX ff ibreve 10
+KPX ff imacron 10
+KPX ff itilde 10
+KPX ff ecaron -10
+KPX ff eogonek -15
+KPX ff edotaccent -10
+KPX ff ebreve -10
+KPX ff emacron -10
+KPX ff aogonek -10
+KPX ff abreve -5
+KPX ff amacron -5
+KPX ff oslash -15
+KPX ff odieresis -10
+KPX ff otilde -10
+KPX ff ocircumflex -10
+KPX ff oacute -10
+KPX ff ograve -10
+KPX ff idieresis 10
+KPX ff icircumflex 10
+KPX ff iacute 10
+KPX ff igrave 10
+KPX ff edieresis -10
+KPX ff ecircumflex -10
+KPX ff eacute -10
+KPX ff egrave -10
+KPX ff aring -5
+KPX ff adieresis -5
+KPX ff atilde -5
+KPX ff acircumflex -5
+KPX ff aacute -10
+KPX ff agrave -5
+KPX ff t 10
+KPX ff o -15
+KPX ff l 25
+KPX ff j 30
+KPX ff i 15
+KPX ff e -15
+KPX ff a -10
+KPX fi jacute -15
+KPX fi uni021A -30
+KPX fi Tcaron -30
+KPX fi jcircumflex -15
+KPX fi j -15
+KPX fi T -30
+KPX fi T_h -30
+KPX fl ycircumflex -25
+KPX fl ydieresis -25
+KPX fl yacute -25
+KPX fl y -25
+KPX fl v -20
+KPX ffi jacute -15
+KPX ffi uni021A -30
+KPX ffi Tcaron -30
+KPX ffi jcircumflex -15
+KPX ffi j -15
+KPX ffi T -30
+KPX ffi T_h -30
+KPX ffl ycircumflex -25
+KPX ffl ydieresis -25
+KPX ffl yacute -25
+KPX ffl y -25
+KPX ffl v -20
+KPX T_h quoteright -35
+KPX T_h ycircumflex -35
+KPX T_h ydieresis -35
+KPX T_h y -35
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/fonts/newpx/doc/newpxdoc.pdf b/fonts/newpx/doc/newpxdoc.pdf
index 811a0a966b..ce4a919c31 100644
--- a/fonts/newpx/doc/newpxdoc.pdf
+++ b/fonts/newpx/doc/newpxdoc.pdf
Binary files differ
diff --git a/fonts/newpx/doc/newpxdoc.tex b/fonts/newpx/doc/newpxdoc.tex
index ba5cc4a189..1c8bcafcd3 100644
--- a/fonts/newpx/doc/newpxdoc.tex
+++ b/fonts/newpx/doc/newpxdoc.tex
@@ -1,5 +1,5 @@
% !TEX TS-program = pdflatexmk
-\documentclass[11pt]{article}
+\documentclass[11pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage[parfill]{parskip}% Begin paragraphs with an empty line rather than an indent
\pdfmapfile{=newtx.map}
@@ -11,7 +11,7 @@
\InputIfFileExists{glyphtounicode-cmr.tex}{}{}
\InputIfFileExists{glyphtounicode-ntx.tex}{}{}
\usepackage{fonttable}
-\usepackage{amsthm}
+\usepackage{amsthm}
\newtheoremstyle{oldplain}
{\topsep} % ABOVESPACE
{\topsep} % BELOWSPACE
@@ -30,7 +30,8 @@
%SetFonts
% newpx text and math
\linespread{1.05}
-\usepackage[largesc,theoremfont]{newpxtext}
+%\usepackage[largesc,theoremfont]{newpxtext}
+\usepackage[theoremfont,trueslanted]{newpxtext}
\usepackage[scaled=1.05]{nimbusmononarrow}
%\usepackage[scaled=1.05,zerostyle=a]{newtxtt}
\usepackage{textcomp}
@@ -89,7 +90,18 @@ the new package is split into separate text and math packages that do not need t
\item Sans serif is by default taken from TeXGyreHeros, a Helvetica clone, and by default at 94\% of the scale factor (set by {\tt scaled}, default value {\tt1}). The option {\tt helvratio=.98} will change that to 98\%. As of newpx version 1.415, there is an option {\tt nohelv} that prevents this loading.
\item New math accents such as \verb|\widearc| have been introduced in tandem with the {\tt newtx} package, where they are documented.
\end{itemize}
+
+
\section{Text mode options and macros}
+\textsc{Important changes as of version 1.42}\\
+Option {\tt theoremfont} was reimplemented using a new font family, {\tt npxth} instead of abusing \verb|\textsl|. By default, users of {\tt theoremfont} will see no change in its functionality, including the use of the macro \verb|\textsl| to output italics with upright punctuation. A new option, {\tt trueslanted}, to {\tt newpxtext} has the following effects:
+\begin{itemize}
+\item
+\verb|\textsl| now outputs slanted text rather than italics with upright punctuation text, but not affecting the usage of the {\tt theoremfont} option to {\tt newpxtext}.
+\item the former behavior of \verb|\textsl| is now available through the new macro \verb|\textth|, \textsc{aka} \verb|\textthit|.
+\item \verb|\pagestyle{headings}| now functions as intended with slanted rather than upright figures in the headers.
+\end{itemize}
+
The text mode environment invoked by
\begin{verbatim}
\usepackage{newpxtext}
@@ -111,7 +123,7 @@ As of version 1.415, the new option {\tt nohelv} prevents the loading of the def
As described above, option {\tt largesc} increases the size of small caps by about 8\%.
-Option {\tt defaultsups} (same effect as {\tt defaultsups=true}) forces the package to use the \LaTeX\ default footnote markers (or, at least, those in force when the package is loaded) instead of preferred by the package---Palatino (clone) superior figures instead of spindly ordinary Palatino lining figures reduced to about 70\%. (Footnote markers in minipages use the default lowercase alphabetic characters, unless otherwise specified by redefining \verb|\thempfootnote|.) For better control over position and size of footnote markers, use the {\tt superiors} package after loading {\tt newpxtext}.
+Option {\tt defaultsups} (same effect as {\tt defaultsups=true}) forces the package to use the \LaTeX\ default footnote markers (or, at least, those in force when the package is loaded) instead of those preferred by the package---Palatino (clone) superior figures instead of spindly ordinary Palatino lining figures reduced to about 70\%. (Footnote markers in minipages use the default lowercase alphabetic characters, unless otherwise specified by redefining \verb|\thempfootnote|.) For better control over position and size of footnote markers, use the {\tt superiors} package after loading {\tt newpxtext}.
The {\tt theoremfont} option changes the default font used for the {\tt plain} theorem style of {\tt amsthm}, keeping italic text but substituting upright figures and punctuation. For example, with this option, you get theorem statements like this:
@@ -123,7 +135,7 @@ Compare this to traditional {\tt plain} theorem style of the same text:
This is Theorem Italic: text numbers are upright---12345; punctuation is in many cases upright (also, parens, braces \{\} and brackets []). What about question marks and exclamations? Also upright! [These fit better with math mode punctuation and figures, like: for all $x\in[0,1]$, let $f(x)\coloneq \exp(\alpha x)$].
\end{oldthm}
-If you are using another theorem package (e.g., ntheorem, theorem) you will have to add your own descriptors as specified in the its documentation and set the body font to \verb|\slshape|.
+If you are using another theorem package (e.g., ntheorem, theorem) you will have to add your own descriptors as specified in the its documentation and set the body font to \verb|\thfamily|.
Superior letters and figures may be called with either \verb|{\sustyle ...}| or \verb|\textsu{...}|, so you can emulate $18$\textsu{th} century orthography such as J\textsu{os} W\textsu{m} Smith, or print French style with , e.g., $1$\textsu{i\`ere}, M\textsu{me} Dubois or M\textsu{lle} D'Orl\'eans.
@@ -155,12 +167,12 @@ You should normally load {\tt babel} before loading {\tt newpxtext} in order for
\begin{verbatim}
\usepackage[greek.polutonico,english]{babel}
% the next line makes text figures proportional, oldstyle, while math uses lining figures
-\usepackage[theoremfont,largesc,tighter,p,osf]{newpxtext}
+\usepackage[theoremfont,trueslanted,largesc,tighter,p,osf]{newpxtext}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[varqu,varl]{inconsolata}
-\usepackage{amsmath,amsthm}
-\usepackage[bigdelims,vvarbb]{newpxmath}
+\usepackage{amsthm}
+\usepackage[vvarbb]{newpxmath}
% option vvarbb gives you stix blackboard bold
\linespread{1.05}
\end{verbatim}
diff --git a/fonts/newpx/map/newpx.map b/fonts/newpx/map/newpx.map
index 4154d0d00e..48bae743f8 100644
--- a/fonts/newpx/map/newpx.map
+++ b/fonts/newpx/map/newpx.map
@@ -99,12 +99,6 @@ zpl-Italic-tlf-sc-ot1 TeXGyrePagellaX-Italic " encntx-ot1-tlf-sc ReEncodeFont "
zpl-Italic-osf-sc-ot1 TeXGyrePagellaX-Italic " encntx-ot1-osf-sc ReEncodeFont " <[ntx-ot1-osf-sc.enc <zplri.pfb
zpl-Italic-lf-sc-ot1 TeXGyrePagellaX-Italic " encntx-ot1-lf-sc ReEncodeFont " <[ntx-ot1-lf-sc.enc <zplri.pfb
zpl-Italic-tosf-sc-ot1 TeXGyrePagellaX-Italic " encntx-ot1-tosf-sc ReEncodeFont " <[ntx-ot1-tosf-sc.enc <zplri.pfb
-zpl-Italic-tlf-th-t1 TeXGyrePagellaX-Italic " encntx-ecth-tlf ReEncodeFont " <[ntx-ecth-tlf.enc <zplri.pfb
-zpl-Italic-osf-th-t1 TeXGyrePagellaX-Italic " encntx-ecth-osf ReEncodeFont " <[ntx-ecth-osf.enc <zplri.pfb
-zpl-Italic-tlf-th-ot1 TeXGyrePagellaX-Italic " encntx-ot1-th-tlf ReEncodeFont " <ntx-ot1-th-tlf.enc <zplri.pfb
-zpl-Italic-osf-th-ot1 TeXGyrePagellaX-Italic " encntx-ot1-th-osf ReEncodeFont " <ntx-ot1-th-osf.enc <zplri.pfb
-zpl-Italic-tlf-th-ly1 TeXGyrePagellaX-Italic " encntx-texnansi-th-tlf ReEncodeFont " <ntx-texnansi-th-tlf.enc <zplri.pfb
-zpl-Italic-osf-th-ly1 TeXGyrePagellaX-Italic " encntx-texnansi-th-osf ReEncodeFont " <ntx-texnansi-th-osf.enc <zplri.pfb
zpl-Bold-osf-scl-ot1 zplb " encntx-ot1-osf-sc ReEncodeFont " <[ntx-ot1-osf-sc.enc <zplb.pfb
zpl-Bold-lf-scl-ot1 zplb " encntx-ot1-lf-sc ReEncodeFont " <[ntx-ot1-lf-sc.enc <zplb.pfb
zpl-Bold-tosf-scl-ot1 zplb " encntx-ot1-tosf-sc ReEncodeFont " <[ntx-ot1-tosf-sc.enc <zplb.pfb
@@ -167,6 +161,64 @@ zplsups-BoldItalic-ot1 npxsups-BoldItalic " ntxsupsOT1Encoding ReEncodeFont " <n
zplsups-BoldItalic-t1 npxsups-BoldItalic " ntxsupsT1Encoding ReEncodeFont " <npxsups_t1.enc <npxsups-BoldItalic.pfb
zplsups-BoldItalic-ly1 npxsups-BoldItalic " ntxsupsLY1Encoding ReEncodeFont " <npxsups_ly1.enc <npxsups-BoldItalic.pfb
+zplth-Italic-tlf-t1 TeXGyrePagellaX-Italic " encntx-ecth-tlf ReEncodeFont " <[ntx-ecth-tlf.enc <zplri.pfb
+zplth-Italic-osf-t1 TeXGyrePagellaX-Italic " encntx-ecth-osf ReEncodeFont " <[ntx-ecth-osf.enc <zplri.pfb
+zplth-Italic-tlf-ot1 TeXGyrePagellaX-Italic " encntx-ot1-th-tlf ReEncodeFont " <ntx-ot1-th-tlf.enc <zplri.pfb
+zplth-Italic-osf-ot1 TeXGyrePagellaX-Italic " encntx-ot1-th-osf ReEncodeFont " <ntx-ot1-th-osf.enc <zplri.pfb
+zplth-Italic-tlf-ly1 TeXGyrePagellaX-Italic " encntx-texnansi-th-tlf ReEncodeFont " <ntx-texnansi-th-tlf.enc <zplri.pfb
+zplth-Italic-osf-ly1 TeXGyrePagellaX-Italic " encntx-texnansi-th-osf ReEncodeFont " <ntx-texnansi-th-osf.enc <zplri.pfb
+
+% Slanted, added 2021-05-21
+zpl-Slanted-tlf-t1 TeXGyrePagellaX-Slanted " encntx-ec-tlf ReEncodeFont " <ntx-ec-tlf.enc <zplrsl.pfb
+zpl-Slanted-osf-t1 TeXGyrePagellaX-Slanted " encntx-ec-osf ReEncodeFont " <ntx-ec-osf.enc <zplrsl.pfb
+zpl-Slanted-lf-t1 TeXGyrePagellaX-Slanted " encntx-ec-lf ReEncodeFont " <ntx-ec-lf.enc <zplrsl.pfb
+zpl-Slanted-tosf-t1 TeXGyrePagellaX-Slanted " encntx-ec-tosf ReEncodeFont " <ntx-ec-tosf.enc <zplrsl.pfb
+zpl-Slanted-tlf-sc-t1 TeXGyrePagellaX-Slanted " encntx-ec-tlf-sc ReEncodeFont " <ntx-ec-tlf-sc.enc <zplrsl.pfb
+zpl-Slanted-osf-sc-t1 TeXGyrePagellaX-Slanted " encntx-ec-osf-sc ReEncodeFont " <ntx-ec-osf-sc.enc <zplrsl.pfb
+zpl-Slanted-lf-sc-t1 TeXGyrePagellaX-Slanted " encntx-ec-lf-sc ReEncodeFont " <ntx-ec-lf-sc.enc <zplrsl.pfb
+zpl-Slanted-tosf-sc-t1 TeXGyrePagellaX-Slanted " encntx-ec-tosf-sc ReEncodeFont " <ntx-ec-tosf-sc.enc <zplrsl.pfb
+zpl-Slanted-tlf-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-tlf ReEncodeFont " <ntx-texnansi-tlf.enc <zplrsl.pfb
+zpl-Slanted-osf-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-osf ReEncodeFont " <ntx-texnansi-osf.enc <zplrsl.pfb
+zpl-Slanted-lf-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-lf ReEncodeFont " <ntx-texnansi-lf.enc <zplrsl.pfb
+zpl-Slanted-tosf-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-tosf ReEncodeFont " <ntx-texnansi-tosf.enc <zplrsl.pfb
+zpl-Slanted-tlf-sc-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-tosf-sc ReEncodeFont " <ntx-texnansi-tlf-sc.enc <zplrsl.pfb
+zpl-Slanted-osf-sc-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-osf-sc ReEncodeFont " <ntx-texnansi-osf-sc.enc <zplrsl.pfb
+zpl-Slanted-lf-sc-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-lf-sc ReEncodeFont " <ntx-texnansi-lf-sc.enc <zplrsl.pfb
+zpl-Slanted-tosf-sc-ly1 TeXGyrePagellaX-Slanted " encntx-texnansi-tosf-sc ReEncodeFont " <ntx-texnansi-tosf-sc.enc <zplrsl.pfb
+zpl-Slanted-tlf-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-tlf ReEncodeFont " <ntx-ot1-tlf.enc <zplrsl.pfb
+zpl-Slanted-osf-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-osf ReEncodeFont " <ntx-ot1-osf.enc <zplrsl.pfb
+zpl-Slanted-lf-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-lf ReEncodeFont " <ntx-ot1-lf.enc <zplrsl.pfb
+zpl-Slanted-tosf-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-tosf ReEncodeFont " <ntx-ot1-tosf.enc <zplrsl.pfb
+zpl-Slanted-tlf-sc-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-tlf-sc ReEncodeFont " <ntx-ot1-tlf-sc.enc <zplrsl.pfb
+zpl-Slanted-osf-sc-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-osf-sc ReEncodeFont " <ntx-ot1-osf-sc.enc <zplrsl.pfb
+zpl-Slanted-lf-sc-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-lf-sc ReEncodeFont " <ntx-ot1-lf-sc.enc <zplrsl.pfb
+zpl-Slanted-tosf-sc-ot1 TeXGyrePagellaX-Slanted " encntx-ot1-tosf-sc ReEncodeFont " <ntx-ot1-tosf-sc.enc <zplrsl.pfb
+zpl-BoldSlanted-tlf-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-tlf ReEncodeFont " <ntx-ec-tlf.enc <zplbsl.pfb
+zpl-BoldSlanted-osf-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-osf ReEncodeFont " <ntx-ec-osf.enc <zplbsl.pfb
+zpl-BoldSlanted-lf-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-lf ReEncodeFont " <ntx-ec-lf.enc <zplbsl.pfb
+zpl-BoldSlanted-tosf-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-tosf ReEncodeFont " <ntx-ec-tosf.enc <zplbsl.pfb
+zpl-BoldSlanted-tlf-sc-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-tlf-sc ReEncodeFont " <ntx-ec-tlf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-osf-sc-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-osf-sc ReEncodeFont " <ntx-ec-osf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-lf-sc-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-lf-sc ReEncodeFont " <ntx-ec-lf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-tosf-sc-t1 TeXGyrePagellaX-BoldSlanted " encntx-ec-tosf-sc ReEncodeFont " <ntx-ec-tosf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-tlf-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-tlf ReEncodeFont " <ntx-texnansi-tlf.enc <zplbsl.pfb
+zpl-BoldSlanted-osf-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-osf ReEncodeFont " <ntx-texnansi-osf.enc <zplbsl.pfb
+zpl-BoldSlanted-lf-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-lf ReEncodeFont " <ntx-texnansi-lf.enc <zplbsl.pfb
+zpl-BoldSlanted-tosf-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-tosf ReEncodeFont " <ntx-texnansi-tosf.enc <zplbsl.pfb
+zpl-BoldSlanted-tlf-sc-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-tosf-sc ReEncodeFont " <ntx-texnansi-tlf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-osf-sc-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-osf-sc ReEncodeFont " <ntx-texnansi-osf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-lf-sc-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-lf-sc ReEncodeFont " <ntx-texnansi-lf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-tosf-sc-ly1 TeXGyrePagellaX-BoldSlanted " encntx-texnansi-tosf-sc ReEncodeFont " <ntx-texnansi-tosf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-tlf-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-tlf ReEncodeFont " <ntx-ot1-tlf.enc <zplbsl.pfb
+zpl-BoldSlanted-osf-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-osf ReEncodeFont " <ntx-ot1-osf.enc <zplbsl.pfb
+zpl-BoldSlanted-lf-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-lf ReEncodeFont " <ntx-ot1-lf.enc <zplbsl.pfb
+zpl-BoldSlanted-tosf-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-tosf ReEncodeFont " <ntx-ot1-tosf.enc <zplbsl.pfb
+zpl-BoldSlanted-tlf-sc-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-tlf-sc ReEncodeFont " <ntx-ot1-tlf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-osf-sc-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-osf-sc ReEncodeFont " <ntx-ot1-osf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-lf-sc-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-lf-sc ReEncodeFont " <ntx-ot1-lf-sc.enc <zplbsl.pfb
+zpl-BoldSlanted-tosf-sc-ot1 TeXGyrePagellaX-BoldSlanted " encntx-ot1-tosf-sc ReEncodeFont " <ntx-ot1-tosf-sc.enc <zplbsl.pfb
+
+
NewPXMI NewPXMI <NewPXMI.pfb
NewPXMI_gnu NewPXMI_gnu <NewPXMI_gnu.pfb
NewPXBMI_gnu NewPXBMI_gnu <NewPXBMI_gnu.pfb
diff --git a/fonts/newpx/tex/ly1zpllf.fd b/fonts/newpx/tex/ly1zpllf.fd
index 813c8a8e28..015ec40325 100644
--- a/fonts/newpx/tex/ly1zpllf.fd
+++ b/fonts/newpx/tex/ly1zpllf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ly1zpllf.fd}[2015/01/17 v1.0 font definition file for LY1/zpl/lf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{LY1}{zpllf}{bx}{n}{<->ssub * zpllf/b/n}{}
\DeclareFontShape{LY1}{zpllf}{bx}{scit}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{LY1}{zpllf}{bx}{it}{<->ssub * zpllf/b/it}{}
-\DeclareFontShape{LY1}{zpllf}{m}{sl}{<-> \zpl@scaled zpl-Italic-tlf-th-ly1}{}
-\DeclareFontShape{LY1}{zpllf}{b}{sl}{<->ssub * zpllf/b/it}{}
-\DeclareFontShape{LY1}{zpllf}{bx}{sl}{<->ssub * zpllf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{LY1}{zpllf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-lf-ly1}{}
+ \DeclareFontShape{LY1}{zpllf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-lf-ly1}{}
+ \DeclareFontShape{LY1}{zpllf}{bx}{sl}{<->ssub * zpllf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{LY1}{zpllf}{m}{sl}{<-> \zpl@scaled zplth-Italic-tlf-ly1}{}
+ \DeclareFontShape{LY1}{zpllf}{b}{sl}{<->ssub * zpllf/m/sl}{}
+ \DeclareFontShape{LY1}{zpllf}{bx}{sl}{<->ssub * zpllf/m/sl}{}
+\fi
\DeclareFontShape{LY1}{zpllf}{b}{scsl}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{LY1}{zpllf}{bx}{scsl}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{LY1}{zpllf}{m}{scsl}{<->ssub * zpllf/m/scit}{}
diff --git a/fonts/newpx/tex/ly1zplosf.fd b/fonts/newpx/tex/ly1zplosf.fd
index f3e136c041..fb669ea1b1 100644
--- a/fonts/newpx/tex/ly1zplosf.fd
+++ b/fonts/newpx/tex/ly1zplosf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ly1zplosf.fd}[2015/01/17 v1.0 font definition file for LY1/zpl/osf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{LY1}{zplosf}{bx}{n}{<->ssub * zplosf/b/n}{}
\DeclareFontShape{LY1}{zplosf}{bx}{scit}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{LY1}{zplosf}{bx}{it}{<->ssub * zplosf/b/it}{}
-\DeclareFontShape{LY1}{zplosf}{m}{sl}{<-> \zpl@scaled zpl-Italic-osf-th-ly1}{}
-\DeclareFontShape{LY1}{zplosf}{b}{sl}{<->ssub * zplosf/b/it}{}
-\DeclareFontShape{LY1}{zplosf}{bx}{sl}{<->ssub * zplosf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{LY1}{zplosf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-osf-ly1}{}
+ \DeclareFontShape{LY1}{zplosf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-osf-ly1}{}
+ \DeclareFontShape{LY1}{zplosf}{bx}{sl}{<->ssub * zplosf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{LY1}{zplosf}{m}{sl}{<-> \zpl@scaled zplth-Italic-osf-ly1}{}
+ \DeclareFontShape{LY1}{zplosf}{b}{sl}{<->ssub * zplosf/m/sl}{}
+ \DeclareFontShape{LY1}{zplosf}{bx}{sl}{<->ssub * zplosf/m/sl}{}
+\fi
\DeclareFontShape{LY1}{zplosf}{b}{scsl}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{LY1}{zplosf}{bx}{scsl}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{LY1}{zplosf}{m}{scsl}{<->ssub * zplosf/m/scit}{}
diff --git a/fonts/newpx/tex/ly1zplth-lf.fd b/fonts/newpx/tex/ly1zplth-lf.fd
new file mode 100644
index 0000000000..5a931f378b
--- /dev/null
+++ b/fonts/newpx/tex/ly1zplth-lf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ly1zplth-lf.fd}[2021/05/07 v1.0 font definition file for LY1/zplth/lf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{LY1}{zplth-lf}{\zpl@spacing}
+\DeclareFontShape{LY1}{zplth-lf}{m}{it}{<-> \zpl@scaled zplth-Italic-tlf-ly1}{}
+\DeclareFontShape{LY1}{zplth-lf}{m}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{m}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{m}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{b}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{bx}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{b}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{bx}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{b}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{bx}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{b}{it}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{bx}{it}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{m}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{b}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{bx}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{b}{scsl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{bx}{scsl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{LY1}{zplth-lf}{m}{scsl}{<->ssub * zplth-lf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ly1zplth-osf.fd b/fonts/newpx/tex/ly1zplth-osf.fd
new file mode 100644
index 0000000000..850dde690b
--- /dev/null
+++ b/fonts/newpx/tex/ly1zplth-osf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ly1zplth-osf.fd}[2021/05/07 v1.0 font definition file for LY1/zplth/osf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{LY1}{zplth-osf}{\zpl@spacing}
+\DeclareFontShape{LY1}{zplth-osf}{m}{it}{<-> \zpl@scaled zplth-Italic-osf-ly1}{}
+\DeclareFontShape{LY1}{zplth-osf}{m}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{m}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{m}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{b}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{bx}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{b}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{bx}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{b}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{bx}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{b}{it}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{bx}{it}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{m}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{b}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{bx}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{b}{scsl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{bx}{scsl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{LY1}{zplth-osf}{m}{scsl}{<->ssub * zplth-osf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ly1zplth-tlf.fd b/fonts/newpx/tex/ly1zplth-tlf.fd
new file mode 100644
index 0000000000..6f55f125a6
--- /dev/null
+++ b/fonts/newpx/tex/ly1zplth-tlf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ly1zplth-tlf.fd}[2021/05/06 v1.0 font definition file for LY1/zplth/tlf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{LY1}{zplth-tlf}{\zpl@spacing}
+\DeclareFontShape{LY1}{zplth-tlf}{m}{it}{<-> \zpl@scaled zplth-Italic-tlf-ly1}{}
+\DeclareFontShape{LY1}{zplth-tlf}{m}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{m}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{m}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{b}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{bx}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{b}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{bx}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{b}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{bx}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{b}{it}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{bx}{it}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{m}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{b}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{bx}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{b}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{bx}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tlf}{m}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ly1zplth-tosf.fd b/fonts/newpx/tex/ly1zplth-tosf.fd
new file mode 100644
index 0000000000..e16756124e
--- /dev/null
+++ b/fonts/newpx/tex/ly1zplth-tosf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ly1zplth-tosf.fd}[2021/05/07 v1.0 font definition file for LY1/zplth/tosf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{LY1}{zplth-tosf}{\zpl@spacing}
+\DeclareFontShape{LY1}{zplth-tosf}{m}{it}{<-> \zpl@scaled zplth-Italic-osf-ly1}{}
+\DeclareFontShape{LY1}{zplth-tosf}{m}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{m}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{m}{scit}{<-> ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{b}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{bx}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{b}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{bx}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{b}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{bx}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{b}{it}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{bx}{it}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{m}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{b}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{bx}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{b}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{bx}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{LY1}{zplth-tosf}{m}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ly1zpltlf.fd b/fonts/newpx/tex/ly1zpltlf.fd
index 9e2d9d4a47..041ab7cb16 100644
--- a/fonts/newpx/tex/ly1zpltlf.fd
+++ b/fonts/newpx/tex/ly1zpltlf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ly1zpltlf.fd}[2015/01/17 v1.0 font definition file for LY1/zpl/tlf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{LY1}{zpltlf}{bx}{n}{<->ssub * zpltlf/b/n}{}
\DeclareFontShape{LY1}{zpltlf}{bx}{scit}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{LY1}{zpltlf}{bx}{it}{<->ssub * zpltlf/b/it}{}
-\DeclareFontShape{LY1}{zpltlf}{m}{sl}{<-> \zpl@scaled zpl-Italic-tlf-th-ly1}{}
-\DeclareFontShape{LY1}{zpltlf}{b}{sl}{<->ssub * zpltlf/b/it}{}
-\DeclareFontShape{LY1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{LY1}{zpltlf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-tlf-ly1}{}
+ \DeclareFontShape{LY1}{zpltlf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-tlf-ly1}{}
+ \DeclareFontShape{LY1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{LY1}{zpltlf}{m}{sl}{<-> \zpl@scaled zplth-Italic-tlf-ly1}{}
+ \DeclareFontShape{LY1}{zpltlf}{b}{sl}{<->ssub * zpltlf/m/sl}{}
+ \DeclareFontShape{LY1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/m/sl}{}
+\fi
\DeclareFontShape{LY1}{zpltlf}{b}{scsl}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{LY1}{zpltlf}{bx}{scsl}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{LY1}{zpltlf}{m}{scsl}{<->ssub * zpltlf/m/scit}{}
diff --git a/fonts/newpx/tex/ly1zpltosf.fd b/fonts/newpx/tex/ly1zpltosf.fd
index af826e3c4b..178c165a92 100644
--- a/fonts/newpx/tex/ly1zpltosf.fd
+++ b/fonts/newpx/tex/ly1zpltosf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ly1zpltosf.fd}[2015/02/07 v1.0 font definition file for LY1/zpl/tosf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -23,9 +25,15 @@
\DeclareFontShape{LY1}{zpltosf}{bx}{n}{<->ssub * zpltosf/b/n}{}
\DeclareFontShape{LY1}{zpltosf}{bx}{scit}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{LY1}{zpltosf}{bx}{it}{<->ssub * zpltosf/b/it}{}
-\DeclareFontShape{LY1}{zpltosf}{m}{sl}{<-> \zpl@scaled zpl-Italic-osf-th-ly1}{}
-\DeclareFontShape{LY1}{zpltosf}{b}{sl}{<->ssub * zpltosf/b/it}{}
-\DeclareFontShape{LY1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{LY1}{zpltosf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-tosf-ly1}{}
+ \DeclareFontShape{LY1}{zpltosf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-tosf-ly1}{}
+ \DeclareFontShape{LY1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{LY1}{zpltosf}{m}{sl}{<-> \zpl@scaled zplth-Italic-osf-ly1}{}
+ \DeclareFontShape{LY1}{zpltosf}{b}{sl}{<->ssub * zpltosf/m/sl}{}
+ \DeclareFontShape{LY1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/m/sl}{}
+\fi
\DeclareFontShape{LY1}{zpltosf}{b}{scsl}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{LY1}{zpltosf}{bx}{scsl}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{LY1}{zpltosf}{m}{scsl}{<->ssub * zpltosf/m/scit}{}
diff --git a/fonts/newpx/tex/newpxtext.sty b/fonts/newpx/tex/newpxtext.sty
index 776533b974..9abba0ef57 100644
--- a/fonts/newpx/tex/newpxtext.sty
+++ b/fonts/newpx/tex/newpxtext.sty
@@ -8,8 +8,8 @@
% Modified the definition of \k to bypass problem with grouping.
% Text is now directed to an extension of TeXGyrePagella rather than ppl.
-\def\fileversion{1.415}
-\def\filedate{2021/03/22}
+\def\fileversion{1.42}
+\def\filedate{2021/05/20}
\ProvidesPackage{newpxtext}[\filedate\space v\fileversion]
\message{`newpxtext' v\fileversion, \filedate\space Text macros taking advantage of TeXGyre Pagella and its extensions (msharpe)}
@@ -41,6 +41,7 @@
\define@boolkey{zpl}{largesc}[true]{%
\csname zpl@largesc#1\endcsname}
\newif\ifzpl@thrm
+\newif\ifzpl@sl
\define@key{zpl}{helvratio}[0.94]{\def\zpl@helvratio{#1}}
\define@key{zpl}{scaled}[1.0]{\def\zpl@scaled{s*[#1]}%
\def\zpl@scale{#1}}
@@ -56,6 +57,7 @@
\DeclareOption{lining}{\edef\zpl@figurestyle{lf}}
\DeclareOption{lf}{\edef\zpl@figurestyle{lf}}
\DeclareOption{theoremfont}{\zpl@thrmtrue}
+\DeclareOption{trueslanted}{\zpl@sltrue}
\DeclareOption{oldstyle}{\useosf}
\DeclareOption{osf}{\useosf}
\DeclareOption{tabular}{\edef\zpl@figurealign{t}}
@@ -158,7 +160,7 @@
\newtheoremstyle{plain}
{\medskipamount} % ABOVESPACE, was \topsep
{\medskipamount} % BELOWSPACE, was \topsep
- {\slshape} % BODYFONT--\slshape is defined to be \itshape with upright figures and punctuation
+ {\thfamily} % BODYFONT--\thfamily is italic with upright figures and punctuation
{} % INDENT (empty value is the same as 0pt)
{\bfseries} % HEADFONT--you may want to add \tlfstyle so the number is tab lining, regardless of text figure selection
{.} % HEADPUNCT
@@ -233,10 +235,29 @@
%\zpl@figurestyle}
% \normalfont
%\else
- \AtEndPreamble{%
+\DeclareRobustCommand\thfamily % new family for theorem font
+ {\not@math@alphabet\thfamily\relax
+ \fontfamily\thdefault\selectfont}
+\DeclareRobustCommand{\textth}[1]{%
+ {\thfamily #1}%
+}
+\let\textthit\textth
+
+\AtEndPreamble{%
\renewcommand*{\rmdefault}{zpl\zpl@figurealign%
\zpl@figurestyle}
- \normalfont}
+\def\zpl@thfigurestyle{\zpl@figurestyle}
+\ifx\zpl@figurestyle\zpl@dfltfigurestyle
+ \def\zpl@thfigurestyle{tlf}
+\else
+ \def\zpl@thfigurestyle{osf}
+\fi % there just two possible figure styles for the theorem font
+\newcommand*{\thdefault}{zplth-\zpl@thfigurestyle}
+\ifzpl@thrm
+ \theoremstyle{plain}
+ \patchcmd{\th@plain}{\itshape}{\thfamily}{\message{Replaced itshape by thfamily in theorem style plain.}}{\message{Unable to replace itshape by thfamily in theorem style plain.}}
+\fi
+\normalfont}
%\fi
\endinput
diff --git a/fonts/newpx/tex/ot1zpllf.fd b/fonts/newpx/tex/ot1zpllf.fd
index 56a56c47f1..704a790a9b 100644
--- a/fonts/newpx/tex/ot1zpllf.fd
+++ b/fonts/newpx/tex/ot1zpllf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ot1zpllf.fd}[2015/01/19 v1.0 font definition file for OT1/zpl/lf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{OT1}{zpllf}{bx}{n}{<->ssub * zpllf/b/n}{}
\DeclareFontShape{OT1}{zpllf}{bx}{scit}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{OT1}{zpllf}{bx}{it}{<->ssub * zpllf/b/it}{}
-\DeclareFontShape{OT1}{zpllf}{m}{sl}{<-> \zpl@scaled zpl-Italic-tlf-th-ot1}{}
-\DeclareFontShape{OT1}{zpllf}{b}{sl}{<->ssub * zpllf/b/it}{}
-\DeclareFontShape{OT1}{zpllf}{bx}{sl}{<->ssub * zpllf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{OT1}{zpllf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-lf-ot1}{}
+ \DeclareFontShape{OT1}{zpllf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-lf-ot1}{}
+ \DeclareFontShape{OT1}{zpllf}{bx}{sl}{<->ssub * zpllf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{OT1}{zpllf}{m}{sl}{<-> \zpl@scaled zplth-Italic-tlf-ot1}{}
+ \DeclareFontShape{OT1}{zpllf}{b}{sl}{<->ssub * zpllf/m/sl}{}
+ \DeclareFontShape{OT1}{zpllf}{bx}{sl}{<->ssub * zpllf/m/sl}{}
+\fi
\DeclareFontShape{OT1}{zpllf}{b}{scsl}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{OT1}{zpllf}{bx}{scsl}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{OT1}{zpllf}{m}{scsl}{<->ssub * zpllf/m/scit}{}
diff --git a/fonts/newpx/tex/ot1zplosf.fd b/fonts/newpx/tex/ot1zplosf.fd
index 32eaebf039..8a4858e69f 100644
--- a/fonts/newpx/tex/ot1zplosf.fd
+++ b/fonts/newpx/tex/ot1zplosf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ot1zplosf.fd}[2015/01/17 v1.0 font definition file for OT1/zpl/osf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{OT1}{zplosf}{bx}{n}{<->ssub * zplosf/b/n}{}
\DeclareFontShape{OT1}{zplosf}{bx}{scit}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{OT1}{zplosf}{bx}{it}{<->ssub * zplosf/b/it}{}
-\DeclareFontShape{OT1}{zplosf}{m}{sl}{<-> \zpl@scaled zpl-Italic-osf-th-ot1}{}
-\DeclareFontShape{OT1}{zplosf}{b}{sl}{<->ssub * zplosf/b/it}{}
-\DeclareFontShape{OT1}{zplosf}{bx}{sl}{<->ssub * zplosf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{OT1}{zplosf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-osf-ot1}{}
+ \DeclareFontShape{OT1}{zplosf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-osf-ot1}{}
+ \DeclareFontShape{OT1}{zplosf}{bx}{sl}{<->ssub * zplosf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{OT1}{zplosf}{m}{sl}{<-> \zpl@scaled zplth-Italic-osf-ot1}{}
+ \DeclareFontShape{OT1}{zplosf}{b}{sl}{<->ssub * zplosf/m/sl}{}
+ \DeclareFontShape{OT1}{zplosf}{bx}{sl}{<->ssub * zplosf/m/sl}{}
+\fi
\DeclareFontShape{OT1}{zplosf}{b}{scsl}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{OT1}{zplosf}{bx}{scsl}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{OT1}{zplosf}{m}{scsl}{<->ssub * zplosf/m/scit}{}
diff --git a/fonts/newpx/tex/ot1zplth-lf.fd b/fonts/newpx/tex/ot1zplth-lf.fd
new file mode 100644
index 0000000000..baf3d976c3
--- /dev/null
+++ b/fonts/newpx/tex/ot1zplth-lf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ot1zplth-lf.fd}[2021/05/07 v1.0 font definition file for OT1/zplth/lf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{OT1}{zplth-lf}{\zpl@spacing}
+\DeclareFontShape{OT1}{zplth-lf}{m}{it}{<-> \zpl@scaled zplth-Italic-tlf-ot1}{}
+\DeclareFontShape{OT1}{zplth-lf}{m}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{m}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{m}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{b}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{bx}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{b}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{bx}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{b}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{bx}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{b}{it}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{bx}{it}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{m}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{b}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{bx}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{b}{scsl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{bx}{scsl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{OT1}{zplth-lf}{m}{scsl}{<->ssub * zplth-lf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ot1zplth-osf.fd b/fonts/newpx/tex/ot1zplth-osf.fd
new file mode 100644
index 0000000000..3820d0718f
--- /dev/null
+++ b/fonts/newpx/tex/ot1zplth-osf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ot1zplth-osf.fd}[2021/05/07 v1.0 font definition file for OT1/zplth/osf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{OT1}{zplth-osf}{\zpl@spacing}
+\DeclareFontShape{OT1}{zplth-osf}{m}{it}{<-> \zpl@scaled zplth-Italic-osf-ot1}{}
+\DeclareFontShape{OT1}{zplth-osf}{m}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{m}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{m}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{b}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{bx}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{b}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{bx}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{b}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{bx}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{b}{it}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{bx}{it}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{m}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{b}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{bx}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{b}{scsl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{bx}{scsl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{OT1}{zplth-osf}{m}{scsl}{<->ssub * zplth-osf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ot1zplth-tlf.fd b/fonts/newpx/tex/ot1zplth-tlf.fd
new file mode 100644
index 0000000000..4a01d9b52d
--- /dev/null
+++ b/fonts/newpx/tex/ot1zplth-tlf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ot1zplth-tlf.fd}[2021/05/06 v1.0 font definition file for OT1/zplth/tlf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{OT1}{zplth-tlf}{\zpl@spacing}
+\DeclareFontShape{OT1}{zplth-tlf}{m}{it}{<-> \zpl@scaled zplth-Italic-tlf-ot1}{}
+\DeclareFontShape{OT1}{zplth-tlf}{m}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{m}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{m}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{b}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{bx}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{b}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{bx}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{b}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{bx}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{b}{it}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{bx}{it}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{m}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{b}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{bx}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{b}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{bx}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tlf}{m}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ot1zplth-tosf.fd b/fonts/newpx/tex/ot1zplth-tosf.fd
new file mode 100644
index 0000000000..a9e43d2069
--- /dev/null
+++ b/fonts/newpx/tex/ot1zplth-tosf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{ot1zplth-tosf.fd}[2021/05/07 v1.0 font definition file for OT1/zplth/tosf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{OT1}{zplth-tosf}{\zpl@spacing}
+\DeclareFontShape{OT1}{zplth-tosf}{m}{it}{<-> \zpl@scaled zplth-Italic-osf-ot1}{}
+\DeclareFontShape{OT1}{zplth-tosf}{m}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{m}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{m}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{b}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{bx}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{b}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{bx}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{b}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{bx}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{b}{it}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{bx}{it}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{m}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{b}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{bx}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{b}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{bx}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{OT1}{zplth-tosf}{m}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/ot1zpltlf.fd b/fonts/newpx/tex/ot1zpltlf.fd
index 77d05bf29e..780efce9ec 100644
--- a/fonts/newpx/tex/ot1zpltlf.fd
+++ b/fonts/newpx/tex/ot1zpltlf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ot1zpltlf.fd}[2015/01/17 v1.0 font definition file for OT1/zpl/tlf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{OT1}{zpltlf}{bx}{n}{<->ssub * zpltlf/b/n}{}
\DeclareFontShape{OT1}{zpltlf}{bx}{scit}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{OT1}{zpltlf}{bx}{it}{<->ssub * zpltlf/b/it}{}
-\DeclareFontShape{OT1}{zpltlf}{m}{sl}{<-> \zpl@scaled zpl-Italic-tlf-th-ot1}{}
-\DeclareFontShape{OT1}{zpltlf}{b}{sl}{<->ssub * zpltlf/b/it}{}
-\DeclareFontShape{OT1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{OT1}{zpltlf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-tlf-ot1}{}
+ \DeclareFontShape{OT1}{zpltlf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-tlf-ot1}{}
+ \DeclareFontShape{OT1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{OT1}{zpltlf}{m}{sl}{<-> \zpl@scaled zplth-Italic-tlf-ot1}{}
+ \DeclareFontShape{OT1}{zpltlf}{b}{sl}{<->ssub * zpltlf/m/sl}{}
+ \DeclareFontShape{OT1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/m/sl}{}
+\fi
\DeclareFontShape{OT1}{zpltlf}{b}{scsl}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{OT1}{zpltlf}{bx}{scsl}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{OT1}{zpltlf}{m}{scsl}{<->ssub * zpltlf/m/scit}{}
diff --git a/fonts/newpx/tex/ot1zpltosf.fd b/fonts/newpx/tex/ot1zpltosf.fd
index 10d20d7491..f1f68107bc 100644
--- a/fonts/newpx/tex/ot1zpltosf.fd
+++ b/fonts/newpx/tex/ot1zpltosf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{ot1zpltosf.fd}[2015/02/07 v1.0 font definition file for OT1/zpl/tosf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -23,9 +25,15 @@
\DeclareFontShape{OT1}{zpltosf}{bx}{n}{<->ssub * zpltosf/b/n}{}
\DeclareFontShape{OT1}{zpltosf}{bx}{scit}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{OT1}{zpltosf}{bx}{it}{<->ssub * zpltosf/b/it}{}
-\DeclareFontShape{OT1}{zpltosf}{m}{sl}{<-> \zpl@scaled zpl-Italic-osf-th-ot1}{}
-\DeclareFontShape{OT1}{zpltosf}{b}{sl}{<->ssub * zpltosf/b/it}{}
-\DeclareFontShape{OT1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{OT1}{zpltosf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-tosf-ot1}{}
+ \DeclareFontShape{OT1}{zpltosf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-tosf-ot1}{}
+ \DeclareFontShape{OT1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{OT1}{zpltosf}{m}{sl}{<-> \zpl@scaled zplth-Italic-osf-ot1}{}
+ \DeclareFontShape{OT1}{zpltosf}{b}{sl}{<->ssub * zpltosf/m/sl}{}
+ \DeclareFontShape{OT1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/m/sl}{}
+\fi
\DeclareFontShape{OT1}{zpltosf}{b}{scsl}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{OT1}{zpltosf}{bx}{scsl}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{OT1}{zpltosf}{m}{scsl}{<->ssub * zpltosf/m/scit}{}
diff --git a/fonts/newpx/tex/t1zpllf.fd b/fonts/newpx/tex/t1zpllf.fd
index 6c7a940b95..5b3b07882f 100644
--- a/fonts/newpx/tex/t1zpllf.fd
+++ b/fonts/newpx/tex/t1zpllf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{t1zpllf.fd}[2015/01/17 v1.0 font definition file for T1/zpl/lf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{T1}{zpllf}{bx}{n}{<->ssub * zpllf/b/n}{}
\DeclareFontShape{T1}{zpllf}{bx}{scit}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{T1}{zpllf}{bx}{it}{<->ssub * zpllf/b/it}{}
-\DeclareFontShape{T1}{zpllf}{m}{sl}{<-> \zpl@scaled zpl-Italic-tlf-th-t1}{}
-\DeclareFontShape{T1}{zpllf}{b}{sl}{<->ssub * zpllf/b/it}{}
-\DeclareFontShape{T1}{zpllf}{bx}{sl}{<->ssub * zpllf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{T1}{zpllf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-lf-t1}{}
+ \DeclareFontShape{T1}{zpllf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-lf-t1}{}
+ \DeclareFontShape{T1}{zpllf}{bx}{sl}{<->ssub * zpllf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{T1}{zpllf}{m}{sl}{<-> \zpl@scaled zplth-Italic-tlf-t1}{}
+ \DeclareFontShape{T1}{zpllf}{b}{sl}{<->ssub * zpllf/m/sl}{}
+ \DeclareFontShape{T1}{zpllf}{bx}{sl}{<->ssub * zpllf/m/sl}{}
+\fi
\DeclareFontShape{T1}{zpllf}{b}{scsl}{<->ssub * zpllf/b/scit}{}
\DeclareFontShape{T1}{zpllf}{m}{scsl}{<->ssub * zpllf/m/scit}{}
\DeclareFontShape{T1}{zpllf}{b}{scsl}{<->ssub * zpllf/b/scit}{}
diff --git a/fonts/newpx/tex/t1zplosf.fd b/fonts/newpx/tex/t1zplosf.fd
index b14ec1d85c..c0685bab46 100644
--- a/fonts/newpx/tex/t1zplosf.fd
+++ b/fonts/newpx/tex/t1zplosf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{t1zplosf.fd}[2015/01/17 v1.0 font definition file for T1/zpl/osf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -22,9 +24,15 @@
\DeclareFontShape{T1}{zplosf}{bx}{n}{<->ssub * zplosf/b/n}{}
\DeclareFontShape{T1}{zplosf}{bx}{scit}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{T1}{zplosf}{bx}{it}{<->ssub * zplosf/b/it}{}
-\DeclareFontShape{T1}{zplosf}{m}{sl}{<->\zpl@scaled zpl-Italic-osf-th-t1}{}
-\DeclareFontShape{T1}{zplosf}{b}{sl}{<->ssub * zplosf/b/it}{}
-\DeclareFontShape{T1}{zplosf}{bx}{sl}{<->ssub * zplosf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{T1}{zplosf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-osf-t1}{}
+ \DeclareFontShape{T1}{zplosf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-osf-t1}{}
+ \DeclareFontShape{T1}{zplosf}{bx}{sl}{<->ssub * zplosf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{T1}{zplosf}{m}{sl}{<-> \zpl@scaled zplth-Italic-osf-t1}{}
+ \DeclareFontShape{T1}{zplosf}{b}{sl}{<->ssub * zplosf/m/sl}{}
+ \DeclareFontShape{T1}{zplosf}{bx}{sl}{<->ssub * zplosf/m/sl}{}
+\fi
\DeclareFontShape{T1}{zplosf}{b}{scsl}{<->ssub * zplosf/b/scit}{}
\DeclareFontShape{T1}{zplosf}{m}{scsl}{<->ssub * zplosf/m/scit}{}
\DeclareFontShape{T1}{zplosf}{bx}{scsl}{<->ssub * zplosf/b/scit}{}
diff --git a/fonts/newpx/tex/t1zplth-lf.fd b/fonts/newpx/tex/t1zplth-lf.fd
new file mode 100644
index 0000000000..a2c23deb67
--- /dev/null
+++ b/fonts/newpx/tex/t1zplth-lf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{t1zplth-lf.fd}[2021/05/07 v1.0 font definition file for T1/zplth/lf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{T1}{zplth-lf}{\zpl@spacing}
+\DeclareFontShape{T1}{zplth-lf}{m}{it}{<-> \zpl@scaled zplth-Italic-tlf-t1}{}
+\DeclareFontShape{T1}{zplth-lf}{m}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{m}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{m}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{b}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{bx}{sc}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{b}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{bx}{n}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{b}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{bx}{scit}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{b}{it}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{bx}{it}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{m}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{b}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{bx}{sl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{b}{scsl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{bx}{scsl}{<->ssub * zplth-lf/m/it}{}
+\DeclareFontShape{T1}{zplth-lf}{m}{scsl}{<->ssub * zplth-lf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/t1zplth-osf.fd b/fonts/newpx/tex/t1zplth-osf.fd
new file mode 100644
index 0000000000..2235f54e27
--- /dev/null
+++ b/fonts/newpx/tex/t1zplth-osf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{t1zplth-osf.fd}[2021/05/07 v1.0 font definition file for T1/zplth/osf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{T1}{zplth-osf}{\zpl@spacing}
+\DeclareFontShape{T1}{zplth-osf}{m}{it}{<-> \zpl@scaled zplth-Italic-osf-t1}{}
+\DeclareFontShape{T1}{zplth-osf}{m}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{m}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{m}{scit}{<-> ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{b}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{bx}{sc}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{b}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{bx}{n}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{b}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{bx}{scit}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{b}{it}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{bx}{it}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{m}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{b}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{bx}{sl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{b}{scsl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{bx}{scsl}{<->ssub * zplth-osf/m/it}{}
+\DeclareFontShape{T1}{zplth-osf}{m}{scsl}{<->ssub * zplth-osf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/t1zplth-tlf.fd b/fonts/newpx/tex/t1zplth-tlf.fd
new file mode 100644
index 0000000000..6742079977
--- /dev/null
+++ b/fonts/newpx/tex/t1zplth-tlf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{t1zplth-tlf.fd}[2021/05/06 v1.0 font definition file for T1/zplth/tlf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+
+\DeclareFontFamily{T1}{zplth-tlf}{\zpl@spacing}
+\DeclareFontShape{T1}{zplth-tlf}{m}{it}{<-> \zpl@scaled zplth-Italic-tlf-t1}{}
+\DeclareFontShape{T1}{zplth-tlf}{m}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{m}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{m}{scit}{<-> ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{b}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{bx}{sc}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{b}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{bx}{n}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{b}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{bx}{scit}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{b}{it}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{bx}{it}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{m}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{b}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{bx}{sl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{b}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{bx}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\DeclareFontShape{T1}{zplth-tlf}{m}{scsl}{<->ssub * zplth-tlf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/t1zplth-tosf.fd b/fonts/newpx/tex/t1zplth-tosf.fd
new file mode 100644
index 0000000000..880a789110
--- /dev/null
+++ b/fonts/newpx/tex/t1zplth-tosf.fd
@@ -0,0 +1,28 @@
+\ProvidesFile{t1zplth-tosf.fd}[2021/05/07 v1.0 font definition file for T1/zplth/tosf]
+
+\expandafter\ifx\csname zpl@scaled\endcsname\relax
+ \let\zpl@scaled\@empty%
+\fi
+
+\ifdefined\zpl@spacing \else\global\let\zpl@spacing\@empty\fi
+%\traceon
+\DeclareFontFamily{T1}{zplth-tosf}{\zpl@spacing}
+\DeclareFontShape{T1}{zplth-tosf}{m}{it}{<-> \zpl@scaled zplth-Italic-osf-t1}{}
+\DeclareFontShape{T1}{zplth-tosf}{m}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{m}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{m}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{b}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{bx}{sc}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{b}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{bx}{n}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{b}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{bx}{scit}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{b}{it}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{bx}{it}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{m}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{b}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{bx}{sl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{b}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{bx}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\DeclareFontShape{T1}{zplth-tosf}{m}{scsl}{<->ssub * zplth-tosf/m/it}{}
+\endinput
diff --git a/fonts/newpx/tex/t1zpltlf.fd b/fonts/newpx/tex/t1zpltlf.fd
index eb0d97b894..2e00bce605 100644
--- a/fonts/newpx/tex/t1zpltlf.fd
+++ b/fonts/newpx/tex/t1zpltlf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{t1zpltlf.fd}[2015/01/17 v1.0 font definition file for T1/zpl/tlf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -21,9 +23,15 @@
\DeclareFontShape{T1}{zpltlf}{bx}{n}{<->ssub * zpltlf/b/n}{}
\DeclareFontShape{T1}{zpltlf}{bx}{scit}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{T1}{zpltlf}{bx}{it}{<->ssub * zpltlf/b/it}{}
-\DeclareFontShape{T1}{zpltlf}{m}{sl}{<-> \zpl@scaled zpl-Italic-tlf-th-t1}{}
-\DeclareFontShape{T1}{zpltlf}{b}{sl}{<->ssub * zpltlf/b/it}{}
-\DeclareFontShape{T1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{T1}{zpltlf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-tlf-t1}{}
+ \DeclareFontShape{T1}{zpltlf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-tlf-t1}{}
+ \DeclareFontShape{T1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{T1}{zpltlf}{m}{sl}{<-> \zpl@scaled zplth-Italic-tlf-t1}{}
+ \DeclareFontShape{T1}{zpltlf}{b}{sl}{<->ssub * zpltlf/m/sl}{}
+ \DeclareFontShape{T1}{zpltlf}{bx}{sl}{<->ssub * zpltlf/m/sl}{}
+\fi
\DeclareFontShape{T1}{zpltlf}{b}{scsl}{<->ssub * zpltlf/b/scit}{}
\DeclareFontShape{T1}{zpltlf}{m}{scsl}{<->ssub * zpltlf/m/scit}{}
\DeclareFontShape{T1}{zpltlf}{bx}{scsl}{<->ssub * zpltlf/b/scit}{}
diff --git a/fonts/newpx/tex/t1zpltosf.fd b/fonts/newpx/tex/t1zpltosf.fd
index d800b5b786..85009e16e6 100644
--- a/fonts/newpx/tex/t1zpltosf.fd
+++ b/fonts/newpx/tex/t1zpltosf.fd
@@ -1,5 +1,7 @@
\ProvidesFile{t1zpltosf.fd}[2015/01/17 v1.0 font definition file for T1/zpl/tosf]
+\@ifundefined{ifzpl@sl}{\global\newif\ifzpl@sl\global\zpl@sltrue}{}
+
\expandafter\ifx\csname zpl@scaled\endcsname\relax
\global\let\zpl@scaled\@empty%
\fi
@@ -23,9 +25,15 @@
\DeclareFontShape{T1}{zpltosf}{bx}{n}{<->ssub * zpltosf/b/n}{}
\DeclareFontShape{T1}{zpltosf}{bx}{scit}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{T1}{zpltosf}{bx}{it}{<->ssub * zpltosf/b/it}{}
-\DeclareFontShape{T1}{zpltosf}{m}{sl}{<->\zpl@scaled zpl-Italic-osf-th-t1}{}
-\DeclareFontShape{T1}{zpltosf}{b}{sl}{<->ssub * zpltosf/b/it}{}
-\DeclareFontShape{T1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/b/it}{}
+\ifzpl@sl % point to real slanted fonts
+ \DeclareFontShape{T1}{zpltosf}{m}{sl}{<-> \zpl@scaled zpl-Slanted-tosf-t1}{}
+ \DeclareFontShape{T1}{zpltosf}{b}{sl}{<-> \zpl@scaled zpl-BoldSlanted-tosf-t1}{}
+ \DeclareFontShape{T1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/b/sl}{}
+\else %point to theorem font
+ \DeclareFontShape{T1}{zpltosf}{m}{sl}{<-> \zpl@scaled zplth-Italic-osf-t1}{}
+ \DeclareFontShape{T1}{zpltosf}{b}{sl}{<->ssub * zpltosf/m/sl}{}
+ \DeclareFontShape{T1}{zpltosf}{bx}{sl}{<->ssub * zpltosf/m/sl}{}
+\fi
\DeclareFontShape{T1}{zpltosf}{b}{scsl}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{T1}{zpltosf}{bx}{scsl}{<->ssub * zpltosf/b/scit}{}
\DeclareFontShape{T1}{zpltosf}{m}{scsl}{<->ssub * zpltosf/m/scit}{}
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-lf-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-lf-ly1.tfm
new file mode 100644
index 0000000000..702358e77d
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-lf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-lf-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-lf-ot1.tfm
new file mode 100644
index 0000000000..8b308cb74f
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-lf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ly1.tfm
new file mode 100644
index 0000000000..c6512179f1
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ot1.tfm
new file mode 100644
index 0000000000..4b1bed9483
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-t1.tfm
new file mode 100644
index 0000000000..27f4906b9e
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-lf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-lf-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-lf-t1.tfm
new file mode 100644
index 0000000000..e67e181725
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-lf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-osf-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-osf-ly1.tfm
new file mode 100644
index 0000000000..de5c0a9924
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-osf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-osf-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-osf-ot1.tfm
new file mode 100644
index 0000000000..41970667aa
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-osf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ly1.tfm
new file mode 100644
index 0000000000..e2b839c06a
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ot1.tfm
new file mode 100644
index 0000000000..ccc9cd35d6
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-t1.tfm
new file mode 100644
index 0000000000..af74cec636
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-osf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-osf-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-osf-t1.tfm
new file mode 100644
index 0000000000..18218ebae9
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-osf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tlf-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-ly1.tfm
new file mode 100644
index 0000000000..2bb5e68d92
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tlf-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-ot1.tfm
new file mode 100644
index 0000000000..0cf810b5d7
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ly1.tfm
new file mode 100644
index 0000000000..088ef31148
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ot1.tfm
new file mode 100644
index 0000000000..17c6269233
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-t1.tfm
new file mode 100644
index 0000000000..568beef602
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tlf-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-t1.tfm
new file mode 100644
index 0000000000..565079c055
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tlf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tosf-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-ly1.tfm
new file mode 100644
index 0000000000..3467dd9051
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tosf-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-ot1.tfm
new file mode 100644
index 0000000000..5911ae559f
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ly1.tfm
new file mode 100644
index 0000000000..249c56ca78
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ot1.tfm
new file mode 100644
index 0000000000..d735cbf6e4
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-t1.tfm
new file mode 100644
index 0000000000..babcc6ad1c
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-BoldSlanted-tosf-t1.tfm b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-t1.tfm
new file mode 100644
index 0000000000..37977bb283
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-BoldSlanted-tosf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-lf-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-lf-ly1.tfm
new file mode 100644
index 0000000000..1f6a15c959
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-lf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-lf-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-lf-ot1.tfm
new file mode 100644
index 0000000000..76972850a8
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-lf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-lf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-lf-sc-ly1.tfm
new file mode 100644
index 0000000000..3487d55e4e
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-lf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-lf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-lf-sc-ot1.tfm
new file mode 100644
index 0000000000..351e17dea5
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-lf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-lf-sc-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-lf-sc-t1.tfm
new file mode 100644
index 0000000000..cce6f783da
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-lf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-lf-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-lf-t1.tfm
new file mode 100644
index 0000000000..b735301a78
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-lf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-osf-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-osf-ly1.tfm
new file mode 100644
index 0000000000..0b1d44ffba
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-osf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-osf-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-osf-ot1.tfm
new file mode 100644
index 0000000000..c9c83330e5
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-osf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-osf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-osf-sc-ly1.tfm
new file mode 100644
index 0000000000..4e24866749
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-osf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-osf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-osf-sc-ot1.tfm
new file mode 100644
index 0000000000..cd00f660a9
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-osf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-osf-sc-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-osf-sc-t1.tfm
new file mode 100644
index 0000000000..378490c8d5
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-osf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-osf-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-osf-t1.tfm
new file mode 100644
index 0000000000..a35346bb0c
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-osf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tlf-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-tlf-ly1.tfm
new file mode 100644
index 0000000000..48794b8164
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tlf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tlf-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-tlf-ot1.tfm
new file mode 100644
index 0000000000..09e1b62df0
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tlf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tlf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-tlf-sc-ly1.tfm
new file mode 100644
index 0000000000..21f8926c28
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tlf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tlf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-tlf-sc-ot1.tfm
new file mode 100644
index 0000000000..92448bc6c3
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tlf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tlf-sc-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-tlf-sc-t1.tfm
new file mode 100644
index 0000000000..d1932829bb
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tlf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tlf-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-tlf-t1.tfm
new file mode 100644
index 0000000000..c8c1ebeee7
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tlf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tosf-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-tosf-ly1.tfm
new file mode 100644
index 0000000000..e2dd91f46f
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tosf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tosf-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-tosf-ot1.tfm
new file mode 100644
index 0000000000..dda44cc1a9
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tosf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tosf-sc-ly1.tfm b/fonts/newpx/tfm/zpl-Slanted-tosf-sc-ly1.tfm
new file mode 100644
index 0000000000..74a820d621
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tosf-sc-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tosf-sc-ot1.tfm b/fonts/newpx/tfm/zpl-Slanted-tosf-sc-ot1.tfm
new file mode 100644
index 0000000000..997aaae62b
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tosf-sc-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tosf-sc-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-tosf-sc-t1.tfm
new file mode 100644
index 0000000000..8bf661efdb
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tosf-sc-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Slanted-tosf-t1.tfm b/fonts/newpx/tfm/zpl-Slanted-tosf-t1.tfm
new file mode 100644
index 0000000000..a064913276
--- /dev/null
+++ b/fonts/newpx/tfm/zpl-Slanted-tosf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zplexx.tfm b/fonts/newpx/tfm/zplexx.tfm
index 2456bc38d4..a829e82b24 100644
--- a/fonts/newpx/tfm/zplexx.tfm
+++ b/fonts/newpx/tfm/zplexx.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Italic-osf-th-ly1.tfm b/fonts/newpx/tfm/zplth-Italic-osf-ly1.tfm
index db49d6bb83..5fe3d656bb 100644
--- a/fonts/newpx/tfm/zpl-Italic-osf-th-ly1.tfm
+++ b/fonts/newpx/tfm/zplth-Italic-osf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Italic-osf-th-ot1.tfm b/fonts/newpx/tfm/zplth-Italic-osf-ot1.tfm
index f3370748c0..8031e74ade 100644
--- a/fonts/newpx/tfm/zpl-Italic-osf-th-ot1.tfm
+++ b/fonts/newpx/tfm/zplth-Italic-osf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Italic-osf-th-t1.tfm b/fonts/newpx/tfm/zplth-Italic-osf-t1.tfm
index b035b29a20..0628ef4e81 100644
--- a/fonts/newpx/tfm/zpl-Italic-osf-th-t1.tfm
+++ b/fonts/newpx/tfm/zplth-Italic-osf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Italic-tlf-th-ly1.tfm b/fonts/newpx/tfm/zplth-Italic-tlf-ly1.tfm
index 1ce9e86da5..daca27b950 100644
--- a/fonts/newpx/tfm/zpl-Italic-tlf-th-ly1.tfm
+++ b/fonts/newpx/tfm/zplth-Italic-tlf-ly1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Italic-tlf-th-ot1.tfm b/fonts/newpx/tfm/zplth-Italic-tlf-ot1.tfm
index b0f66853c5..1525d37fb9 100644
--- a/fonts/newpx/tfm/zpl-Italic-tlf-th-ot1.tfm
+++ b/fonts/newpx/tfm/zplth-Italic-tlf-ot1.tfm
Binary files differ
diff --git a/fonts/newpx/tfm/zpl-Italic-tlf-th-t1.tfm b/fonts/newpx/tfm/zplth-Italic-tlf-t1.tfm
index db520ff6f9..f086e67caf 100644
--- a/fonts/newpx/tfm/zpl-Italic-tlf-th-t1.tfm
+++ b/fonts/newpx/tfm/zplth-Italic-tlf-t1.tfm
Binary files differ
diff --git a/fonts/newpx/type1/zplbsl.pfb b/fonts/newpx/type1/zplbsl.pfb
new file mode 100644
index 0000000000..617625cab5
--- /dev/null
+++ b/fonts/newpx/type1/zplbsl.pfb
Binary files differ
diff --git a/fonts/newpx/type1/zplrsl.pfb b/fonts/newpx/type1/zplrsl.pfb
new file mode 100644
index 0000000000..3e64816a52
--- /dev/null
+++ b/fonts/newpx/type1/zplrsl.pfb
Binary files differ
diff --git a/fonts/newtx/README b/fonts/newtx/README
index 1d31e0cd3e..0bc082730d 100644
--- a/fonts/newtx/README
+++ b/fonts/newtx/README
@@ -1,10 +1,13 @@
This package, initially based on txfonts, provides many fixes and enhancements to the txfonts package, splitting it into two separate packages---newtxtext and newtxmath, which may be run independently of one another. It provides scaling, improved metrics, and other options. In particular, newtxmath offers a libertine option which substitutes Linux Libertine (provided with TeXLive and MikTeX) italic and Greek letters for the default Times letters, providing a good match for the Libertine text font, which is heavier than Computer Modern but lighter than Times, and in my experience, looks very sharp and clear on the screen.
-Current version: 1.651 2021-05-20
+Current version: 1.652 2021-05-22
This material is subject to the LaTeX Project Public License. See http://www.ctan.org/license/lppl1.3
for the details of that license.
+Changes in version 1.652
+Corrected the fd files for the main text fonts. Those in version 1.651 were not functional and were released in error.
+
Changes in version 1.651
Corrected an error introduced in version 1.65 in a number of fd files for the main text fonts. (Thanks Alexara Wu.)
diff --git a/fonts/newtx/tex/ly1ntxlf.fd b/fonts/newtx/tex/ly1ntxlf.fd
index 308fb6b1cc..f3cccce9b7 100644
--- a/fonts/newtx/tex/ly1ntxlf.fd
+++ b/fonts/newtx/tex/ly1ntxlf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ly1ntxlf.fd}[2021/05/08 v1.0 font definition file for LY1/ntx/lf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/ly1ntxosf.fd b/fonts/newtx/tex/ly1ntxosf.fd
index 31495f6472..008f8c64c4 100644
--- a/fonts/newtx/tex/ly1ntxosf.fd
+++ b/fonts/newtx/tex/ly1ntxosf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ly1ntxosf.fd}[2021/05/08 v1.0 font definition file for LY1/ntx/osf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/ly1ntxtlf.fd b/fonts/newtx/tex/ly1ntxtlf.fd
index defa93b4cb..2c209fb822 100644
--- a/fonts/newtx/tex/ly1ntxtlf.fd
+++ b/fonts/newtx/tex/ly1ntxtlf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ly1ntxtlf.fd}[2021/05/08 v1.0 font definition file for LY1/ntx/tlf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/ly1ntxtosf.fd b/fonts/newtx/tex/ly1ntxtosf.fd
index 6ee7c367aa..5360d0aa3c 100644
--- a/fonts/newtx/tex/ly1ntxtosf.fd
+++ b/fonts/newtx/tex/ly1ntxtosf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ly1ntxtosf.fd}[2021/05/08 v1.0 font definition file for LY1/ntx/tosf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/newtxtext.sty b/fonts/newtx/tex/newtxtext.sty
index 719ef13945..846b03d90d 100644
--- a/fonts/newtx/tex/newtxtext.sty
+++ b/fonts/newtx/tex/newtxtext.sty
@@ -1,7 +1,7 @@
\NeedsTeXFormat{LaTeX2e}
-\def\fileversion{1.65}
-\def\filedate{2021/05/16}
+\def\fileversion{1.652}
+\def\filedate{2021/05/22}
\ProvidesPackage{newtxtext}[\filedate\space v\fileversion]
\message{`newtxtext' v\fileversion, \filedate\space Text macros taking advantage of TeX-Gyre Termes fonts (msharpe)}
diff --git a/fonts/newtx/tex/ot1ntxlf.fd b/fonts/newtx/tex/ot1ntxlf.fd
index 7f423ce6c2..8065b81eb9 100644
--- a/fonts/newtx/tex/ot1ntxlf.fd
+++ b/fonts/newtx/tex/ot1ntxlf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ot1ntxlf.fd}[2021/05/08 v1.0 font definition file for OT1/ntx/lf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/ot1ntxosf.fd b/fonts/newtx/tex/ot1ntxosf.fd
index bbcb154694..2263ac3db8 100644
--- a/fonts/newtx/tex/ot1ntxosf.fd
+++ b/fonts/newtx/tex/ot1ntxosf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ot1ntxosf.fd}[2021/05/08 v1.0 font definition file for OT1/ntx/osf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/ot1ntxtlf.fd b/fonts/newtx/tex/ot1ntxtlf.fd
index 3247b8ddca..72f2cfb9ef 100644
--- a/fonts/newtx/tex/ot1ntxtlf.fd
+++ b/fonts/newtx/tex/ot1ntxtlf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ot1ntxtlf.fd}[2021/05/08 v1.0 font definition file for OT1/ntx/tlf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/ot1ntxtosf.fd b/fonts/newtx/tex/ot1ntxtosf.fd
index 176bad670f..a44b5e8ef7 100644
--- a/fonts/newtx/tex/ot1ntxtosf.fd
+++ b/fonts/newtx/tex/ot1ntxtosf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{ot1ntxtosf.fd}[2021/05/08 v1.0 font definition file for OT1/ntx/tosf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/t1ntxlf.fd b/fonts/newtx/tex/t1ntxlf.fd
index e55c5d8ef7..fe02287b28 100644
--- a/fonts/newtx/tex/t1ntxlf.fd
+++ b/fonts/newtx/tex/t1ntxlf.fd
@@ -1,12 +1,11 @@
\ProvidesFile{t1ntxlf.fd}[2021/05/07 v1.1 font definition file for T1/ntx/lf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
\fi
+
\def\ntx@lsfx{}
\def\ntx@makelsfx{\ifntx@largesc\def\ntx@lsfx{l}\fi}
\ifdefined\ntx@largescfalse \ntx@makelsfx\fi
diff --git a/fonts/newtx/tex/t1ntxosf.fd b/fonts/newtx/tex/t1ntxosf.fd
index 5f9837d454..0e5603e704 100644
--- a/fonts/newtx/tex/t1ntxosf.fd
+++ b/fonts/newtx/tex/t1ntxosf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{t1ntxosf.fd}[2021/05/07 v1.1 font definition file for T1/ntx/osf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/t1ntxtlf.fd b/fonts/newtx/tex/t1ntxtlf.fd
index bc8fdd1578..49ab9bb3bb 100644
--- a/fonts/newtx/tex/t1ntxtlf.fd
+++ b/fonts/newtx/tex/t1ntxtlf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{t1ntxtlf.fd}[2021/05/07 v1.1 font definition file for T1/ntx/tlf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/fonts/newtx/tex/t1ntxtosf.fd b/fonts/newtx/tex/t1ntxtosf.fd
index 1aec7119a1..038c9fbb92 100644
--- a/fonts/newtx/tex/t1ntxtosf.fd
+++ b/fonts/newtx/tex/t1ntxtosf.fd
@@ -1,8 +1,6 @@
\ProvidesFile{t1ntxtosf.fd}[2021/05/07 v1.1 font definition file for T1/ntx/tosf]
-\expandafter\ifx\csname ntx@sltrue\endcsname\relax
- \global\newif\ifntx@sl\global\ntx@sltrue%
-\fi
+\@ifundefined{ifntx@sl}{\global\newif\ifntx@sl\global\ntx@sltrue}{}
\expandafter\ifx\csname ntx@scaled\endcsname\relax
\let\ntx@scaled\@empty%
diff --git a/info/biblio/litprog.bib b/info/biblio/litprog.bib
index 6aed678343..8ece080415 100644
--- a/info/biblio/litprog.bib
+++ b/info/biblio/litprog.bib
@@ -4,9 +4,9 @@
%%% ====================================================================
%%% BibTeX-file{
%%% author = "Nelson H. F. Beebe",
-%%% version = "3.36",
-%%% date = "05 February 2021",
-%%% time = "15:06:25 MST",
+%%% version = "3.37",
+%%% date = "08 April 2021",
+%%% time = "08:46:53 MDT",
%%% filename = "litprog.bib",
%%% address = "University of Utah
%%% Department of Mathematics, 110 LCB
@@ -16,7 +16,7 @@
%%% telephone = "+1 801 581 5254",
%%% FAX = "+1 801 581 4148",
%%% URL = "http://www.math.utah.edu/~beebe",
-%%% checksum = "44735 8750 39421 388361",
+%%% checksum = "14907 8770 39490 389098",
%%% email = "beebe at math.utah.edu, beebe at acm.org,
%%% beebe at computer.org (Internet)",
%%% codetable = "ISO/ASCII",
@@ -28,24 +28,26 @@
%%% fields will be printed if the is-alpha.bst
%%% or is-plain.bst style files are used.
%%%
-%%% At version 3.36, the coverage looked like
+%%% At version 3.37, the coverage looked like
%%% this:
%%%
-%%% 1982 ( 1) 1994 ( 19) 2006 ( 5)
-%%% 1983 ( 2) 1995 ( 18) 2007 ( 4)
-%%% 1984 ( 2) 1996 ( 30) 2008 ( 2)
-%%% 1985 ( 1) 1997 ( 14) 2009 ( 3)
-%%% 1986 ( 11) 1998 ( 14) 2010 ( 4)
-%%% 1987 ( 10) 1999 ( 6) 2011 ( 1)
-%%% 1988 ( 11) 2000 ( 5) 2012 ( 2)
-%%% 1989 ( 15) 2001 ( 3) 2013 ( 1)
-%%% 1990 ( 25) 2002 ( 10) 2014 ( 0)
-%%% 1991 ( 15) 2003 ( 10) 2015 ( 1)
-%%% 1992 ( 24) 2004 ( 5) 2016 ( 0)
-%%% 1993 ( 22) 2005 ( 7) 2017 ( 3)
+%%% 1982 ( 1) 1996 ( 30) 2010 ( 4)
+%%% 1983 ( 2) 1997 ( 14) 2011 ( 1)
+%%% 1984 ( 2) 1998 ( 14) 2012 ( 2)
+%%% 1985 ( 1) 1999 ( 6) 2013 ( 1)
+%%% 1986 ( 11) 2000 ( 5) 2014 ( 0)
+%%% 1987 ( 10) 2001 ( 3) 2015 ( 1)
+%%% 1988 ( 11) 2002 ( 10) 2016 ( 0)
+%%% 1989 ( 15) 2003 ( 10) 2017 ( 3)
+%%% 1990 ( 25) 2004 ( 5) 2018 ( 0)
+%%% 1991 ( 15) 2005 ( 7) 2019 ( 0)
+%%% 1992 ( 24) 2006 ( 5) 2020 ( 0)
+%%% 1993 ( 22) 2007 ( 4) 2021 ( 1)
+%%% 1994 ( 19) 2008 ( 2)
+%%% 1995 ( 18) 2009 ( 3)
%%% 19xx ( 1)
%%%
-%%% Article: 139
+%%% Article: 140
%%% Book: 35
%%% InCollection: 1
%%% InProceedings: 49
@@ -56,7 +58,7 @@
%%% TechReport: 29
%%% Unpublished: 1
%%%
-%%% Total entries: 307
+%%% Total entries: 308
%%%
%%% There is an extensive ``Literate Programming
%%% Library'' resource on the World Wide Web at
@@ -8193,6 +8195,24 @@
reading and writing",
}
+@Article{Knuth:2021:TT,
+ author = "Donald Knuth",
+ title = "The {\TeX} tuneup of 2021",
+ journal = j-TUGboat,
+ volume = "42",
+ number = "1",
+ pages = "1--4 (check??)",
+ month = feb,
+ year = "2021",
+ ISSN = "0896-3207",
+ bibdate = "Thu Apr 08 07:49:24 2021",
+ bibsource = "http://www.math.utah.edu/pub/tex/bib/litprog.bib;
+ http://www.math.utah.edu/pub/tex/bib/tugboat.bib",
+ URL = "https://tug.org/TUGboat/tb42-1/tb130knuth-tuneup21.pdf",
+ acknowledgement = ack-nhfb,
+ journal-URL = "https://tug.org/TUGboat/",
+}
+
%%% ====================================================================
%%% Cross-referenced entries must come last, sort by year, and then by
%%% citation label, with ``bibsort --byyear'':
diff --git a/info/biblio/litprog.ltx b/info/biblio/litprog.ltx
index 49dc730831..9df88c2a79 100644
--- a/info/biblio/litprog.ltx
+++ b/info/biblio/litprog.ltx
@@ -5,9 +5,9 @@
%%% ====================================================================
%%% @LaTeX-file{
%%% author = "Nelson H. F. Beebe",
-%%% version = "3.36",
-%%% date = "05 February 2021",
-%%% time = "15:06:29 MST",
+%%% version = "3.37",
+%%% date = "08 April 2021",
+%%% time = "08:46:59 MDT",
%%% filename = "litprog.ltx",
%%% address = "University of Utah
%%% Department of Mathematics, 110 LCB
@@ -17,7 +17,7 @@
%%% telephone = "+1 801 581 5254",
%%% FAX = "+1 801 581 4148",
%%% URL = "http://www.math.utah.edu/~beebe",
-%%% checksum = "25729 87 321 3210",
+%%% checksum = "28460 87 321 3204",
%%% email = "beebe@math.utah.edu, beebe@acm.org,
%%% beebe@computer.org (Internet)",
%%% codetable = "ISO/ASCII",
@@ -61,8 +61,8 @@
WWW URL: \protect\path=http://www.math.utah.edu/~beebe/=
}
-\date{05 February 2021 \\
-Version 3.36}
+\date{08 April 2021 \\
+Version 3.37}
\begin{document}
\nocite{*}
diff --git a/info/tlmgrbasics/README b/info/tlmgrbasics/README
index 832bdf017d..e9e19a5c58 100644
--- a/info/tlmgrbasics/README
+++ b/info/tlmgrbasics/README
@@ -1,5 +1,5 @@
This is the README for the tlmgrbasics package,
-version 2021-05-08.
+version 2021-05-22.
This package provides simplified documentation for tlmgr,
the TeX Live Native Manager. It is derived from tlmgr.1, the
diff --git a/info/tlmgrbasics/doc/tlmgr.pdf b/info/tlmgrbasics/doc/tlmgr.pdf
index e993c04747..6d4795b9e4 100644
--- a/info/tlmgrbasics/doc/tlmgr.pdf
+++ b/info/tlmgrbasics/doc/tlmgr.pdf
Binary files differ
diff --git a/info/tlmgrbasics/doc/tlmgr.tex b/info/tlmgrbasics/doc/tlmgr.tex
index a6f9563d94..4e1170b8d7 100644
--- a/info/tlmgrbasics/doc/tlmgr.tex
+++ b/info/tlmgrbasics/doc/tlmgr.tex
@@ -645,6 +645,23 @@ rights uses the option \texttt{-w32mode admin} a warning
is issued that the caller does not have enough privileges.
\end{itemize}
+\clearpage
+
+\subsection{The \texttt{paper} Action}
+\label{paper}
+
+\paragraph{Usage}
+\begin{list}{}{}
+\item \texttt{tlmgr paper}
+\item \texttt{tlmgr paper [a4|letter]}
+\item \texttt{tlmgr \textit{program} paper [a4|letter]}
+\end{list}
+
+With no arguments, \texttt{tlmgr paper} shows the default paper size for all known programs.
+With one argument (e.g., \texttt{tlmgr paper a4}), sets the default for all known programs to that
+paper size.
+With a \textit{program} given as the first argument and a paper size as the last argument
+(e.g., \texttt{tlmgr dvips paper a4}), sets the default for that program to that paper size.
\clearpage
diff --git a/macros/latex/contrib/bmstu-iu8/BMSTU-IU8.cls b/macros/latex/contrib/bmstu-iu8/BMSTU-IU8.cls
new file mode 100644
index 0000000000..e3c4748c0d
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/BMSTU-IU8.cls
@@ -0,0 +1,53 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{BMSTU-IU8}[2020/06/01 IU8 class]
+
+\LoadClass{article}
+
+\DeclareOption{diploma}{
+ \def\termsAndDefinitionsLine{В настоящем отчете о выпускной квалификационной работе специалиста
+ применяют следующие термины с соответствующими определениями:}
+ \def\abbreviationsLine{В настоящем отчете о выпускной квалификационной работе специалиста
+ применяют следующие следующие сокращения и обозначения:}
+ \def\fillTitle{\fillDiplomaTitle}
+}
+\DeclareOption{research}{
+ \def\termsAndDefinitionsLine{В настоящем отчете о НИР
+ применяют следующие термины с соответствующими определениями:}
+ \def\abbreviationsLine{В настоящем отчете о НИР
+ применяют следующие следующие сокращения и обозначения:}
+ \def\fillTitle{\fillResearchTitle}
+}
+\ExecuteOptions{diploma}
+\ProcessOptions
+
+\RequirePackage[T2A]{fontenc}
+\RequirePackage[utf8]{inputenc}
+\RequirePackage[russian]{babel}
+\RequirePackage{hyphsubst}
+\RequirePackage{csquotes}
+
+\RequirePackage{01-IU8-base}
+\RequirePackage{02-IU8-construction}
+\RequirePackage{03-IU8-numbering}
+\RequirePackage{04-IU8-section-numbering}
+\RequirePackage{05-IU8-figures}
+\RequirePackage{06-IU8-tables}
+\RequirePackage{07-IU8-footnotes}
+\RequirePackage{08-IU8-formulas}
+\RequirePackage{09-IU8-cites}
+\RequirePackage{10-IU8-titlepage}
+\RequirePackage{11-IU8-performers}
+\RequirePackage{12-IU8-abstract}
+\RequirePackage{13-IU8-contents}
+\RequirePackage{14-IU8-terms-and-definitions}
+\RequirePackage{15-IU8-list-of-abbreviations}
+\RequirePackage{16-IU8-references}
+\RequirePackage{17-IU8-appendices}
+\RequirePackage{18-IU8-extra}
+\RequirePackage{19-IU8-counters}
+\RequirePackage{20-IU8-listing}
+\RequirePackage{21-IU8-math}
+\RequirePackage{22-IU8-algorithms}
+
+\makeglossaries
diff --git a/macros/latex/contrib/bmstu-iu8/LICENSE b/macros/latex/contrib/bmstu-iu8/LICENSE
new file mode 100644
index 0000000000..b9a8428a7d
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 CatInCosmicSpace/latex-template repo contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/macros/latex/contrib/bmstu-iu8/README.md b/macros/latex/contrib/bmstu-iu8/README.md
new file mode 100644
index 0000000000..4fb70940ea
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/README.md
@@ -0,0 +1,3 @@
+# IU8 package
+
+This package consist of class file and style files for writing reports at the IU8 department of IU faculty of BMSTU (Bauman Moscow State Technical University).
diff --git a/macros/latex/contrib/bmstu-iu8/example.pdf b/macros/latex/contrib/bmstu-iu8/example.pdf
new file mode 100644
index 0000000000..bbf0887362
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/example.pdf
Binary files differ
diff --git a/macros/latex/contrib/bmstu-iu8/example.tex b/macros/latex/contrib/bmstu-iu8/example.tex
new file mode 100644
index 0000000000..0d2499d7bd
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/example.tex
@@ -0,0 +1,55 @@
+\documentclass[diploma]{BMSTU-IU8}
+
+\usepackage{lipsum}
+
+\student{И. И. Иванов}
+\theme{Создание отчёта \\ по НИРС \\ или ВКР}
+\group{ИУ8-999}
+
+\supervisor{П. П. Петров}
+\researchConsultant{П. П. Петров}
+\designConsultant{П. П. Петров}
+\technologicalConsultant{П. П. Петров}
+\economicsConsultant{П. П. Петров}
+\lawsConsultant{П. П. Петров}
+\normController{Т. Е. Завадская}
+
+% \theme{Тест \hfill} % Тема для НИРСа заполняется по-другому
+\studentFullName{Иванов Иван Иванович}
+\profile{10У101}
+\speciality{10.05.01 <<Компьютерная безопасность>>}
+\specialization{10.05.01\_01 <<Математические методы защиты информации>>}
+\supervisorWithDegree{доцент, к.т.н. Иванов И. И.}
+
+
+\begin{document}
+ \maketitle
+
+ \abstract % Структурный элемент: РЕФЕРАТ
+
+ \lipsum[1-2]
+
+ \tableofcontents % Содержание
+ \termsanddefenitions % Термины и определения
+ \listofabbreviations % Перечень сокращений и обозначений
+
+ \introduction
+
+ \lipsum[1-2]
+
+ \section{Исследовательская часть}
+
+ \lipsum[1-2]
+
+ \conclusion
+
+ \lipsum[1-2]
+
+ \printbibliography
+
+ \appendix
+
+ \appendixsection{Приложение для примера}
+
+ \lipsum[1-2]
+\end{document}
diff --git a/macros/latex/contrib/bmstu-iu8/inc/bmstu.png b/macros/latex/contrib/bmstu-iu8/inc/bmstu.png
new file mode 100644
index 0000000000..469c7d9797
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/inc/bmstu.png
Binary files differ
diff --git a/macros/latex/contrib/bmstu-iu8/styles/01-IU8-base.sty b/macros/latex/contrib/bmstu-iu8/styles/01-IU8-base.sty
new file mode 100644
index 0000000000..2ade498ef7
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/01-IU8-base.sty
@@ -0,0 +1,40 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{01-IU8-base}[2021/03/21 v1.0 Общие требования]
+
+% 6.1.1 Изложение текста и оформление отчета выполняют в соответствии с
+% требованиями настоящего стандарта. Страницы текста отчета о НИР и включенные в
+% отчет иллюстрации и таблицы должны соответствовать формату А4 по ГОСТ 9327.
+% Допускается применение формата А3 при наличии большого количества таблиц и
+% иллюстраций данного формата.
+
+% Отчет о НИР должен быть выполнен любым печатным способом на одной стороне
+% листа белой бумаги формата А4 через полтора интервала.
+\RequirePackage{setspace}
+\onehalfspacing
+
+% Цвет шрифта должен быть черным, размер шрифта - не менее 12 пт.
+% Рекомендуемый тип шрифта для основного текста отчета - Times New Roman.
+\RequirePackage[fontsize=14pt]{scrextend}
+% Но у Times New Roman нет открытой реализации, так что будет стандартный
+% Или можете попробовать xelatex:
+% \RequirePackage{fontspec}
+% \setmainfont{Times New Roman}
+
+% Текст отчета следует печатать, соблюдая следующие размеры полей:
+% левое - 30 мм, правое - 15 мм, верхнее и нижнее - 20 мм.
+\RequirePackage[
+ a4paper,
+ left=30mm, right=10mm, top=20mm, bottom=20mm,
+ footskip=10mm, % Для расположения номера страницы на 10 мм выше края листа
+ ignoreall,
+ % showframe,
+]{geometry}
+% Ты там пишешь, что правое поле должно быть 15 мм,
+% а потом ставишь его в 10 мм. Почему?
+% А потому что в программе TestVKR проходит только 10 мм, а не 15 мм ¯\_(ツ)_/¯
+
+% Абзацный отступ должен быть одинаковым по всему тексту отчета и равен 1,25 см.
+\setlength{\parindent}{1.25cm}
+
+\RequirePackage{indentfirst} % Отступ первой строки для абзацев
diff --git a/macros/latex/contrib/bmstu-iu8/styles/02-IU8-construction.sty b/macros/latex/contrib/bmstu-iu8/styles/02-IU8-construction.sty
new file mode 100644
index 0000000000..ebf8957a62
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/02-IU8-construction.sty
@@ -0,0 +1,66 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{02-IU8-construction}[2021/03/21 v1.0 Построение отчета]
+
+% 6.2.1 Наименования структурных элементов отчета:
+% "СПИСОК ИСПОЛНИТЕЛЕЙ", % у нас не используется
+% "РЕФЕРАТ", % У нас не используется
+% "СОДЕРЖАНИЕ",
+% "ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ",
+% "ПЕРЕЧЕНЬ СОКРАЩЕНИЙ И ОБОЗНАЧЕНИЙ",
+% "ВВЕДЕНИЕ",
+% "ЗАКЛЮЧЕНИЕ",
+% "СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ",
+% "ПРИЛОЖЕНИЕ"
+% служат заголовками структурных элементов отчета.
+
+% Заголовки структурных элементов следует располагать в середине строки без
+% точки в конце, прописными буквами, не подчеркивая. Каждый структурный элемент
+% и каждый раздел основной части отчета начинают с новой страницы.
+\RequirePackage{titlesec}
+\RequirePackage{titletoc}
+\RequirePackage{chngcntr}
+
+\newcounter{structure}
+\renewcommand{\thestructure}{} % Убрать появление счётчика в содержании
+\titleclass{\structure}{straight}[\section]
+\titleformat{\structure}[hang]{\clearpage\normalfont\bfseries\centering}{}{0em}{}
+\titlespacing*{\structure}{0pt}{0pt}{2\baselineskip}
+\titlecontents{structure}{}{}{}{}
+\renewcommand*\l@structure{\@dottedtocline{0}{0mm}{0em}}
+
+\newcommand{\structurebreak}{\clearpage}
+\newcommand{\sectionbreak}{\clearpage}
+
+% 6.2.2 Основную часть отчета следует делить на разделы, подразделы и пункты.
+% Пункты при необходимости могут делиться на подпункты. Разделы и подразделы
+% отчета должны иметь заголовки. Пункты и подпункты, как правило, заголовков не
+% имеют.
+
+% 6.2.3 Заголовки разделов и подразделов основной части отчета следует начинать
+% с абзацного отступа и размещать после порядкового номера, печатать с
+% прописной буквы, полужирным шрифтом, не подчеркивать, без точки в конце.
+% Пункты и подпункты могут иметь только порядковый номер без заголовка,
+% начинающийся с абзацного отступа.
+\titleformat{\section}[block]{\hspace{\parindent}\normalfont\bfseries}{\thesection}{1em}{}
+\titleformat{\subsection}[block]{\hspace{\parindent}\normalfont\bfseries}{\thesubsection}{1em}{}
+\titleformat{\subsubsection}[block]{\hspace{\parindent}\normalfont\bfseries}{\thesubsubsection}{1em}{}
+\titleformat{\paragraph}[block]{\hspace{\parindent}\normalfont\bfseries}{\theparagraph}{1em}{}
+\titleformat{\subparagraph}[block]{\hspace{\parindent}\normalfont\bfseries}{\thesubparagraph}{1em}{}
+
+\titlespacing*{\section}{0pt}{0pt}{2ex}[2ex]
+\titlespacing*{\subsection}{0pt}{2ex}{2ex}[2ex]
+\titlespacing*{\subsubsection}{0pt}{2ex}{2ex}[2ex]
+\titlespacing*{\paragraph}{0pt}{2ex}{2ex}[2ex]
+\titlespacing*{\subparagraph}{0pt}{2ex}{2ex}[2ex]
+
+% 6.2.4 Если заголовок включает несколько предложений, их разделяют точками.
+% Переносы слов в заголовках не допускаются.
+
+\newcommand{\introduction}{
+ \structure{ВВЕДЕНИЕ}
+}
+
+\newcommand{\conclusion}{
+ \structure{ЗАКЛЮЧЕНИЕ}
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/03-IU8-numbering.sty b/macros/latex/contrib/bmstu-iu8/styles/03-IU8-numbering.sty
new file mode 100644
index 0000000000..b9ebc5b699
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/03-IU8-numbering.sty
@@ -0,0 +1,17 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{03-IU8-numbering}[2021/03/21 v1.0 Нумерация страниц отчета]
+
+% 6.3.1 Страницы отчета следует нумеровать арабскими цифрами, соблюдая сквозную
+% нумерацию по всему тексту отчета, включая приложения. Номер страницы
+% проставляется в центре нижней части страницы без точки. Приложения, которые
+% приведены в отчете о НИР и имеющие собственную нумерацию, допускается не перенумеровать.
+\pagestyle{plain}
+\pagenumbering{arabic}
+
+% 6.3.2 Титульный лист включают в общую нумерацию страниц отчета. Номер страницы
+% на титульном листе не проставляют.
+
+% 6.3.3 Иллюстрации и таблицы, расположенные на отдельных листах, включают в общую
+% нумерацию страниц отчета. Иллюстрации и таблицы на листе формата А3 учитывают
+% как одну страницу.
diff --git a/macros/latex/contrib/bmstu-iu8/styles/04-IU8-section-numbering.sty b/macros/latex/contrib/bmstu-iu8/styles/04-IU8-section-numbering.sty
new file mode 100644
index 0000000000..de614468c4
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/04-IU8-section-numbering.sty
@@ -0,0 +1,52 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{04-IU8-section-numbering}[2021/03/21 v1.0 Нумерация разделов, подразделов, пунктов, подпунктов и книг отчета]
+
+% 6.4.1 Разделы должны иметь порядковые номера в пределах всего отчета,
+% обозначенные арабскими цифрами без точки и расположенные с абзацного отступа.
+% Подразделы должны иметь нумерацию в пределах каждого раздела. Номер подраздела
+% состоит из номеров раздела и подраздела, разделенных точкой.
+% В конце номера подраздела точка не ставится. Разделы, как и
+% подразделы, могут состоять из одного или нескольких пунктов.
+
+% Это настройка по умолчанию, так что её не меняю
+% Про абзацный отступ учетно в 02-IU8-construction
+
+% 6.4.2 Если отчет не имеет подразделов, то нумерация пунктов в нем должна
+% быть в пределах каждого раздела и номер пункта должен состоять из номеров
+% раздела и пункта, разделенных точкой. В конце номера пункта точка не ставится.
+% Если отчет имеет подразделы, то нумерация пунктов должна быть в пределах
+% подраздела и номер пункта должен состоять
+% из номеров раздела, подраздела и пункта, разделенных точками.
+
+% Это настройка по умолчанию, так что её не меняю
+
+% 6.4.6 Внутри пунктов или подпунктов могут быть приведены перечисления.
+% Перед каждым элементом перечисления следует ставить тире. При необходимости
+% ссылки в тексте отчета на один из элементов перечисления вместо тире ставят
+% строчные буквы русского алфавита со скобкой, начиная с буквы "а" (за
+% исключением букв ё, з, й, о, ч, ъ, ы, ь). Простые перечисления отделяются
+% запятой, сложные - точкой с запятой.
+% При наличии конкретного числа перечислений допускается перед каждым элементом
+% перечисления ставить арабские цифры, после которых ставится скобка.
+\RequirePackage{enumitem}
+\AddEnumerateCounter{\Asbuk}{\@Asbuk}{А}
+\AddEnumerateCounter{\asbuk}{\@asbuk}{а}
+
+\setlist[enumerate]{
+ leftmargin=\parindent+\labelwidth+\labelsep,
+ labelindent=\parindent,
+ align=left,
+ nosep,
+}
+\setlist[itemize]{
+ label=\textendash,
+ leftmargin=\parindent+\labelwidth+\labelsep,
+ labelindent=\parindent,
+ align=left,
+ nosep,
+}
+\setlist[enumerate, 1]{label=\asbuk*)}
+\setlist[enumerate, 2]{label=\arabic*)}
+\setlist[enumerate, 3]{label=\alph*)}
+\setlist[enumerate, 4]{label=\roman*)} \ No newline at end of file
diff --git a/macros/latex/contrib/bmstu-iu8/styles/05-IU8-figures.sty b/macros/latex/contrib/bmstu-iu8/styles/05-IU8-figures.sty
new file mode 100644
index 0000000000..c0f50267de
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/05-IU8-figures.sty
@@ -0,0 +1,54 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{05-IU8-figures}[2021/03/21 v1.0 Иллюстрации]
+
+% 6.5.1 Иллюстрации (чертежи, графики, схемы, компьютерные распечатки, диаграммы,
+% фотоснимки) следует располагать в отчете непосредственно после текста отчета,
+% где они упоминаются впервые, или на следующей странице (по возможности ближе к
+% соответствующим частям текста отчета). На все иллюстрации в отчете должны быть
+% даны ссылки. При ссылке необходимо писать слово "рисунок" и его номер,
+% например: "в соответствии с рисунком 2" и т.д.
+\RequirePackage{float}
+\def\fps@figure{H}
+
+% 6.5.2 Чертежи, графики, диаграммы, схемы, помещаемые в отчете, должны
+% соответствовать требованиям стандартов
+% Единой системы конструкторской документации (ЕСКД).
+
+% 6.5.3 Количество иллюстраций должно быть достаточным для пояснения
+% излагаемого текста отчета. Не рекомендуется в отчете о НИР приводить
+% объемные рисунки.
+
+% 6.5.4 Иллюстрации, за исключением иллюстраций, приведенных в приложениях,
+% следует нумеровать арабскими цифрами сквозной нумерацией. Если рисунок один,
+% то он обозначается: Рисунок 1.
+% Пример - Рисунок 1 - Схема прибора
+
+% 6.5.5 Иллюстрации каждого приложения обозначают отдельной нумерацией арабскими
+% цифрами с добавлением перед цифрой обозначения приложения: Рисунок А.3.
+
+% 6.5.6 Допускается нумеровать иллюстрации в пределах раздела отчета.
+% В этом случае номер иллюстрации состоит из номера раздела и порядкового номера
+% иллюстрации, разделенных точкой: Рисунок 2.1.
+
+% 6.5.7 Иллюстрации при необходимости могут иметь наименование и пояснительные
+% данные (подрисуночный текст).
+% Слово "Рисунок", его номер и через тире наименование помещают после
+% пояснительных данных и располагают в центре под
+% рисунком без точки в конце.
+% Пример - Рисунок 2 - Оформление таблицы
+
+% 6.5.8 Если наименование рисунка состоит из нескольких строк, то его следует
+% записывать через один межстрочный интервал. Наименование рисунка приводят с
+% прописной буквы без точки в конце. Перенос слов в наименовании графического
+% материала не допускается.
+
+\RequirePackage{caption} % Настройка подписи
+\captionsetup[figure]{
+ name=Рисунок, % 6.5.7
+ labelsep=endash, % 6.5.7
+ position=below, % 6.5.7
+ justification=centering, % Выравнивание по центру
+ font={stretch=\setspace@singlespace}, % 6.5.8
+ width=0.8\linewidth, % Ограничение по длине, а то будет на всю строку
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/06-IU8-tables.sty b/macros/latex/contrib/bmstu-iu8/styles/06-IU8-tables.sty
new file mode 100644
index 0000000000..fd08b71fb9
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/06-IU8-tables.sty
@@ -0,0 +1,78 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{06-IU8-tables}[2021/03/21 v1.0 Таблицы]
+
+% Пакеты, которые скорее всего пригодятся
+\RequirePackage{tabularx}
+\RequirePackage{longtable}
+\RequirePackage{xltabular}
+\RequirePackage{multirow}
+\RequirePackage{hhline}
+
+% 6.6.1 Цифровой материал должен оформляться в виде таблиц. Таблицы применяют
+% для наглядности и удобства сравнения показателей.
+
+% 6.6.2 Таблицу следует располагать непосредственно после текста, в котором она
+% упоминается впервые, или на следующей странице.
+% На все таблицы в отчете должны быть ссылки. При ссылке следует печатать слово
+% "таблица" с указанием ее номера.
+\RequirePackage{float}
+\def\fps@table{H}
+
+% 6.6.3 Наименование таблицы, при ее наличии, должно отражать ее содержание,
+% быть точным, кратким. Наименование следует помещать над таблицей слева,
+% без абзацного отступа в следующем формате:
+% Таблица Номер таблицы - Наименование таблицы.
+% Наименование таблицы приводят с прописной буквы без точки в конце.
+% Если наименование таблицы занимает две строки и более, то его следует
+% записывать через один межстрочный интервал.
+% Таблицу с большим количеством строк допускается переносить на другую страницу.
+% При переносе части таблицы на другую страницу слово "Таблица", ее номер и
+% наименование указывают один раз слева над первой частью таблицы, а над
+% другими частями также слева пишут слова "Продолжение таблицы" и указывают
+% номер таблицы.
+% При делении таблицы на части допускается ее головку или боковик заменять
+% соответственно номерами граф и строк. При этом нумеруют арабскими цифрами
+% графы и (или) строки первой части таблицы.
+\RequirePackage{caption} % Настройка подписи
+\captionsetup[table]{
+ name=Таблица,
+ labelsep=endash, % Тире
+ position=above,
+ justification=justified, % Выравнивание по ширине
+ singlelinecheck=false,
+ font={stretch=\setspace@singlespace},
+}
+
+% 6.6.4 Таблицы, за исключением таблиц приложений, следует нумеровать
+% арабскими цифрами сквозной нумерацией.
+% Таблицы каждого приложения обозначаются отдельной нумерацией арабскими цифрами
+% с добавлением перед цифрой обозначения приложения. Если в отчете одна таблица,
+% она должна быть обозначена "Таблица 1" или "Таблица А.1" (если она
+% приведена в приложении А).
+% Допускается нумеровать таблицы в пределах раздела при большом объеме отчета.
+% В этом случае номер таблицы состоит из
+% номера раздела и порядкового номера таблицы, разделенных точкой: Таблица 2.3.
+
+% 6.6.5 Заголовки граф и строк таблицы следует печатать с прописной буквы, а
+% подзаголовки граф - со строчной буквы, если они составляют одно предложение с
+% заголовком, или с прописной буквы, если они имеют самостоятельное значение.
+% В конце заголовков и подзаголовков таблиц точки не ставятся. Названия
+% заголовков и подзаголовков таблиц указывают в единственном
+% числе.
+
+% 6.6.6 Таблицы слева, справа, сверху и снизу ограничивают линиями.
+% Разделять заголовки и подзаголовки боковика и граф диагональными линиями не
+% допускается. Заголовки граф выравнивают по центру, а заголовки строк -
+% по левому краю.
+% Горизонтальные и вертикальные линии, разграничивающие строки таблицы,
+% допускается не проводить, если их отсутствие не затрудняет пользование
+% таблицей.
+
+% 6.6.7 Текст, повторяющийся в строках одной и той же графы и состоящий из
+% одиночных слов, заменяют кавычками.
+% Ставить кавычки вместо повторяющихся цифр, буквенно-цифровых обозначений,
+% знаков и символов не допускается.
+% Если текст повторяется, то при первом повторении его заменяют словами
+% "то же", а далее кавычками.
+% В таблице допускается применять размер шрифта меньше, чем в тексте отчета. \ No newline at end of file
diff --git a/macros/latex/contrib/bmstu-iu8/styles/07-IU8-footnotes.sty b/macros/latex/contrib/bmstu-iu8/styles/07-IU8-footnotes.sty
new file mode 100644
index 0000000000..a485d0d0af
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/07-IU8-footnotes.sty
@@ -0,0 +1,37 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{07-IU8-footnotes}[2021/03/21 v1.0 Примечания и сноски]
+
+% 6.7.1 Примечания приводят в отчете, если необходимы пояснения или справочные
+% данные к содержанию текста, таблиц или графического материала.
+
+% 6.7.2 Слово "Примечание" следует печатать с прописной буквы с абзацного
+% отступа, не подчеркивая.
+
+% 6.7.3 Примечания следует помещать непосредственно после текстового,
+% графического материала или таблицы, к которым относятся эти примечания.
+% Если примечание одно, то после слова "Примечание" ставится тире и текст
+% примечания печатают с прописной буквы. Одно примечание не нумеруется.
+% Несколько примечаний нумеруют по порядку арабскими цифрами без
+% точки.
+% Примеры
+% 1 Примечание - Применение локально введенных кодов обеспечивает определенный
+% уровень гибкости, который дает возможность проводить улучшения или изменения,
+% сохраняя при этом совместимость с основным набором элементов
+% данных.
+% 2 Примечания
+% 1 К тексту дается... .
+% 2 Дополнительные данные... .
+
+% 6.7.4 При необходимости дополнительного пояснения в отчете допускается
+% использовать примечание, оформленное в виде сноски. Знак сноски ставят без
+% пробела непосредственно после того слова, числа, символа, предложения,
+% к которому дается пояснение. Знак сноски указывается надстрочно
+% арабскими цифрами. Допускается вместо цифр использовать знак звездочка - *.
+% Сноску располагают с абзацного отступа в конце страницы, на которой
+% приведено поясняемое слово (словосочетание или данные). Сноску отделяют от
+% текста короткой сплошной тонкой горизонтальной линией с левой стороны
+% страницы.
+
+
+% Настройки по умолчанию всему этому удовлетворяют \ No newline at end of file
diff --git a/macros/latex/contrib/bmstu-iu8/styles/08-IU8-formulas.sty b/macros/latex/contrib/bmstu-iu8/styles/08-IU8-formulas.sty
new file mode 100644
index 0000000000..5370ea82a6
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/08-IU8-formulas.sty
@@ -0,0 +1,5 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{08-IU8-formulas}[2021/03/21 v1.0 Формулы]
+
+% Настройки по умолчанию в целом соответствуют ГОСТ \ No newline at end of file
diff --git a/macros/latex/contrib/bmstu-iu8/styles/09-IU8-cites.sty b/macros/latex/contrib/bmstu-iu8/styles/09-IU8-cites.sty
new file mode 100644
index 0000000000..8a42ee23f6
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/09-IU8-cites.sty
@@ -0,0 +1,19 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{09-IU8-cites}[2021/03/21 v1.0 Ссылки]
+
+% 6.9.1 В отчете о НИР рекомендуется приводить ссылки на использованные
+% источники. При нумерации ссылок на документы, использованные при составлении
+% отчета, приводится сплошная нумерация для всего текста отчета в целом или для
+% отдельных разделов. Порядковый номер ссылки (отсылки) приводят арабскими
+% цифрами в квадратных скобках в конце текста ссылки. Порядковый номер
+% библиографического описания источника в списке использованных источников
+% соответствует
+% номеру ссылки.
+
+% 6.9.2 Ссылаться следует на документ в целом или на его разделы и приложения.
+
+% 6.9.3 При ссылках на стандарты и технические условия указывают их обозначение,
+% при этом допускается не указывать год их утверждения при условии полного
+% описания стандарта и технических условий в списке использованных источников в
+% соответствии с ГОСТ 7.1.
diff --git a/macros/latex/contrib/bmstu-iu8/styles/10-IU8-titlepage.sty b/macros/latex/contrib/bmstu-iu8/styles/10-IU8-titlepage.sty
new file mode 100644
index 0000000000..1d1cc37751
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/10-IU8-titlepage.sty
@@ -0,0 +1,237 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{10-IU8-titlepage}[2021/03/21 v1.0 Титульный лист]
+
+% Поля для заполнения для ВКР
+\def\student#1{\gdef\@student{#1}}
+\def\@student{\@latex@warning@no@line{No \noexpand\student given}}
+
+\def\theme#1{\gdef\@theme{#1}}
+\def\@theme{\@latex@warning@no@line{No \noexpand\theme given}}
+
+\def\group#1{\gdef\@group{#1}}
+\def\@group{\@latex@warning@no@line{No \noexpand\group given}}
+
+\def\supervisor#1{\gdef\@supervisor{#1}}
+\def\@supervisor{\@latex@warning@no@line{No \noexpand\supervisor given}}
+
+\def\researchConsultant#1{\gdef\@researchConsultant{#1}}
+\def\@researchConsultant{\@latex@warning@no@line{No \noexpand\researchConsultant given}}
+
+\def\designConsultant#1{\gdef\@designConsultant{#1}}
+\def\@designConsultant{\@latex@warning@no@line{No \noexpand\designConsultant given}}
+
+\def\technologicalConsultant#1{\gdef\@technologicalConsultant{#1}}
+\def\@technologicalConsultant{\@latex@warning@no@line{No \noexpand\technologicalConsultant given}}
+
+\def\economicsConsultant#1{\gdef\@economicsConsultant{#1}}
+\def\@economicsConsultant{\@latex@warning@no@line{No \noexpand\economicsConsultant given}}
+
+\def\lawsConsultant#1{\gdef\@lawsConsultant{#1}}
+\def\@lawsConsultant{\@latex@warning@no@line{No \noexpand\lawsConsultant given}}
+
+\def\normController#1{\gdef\@normController{#1}}
+\def\@normController{\@latex@warning@no@line{No \noexpand\normController given}}
+
+% Поля для заполнения для НИР
+\def\studentFullName#1{\gdef\@studentFullName{#1}}
+\def\@studentFullName{\@latex@warning@no@line{No \noexpand\studentFullName given}}
+
+\def\profile#1{\gdef\@profile{#1}}
+\def\@profile{\@latex@warning@no@line{No \noexpand\profile given}}
+
+\def\speciality#1{\gdef\@speciality{#1}}
+\def\@speciality{\@latex@warning@no@line{No \noexpand\speciality given}}
+
+\def\specialization#1{\gdef\@specialization{#1}}
+\def\@specialization{\@latex@warning@no@line{No \noexpand\specialization given}}
+
+\def\supervisorWithDegree#1{\gdef\@supervisorWithDegree{#1}}
+\def\@supervisorWithDegree{\@latex@warning@no@line{No \noexpand\supervisorWithDegree given}}
+
+
+\RequirePackage{fancyhdr}
+\fancypagestyle{year}{
+ \fancyfoot[C]{\itshape Москва, \the\year~г.}
+ \renewcommand{\headrulewidth}{0pt}
+ \fancyhead{}
+}
+
+\RequirePackage{tabto}
+\RequirePackage[normalem]{ulem}
+\RequirePackage[usestackEOL]{stackengine}
+\RequirePackage{lineno}
+\RequirePackage{xstring}
+\RequirePackage{ifthen}
+
+\newcommand\makeUlineStack[3][3cm]{
+ \Shortunderstack{
+ \uline{\parbox{#1}{\centering #2}}\\
+ {\fontsize{9pt}{9pt}\selectfont #3}
+ }
+}
+
+\newcommand\makeBMSTUHeader{
+ \noindent\begin{minipage}{0.05\textwidth}
+ \includegraphics[scale=0.4]{inc/bmstu.png}
+ \end{minipage}
+ \hfill
+ \begin{minipage}{0.85\textwidth}\raggedleft
+ \begin{center}
+ \fontsize{10pt}{0.3\baselineskip}\selectfont
+ \textbf{Министерство науки и высшего образования
+ Российской Федерации \\
+ Федеральное государственное бюджетное образовательное
+ учреждение \\
+ высшего образования \\
+ <<Московский государственный технический университет \\
+ имени Н. Э. Баумана \\
+ (национальный исследовательский университет)>> \\
+ (МГТУ им. Н. Э. Баумана)
+ }
+ \end{center}
+ \end{minipage}
+ \begin{center}
+ \fontsize{12pt}{0.1\baselineskip}\selectfont
+ \noindent\makebox[\linewidth]{\rule{\textwidth}{2pt}}
+ \makebox[\linewidth]{\rule{\textwidth}{1pt}}
+ \end{center}
+ \begin{flushleft}
+ \fontsize{12pt}{14pt}\selectfont
+ ФАКУЛЬТЕТ \tabto{3cm} <<Информатика и системы управления>> (ИУ)\\
+ КАФЕДРА \tabto{3cm} <<Информационная безопасность>> (ИУ8)
+ \end{flushleft}
+}
+
+\newcommand\fillingBox[3][\maxlen]{
+ \noindent#2 \hfill \makeUlineStack[2.5cm]{~}{(Подпись, дата)} \quad
+ \makeUlineStack[#1]{#3}{(И. О. Фамилия)}\\
+}
+
+\newcommand\makeDiplomaTheme[1]{
+ \noindent
+ \begin{minipage}{\linewidth}
+ \centering\internallinenumbers\rmfamily\bfseries\fontsize{20pt}{20pt}\selectfont
+ \renewcommand{\makeLineNumber}{\rule[-0.7ex]{\textwidth}{0.4pt}\hss}%
+ #1
+ \end{minipage}
+}
+
+\newlength{\maxlen}
+\newlength{\templen}
+
+\newcommand\CompLen[1]{
+ \settowidth{\templen}{#1}
+ \ifdim\templen>\maxlen
+ \settowidth{\maxlen}{#1}
+ \fi
+}
+
+\newcommand\fillDiplomaTitle{
+ \noindent\begin{center}
+ \centering\bfseries\fontsize{20pt}{25pt}\selectfont
+ РАСЧЁТНО-ПОЯСНИТЕЛЬНАЯ~ЗАПИСКА\\
+ {\fontsize{16pt}{25pt}\bfseries\selectfont К~ВЫПУСКОЙ~КВАЛИФИКАЦИОННОЙ~РАБОТЕ}\\
+ {\fontsize{16pt}{25pt}\bfseries\selectfont НА~ТЕМУ:}
+ \end{center}
+
+ \vfill
+
+ \makeDiplomaTheme{\@theme}
+
+ \vfill
+
+ {\fontsize{12pt}{15pt}\selectfont
+
+ \fillingBox{Студент \hfill \makeUlineStack[2cm]{\@group}{(Группа)}}{\@student}
+
+ \fillingBox{Руководитель ВКР}{\@supervisor}
+
+ \fillingBox{Консультант по исследовательской части}{\@researchConsultant}
+
+ \fillingBox{Консультант по конструкторской части}{\@designConsultant}
+
+ \fillingBox{Консультант по технологической части}{\@technologicalConsultant}
+
+ \fillingBox{Консультант по организационно-\\экономической части}{\@economicsConsultant}
+
+ \fillingBox{Консультант по организационно-\\правовому обеспечению ИБ}{\@lawsConsultant}
+
+ \fillingBox{Нормоконтролер}{\@normController}
+ }
+}
+
+\newcommand\makeResearchTheme[1]{
+ \noindent на тему \uline{#1}
+}
+
+\newcommand\fillResearchTitle{
+ \noindent\begin{center}
+ \centering\bfseries\fontsize{20pt}{25pt}\selectfont
+ Отчёт\\
+ {\fontsize{16pt}{25pt}\bfseries\selectfont по научно-исследовательской работе студента}\\
+ \end{center}
+
+ \vfill
+
+ \makeResearchTheme{\@theme}
+
+ \vfill
+ {
+ \setlength{\tabcolsep}{0pt}
+ \renewcommand{\arraystretch}{1.5}
+ \noindent \begin{tabular}{ll}
+ \noindent ФИО студента: & \@studentFullName \\
+ \noindent Группа: & \@group \\
+ \noindent Специальность: & \@speciality \\
+ \noindent Специализация: & \@specialization \\
+ \end{tabular}
+ }
+
+ \bigskip
+
+ \noindent Научный руководитель НИРС: \@supervisorWithDegree
+
+ \bigskip
+
+ \noindent Работа выполнена: \hfill \makeUlineStack[2.5cm]{~}{Дата} \quad \makeUlineStack[2.5cm]{~}{Подпись} \quad \makeUlineStack[4cm]{\@student}{(И. О. Фамилия)}
+
+ \bigskip
+
+ \noindent Допуск к защите: \hfill \makeUlineStack[2.5cm]{~}{Дата} \quad \makeUlineStack[2.5cm]{~}{Подпись} \quad \makeUlineStack[4cm]{\@supervisor}{(И. О. Фамилия)}
+
+ \vfill
+ {
+ \setlength{\tabcolsep}{0pt}
+ \renewcommand{\arraystretch}{1.5}
+ \noindent \begin{tabular}{ll}
+ \noindent Дата защиты НИРС: & \makeUlineStack[6cm]{~}{~} \\
+ \noindent Результаты защиты: & \makeUlineStack[6cm]{~}{~} \\
+ \end{tabular}
+ }
+
+ \vfill
+
+ \clearpage
+}
+
+\renewcommand\maketitle{
+ \begin{titlepage}
+ \settowidth{\maxlen}{\@student}
+ \CompLen{\@student}
+ \CompLen{\@supervisor}
+ \CompLen{\@researchConsultant}
+ \CompLen{\@designConsultant}
+ \CompLen{\@technologicalConsultant}
+ \CompLen{\@economicsConsultant}
+ \CompLen{\@lawsConsultant}
+ \CompLen{\@normController}
+
+ \thispagestyle{year}
+ \makeBMSTUHeader
+
+ \fillTitle
+
+ \clearpage
+ \end{titlepage}
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/11-IU8-performers.sty b/macros/latex/contrib/bmstu-iu8/styles/11-IU8-performers.sty
new file mode 100644
index 0000000000..8ba0ce8458
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/11-IU8-performers.sty
@@ -0,0 +1,5 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{10-IU8-performes}[2021/03/21 v1.0 Список исполниетелей]
+
+% Т.к. у нас это не используется, я оставляю это пустымы \ No newline at end of file
diff --git a/macros/latex/contrib/bmstu-iu8/styles/12-IU8-abstract.sty b/macros/latex/contrib/bmstu-iu8/styles/12-IU8-abstract.sty
new file mode 100644
index 0000000000..c674c5efac
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/12-IU8-abstract.sty
@@ -0,0 +1,27 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{12-IU8-abstract}[2021/03/21 v1.0 Реферат]
+
+% 6.12.1 Сведения об общем объеме отчета, количестве книг отчета, иллюстраций,
+% таблиц, использованных источников, приложений являются первой компонентой
+% реферата и располагаются с абзацного отступа, в строку, через запятые.
+
+% 6.12.2 Ключевые слова являются второй компонентой реферата. Они приводятся в
+% именительном падеже и печатаются прописными буквами, в строку, через запятые,
+% без абзацного отступа и переноса слов, без точки в конце перечня.
+
+% 6.12.3 Текст реферата помещается с абзацного отступа после ключевых слов.
+% Для выделения структурных частей реферата в соответствии с 5.3.2.2
+% используются абзацные отступы.
+
+\RequirePackage{lastpage}
+
+\renewcommand{\abstract}{
+ \structure*{РЕФЕРАТ}
+
+ Отчёт содержит \pageref{LastPage} стр.\ifnum
+ \TotalValue{totalfigures}>0, \TotalValue{totalfigures} рис.\fi\ifnum
+ \TotalValue{totaltables}>0, \TotalValue{totaltables} табл.\fi\ifnum
+ \TotalValue{totalcites}>0, \TotalValue{totalcites} источн.\fi\ifnum
+ \TotalValue{totalappendices}>0, \TotalValue{totalappendices} прил.\fi
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/13-IU8-contents.sty b/macros/latex/contrib/bmstu-iu8/styles/13-IU8-contents.sty
new file mode 100644
index 0000000000..4bba4deb7e
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/13-IU8-contents.sty
@@ -0,0 +1,29 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{13-IU8-contents}[2021/03/21 v1.0 Содержание]
+
+% Каждую запись содержания оформляют как отдельный абзац, выровненный влево.
+% Номера страниц указывают выровненными по правому краю поля и соединяют
+% с наименованием структурного элемента или раздела отчета посредством
+% отточия.
+
+\renewcommand\tableofcontents{
+ \structure*{СОДЕРЖАНИЕ}
+ \@starttoc{toc}
+}
+
+\renewcommand*\l@section{\@dottedtocline{0}{0mm}{2em}}
+\renewcommand*\l@structure{\@dottedtocline{0}{0mm}{0em}}
+% ГОСТ 7.32-2017. Пункт 5.4.1:
+% Обозначения подразделов приводят после абзацного отступа,
+% равного двум знакам, относительно обозначения разделов.
+\renewcommand*\l@subsection{\@dottedtocline{1}{5mm}{3em}}
+% ГОСТ 7.32-2017. Пункт 5.4.1:
+% Обозначения пунктов приводят после абзацного отступа,
+% равного четырем знакам, относительно обозначения разделов.
+\renewcommand*\l@subsubsection{\@dottedtocline{2}{10mm}{4em}}
+% Остальное - индуктивно
+\renewcommand*\l@paragraph{\@dottedtocline{3}{15mm}{5em}}
+
+\setcounter{secnumdepth}{5} % Глубина заголовков - до пятого уровня
+\setcounter{tocdepth}{2} % Глубина содержания - до второго уровня
diff --git a/macros/latex/contrib/bmstu-iu8/styles/14-IU8-terms-and-definitions.sty b/macros/latex/contrib/bmstu-iu8/styles/14-IU8-terms-and-definitions.sty
new file mode 100644
index 0000000000..ea679bd6c5
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/14-IU8-terms-and-definitions.sty
@@ -0,0 +1,44 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{14-IU8-terms-and-definitions}[2021/03/21 v1.0 Содержание]
+
+\RequirePackage[
+ acronym,
+ automake,
+ nopostdot,
+ xindy={glsnumbers=false, language=russian},
+]{glossaries}
+\RequirePackage[abbreviations]{glossaries-extra}
+
+\GlsSetXdyCodePage{utf8}
+
+\renewcommand{\glossarysection}[2][]{}
+
+\newglossarystyle{terms}{
+ \renewenvironment{theglossary}{}{}
+ \renewcommand*{\glossentry}[2]{
+ \noindent\glstarget{##1}{\glossentryname{##1}}~\textemdash~\glossentrydesc{##1}
+ \newline
+ }
+ \renewcommand*{\glsgroupskip}{}%
+}
+
+\newcommand{\termsanddefenitions}{
+ \structure{ТЕРМИНЫ~И~ОПРЕДЕЛЕНИЯ}
+
+ \termsAndDefinitionsLine
+
+ \printunsrtglossary[
+ style=terms,
+ nonumberlist
+ ]
+}
+
+% \newglossarystyle{definitions}{%
+% \renewenvironment{theglossary}{}{}
+% \renewcommand*{\glossentry}[2]{
+% \noindent\glstarget{##1}{\glossentryname{##1}}~\textemdash~\glossentrydesc{##1}
+% \newline
+% }
+% \renewcommand*{\glsgroupskip}{}%
+% }
diff --git a/macros/latex/contrib/bmstu-iu8/styles/15-IU8-list-of-abbreviations.sty b/macros/latex/contrib/bmstu-iu8/styles/15-IU8-list-of-abbreviations.sty
new file mode 100644
index 0000000000..8440aac950
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/15-IU8-list-of-abbreviations.sty
@@ -0,0 +1,29 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{15-IU8-list-of-abbreviations}[2021/03/21 v1.0 Содержание]
+
+\RequirePackage[abbreviations]{glossaries-extra}
+
+\GlsSetXdyCodePage{utf8}
+
+\renewcommand{\glossarysection}[2][]{}
+
+\newglossarystyle{definitions}{
+ \renewenvironment{theglossary}{}{}
+ \renewcommand*{\glossentry}[2]{
+ \noindent\glstarget{##1}{\glossentryname{##1}}~\textemdash~\glossentrydesc{##1}
+ \newline
+ }
+ \renewcommand*{\glsgroupskip}{}
+}
+
+\newcommand{\listofabbreviations}{
+ \structure{ПЕРЕЧЕНЬ~СОКРАЩЕНИЙ~И~ОБОЗНАЧЕНИЙ}
+
+ \abbreviationsLine
+
+ \printunsrtglossary[
+ style=definitions,
+ type=\acronymtype
+ ]
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/16-IU8-references.sty b/macros/latex/contrib/bmstu-iu8/styles/16-IU8-references.sty
new file mode 100644
index 0000000000..65c710c41f
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/16-IU8-references.sty
@@ -0,0 +1,27 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{16-IU8-references}[2021/03/21 v1.0 Список использованных источников]
+
+% Сведения об источниках следует располагать в порядке появления ссылок на
+% источники в тексте отчета и нумеровать арабскими цифрами с точкой и печатать
+% с абзацного отступа.
+\usepackage[
+ backend=biber,
+ style=gost-numeric,
+ % refsection=structure,
+ % sorting=ynt,
+]{biblatex}
+\defbibheading{bibliography}[СПИСОК~ИСПОЛЬЗОВАННЫХ~ИСТОЧНИКОВ]{\structure{#1}}
+\addto{\captionsrussian}{%
+ \renewcommand{\contentsname}{СОДЕРЖАНИЕ}
+}
+
+% \bibliographystyle{ugost2008}
+% \renewcommand{\@biblabel}[1]{#1.}
+
+ % \usepackage{natbib}
+% \renewcommand\bibsection{%
+% \structure*{{\normalsize\underline{\refname}}\@mkboth{\MakeUppercase{\refname}}{\MakeUppercase{\refname}}}%
+% }%
+% \def\bibheading{bibliography}{\section*{Bibliography}}
+% \usepackage[nottoc,numbib]{tocbibind} \ No newline at end of file
diff --git a/macros/latex/contrib/bmstu-iu8/styles/17-IU8-appendices.sty b/macros/latex/contrib/bmstu-iu8/styles/17-IU8-appendices.sty
new file mode 100644
index 0000000000..26f692b165
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/17-IU8-appendices.sty
@@ -0,0 +1,23 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{17-IU8-appendices}[2021/03/21 v1.0 Приложения]
+
+\newcommand{\appendixsection}[1]{
+ \stepcounter{apps}
+ \section*{\Asbuk{apps}}
+ \begin{center}
+ \bfseries #1
+ \end{center}
+ \addcontentsline{toc}{section}{ПРИЛОЖЕНИЕ~\Asbuk{apps}~{#1}}
+}
+
+\renewcommand{\appendix}{
+ \renewcommand\section{\clearpage\@startsection{section}{1}{0pt}{1em}{1em}{\bfseries\centering ПРИЛОЖЕНИЕ~}}
+ \setcounter{section}{0}
+ \setcounter{figure}{0}
+ \setcounter{table}{0}
+ \setcounter{equation}{0}
+ \renewcommand\thefigure{\Asbuk{apps}.\arabic{figure}}
+ \renewcommand\thetable{\Asbuk{apps}.\arabic{figure}}
+ \renewcommand\theequation{\Asbuk{apps}.\arabic{figure}}
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/18-IU8-extra.sty b/macros/latex/contrib/bmstu-iu8/styles/18-IU8-extra.sty
new file mode 100644
index 0000000000..c456e8e8fd
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/18-IU8-extra.sty
@@ -0,0 +1,27 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{18-IU8-extra}[2021/03/21 v1.0 Разные улучшения]
+
+\RequirePackage{graphicx}
+
+\RequirePackage[none]{hyphenat} % Отключим переносы, так красивее
+
+\RequirePackage[all, defaultlines=4]{nowidow} % Запрет "висячих" слов
+
+\sloppy % Запретить выход текста за поля
+
+\RequirePackage{bookmark}
+\def\toclevel@structure{1} % Для правильного отображения в содержании pdf
+
+\hypersetup{
+ colorlinks=true,
+ unicode=true,
+ urlcolor=black,
+ linkcolor=black,
+ anchorcolor=black,
+ citecolor=black,
+ menucolor=black,
+ filecolor=black,
+} % Кликабельные ссылки в pdf
+
+\hbadness=10000
diff --git a/macros/latex/contrib/bmstu-iu8/styles/19-IU8-counters.sty b/macros/latex/contrib/bmstu-iu8/styles/19-IU8-counters.sty
new file mode 100644
index 0000000000..35253a1b2d
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/19-IU8-counters.sty
@@ -0,0 +1,22 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{19-IU8-counters}[2021/03/21 v1.0 Счётчики]
+
+\RequirePackage{calc}
+\RequirePackage{xassoccnt}
+\RequirePackage{totcount}
+
+\NewTotalDocumentCounter{totalfigures}
+\DeclareAssociatedCounters{figure}{totalfigures}
+\NewTotalDocumentCounter{totaltables}
+\DeclareAssociatedCounters{table}{totaltables}
+
+\RequirePackage{totcount}
+\newtotcounter{citenum}
+\AtEveryBibitem{\stepcounter{citenum}}
+\NewTotalDocumentCounter{totalcites}
+\DeclareAssociatedCounters{citenum}{totalcites}
+
+\newcounter{apps}
+\NewTotalDocumentCounter{totalappendices}
+\DeclareAssociatedCounters{apps}{totalappendices}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/20-IU8-listing.sty b/macros/latex/contrib/bmstu-iu8/styles/20-IU8-listing.sty
new file mode 100644
index 0000000000..a2d817a0fb
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/20-IU8-listing.sty
@@ -0,0 +1,43 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{20-IU8-listing}[2021/03/21 v1.0 Листинги]
+
+\RequirePackage{listings}
+\RequirePackage{xcolor}
+
+\definecolor{codegreen}{rgb}{0,0.6,0}
+\definecolor{codegray}{rgb}{0.5,0.5,0.5}
+\definecolor{codepurple}{rgb}{0.58,0,0.82}
+\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
+
+\lstdefinestyle{IU8}{
+ % backgroundcolor=\color{backcolour},
+ % commentstyle=\color{codegreen},
+ % keywordstyle=\color{magenta},
+ numberstyle=\tiny\color{black},
+ % stringstyle=\color{codepurple},
+ basicstyle=\ttfamily\footnotesize,
+ breakatwhitespace=false,
+ breaklines=true,
+ captionpos=tl,
+ xleftmargin=0.5\parindent,
+ keepspaces=true,
+ numbers=left,
+ numbersep=5pt,
+ showspaces=false,
+ showstringspaces=false,
+ showtabs=false,
+ tabsize=2,
+}
+\lstset{style=IU8}
+
+\DeclareCaptionFormat{listing}{#1#2#3}
+\captionsetup[lstlisting]{
+ format=listing,
+ singlelinecheck=false,
+ labelsep=endash,
+}
+
+\newcommand{\listing}[2][]{%
+ \lstinputlisting[caption={\texttt{\detokenize{#2}}},#1]{#2}%
+}
diff --git a/macros/latex/contrib/bmstu-iu8/styles/21-IU8-math.sty b/macros/latex/contrib/bmstu-iu8/styles/21-IU8-math.sty
new file mode 100644
index 0000000000..00b85e1c24
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/21-IU8-math.sty
@@ -0,0 +1,11 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{21-IU8-math}[2021/03/21 v1.0 Математика]
+
+\RequirePackage{amsthm}
+\theoremstyle{definition}
+\newtheorem{definition}{Определение}[section]
+\newtheorem{theorem}{Теорема}[section]
+\newtheorem{corollary}{Следствие}[theorem]
+\newtheorem{lemma}{Лемма}[section]
+\newtheorem{example}{Пример}[section]
diff --git a/macros/latex/contrib/bmstu-iu8/styles/22-IU8-algorithms.sty b/macros/latex/contrib/bmstu-iu8/styles/22-IU8-algorithms.sty
new file mode 100644
index 0000000000..e7ede15997
--- /dev/null
+++ b/macros/latex/contrib/bmstu-iu8/styles/22-IU8-algorithms.sty
@@ -0,0 +1,26 @@
+% Author: CatInCosmicSpace
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{22-IU8-algorithms}[2021/03/21 v1.0 Алгоритмы]
+
+\RequirePackage[linesnumbered,boxruled]{algorithm2e}
+\SetAlCapSty{}
+
+% Перевод плагина
+\SetKwInput{KwData}{Исходные параметры}
+\SetKwInput{KwResult}{Результат}
+\SetKwInput{KwIn}{Входные данные}
+\SetKwInput{KwOut}{Выходные данные}
+\SetKwIF{If}{ElseIf}{Else}{если}{тогда}{иначе если}{иначе}{конец условия}
+\SetKwFor{While}{до тех пор, пока}{выполнять}{конец цикла}
+\SetKw{KwTo}{от}
+\SetKw{KwRet}{возвратить}
+\SetKw{Return}{возвратить}
+\SetKwBlock{Begin}{начало блока}{конец блока}
+\SetKwSwitch{Switch}{Case}{Other}{Проверить значение}{и выполнить}{вариант}{в противном случае}{конец варианта}{конец проверки значений}
+\SetKwFor{For}{цикл}{выполнять}{конец цикла}
+\SetKwFor{ForEach}{для каждого}{выполнять}{конец цикла}
+\SetKwRepeat{Repeat}{повторять}{до тех пор, пока}
+\SetAlgorithmName{Алгоритм}{алгоритм}{Список алгоритмов}
+\SetAlgoCaptionSeparator{~---}
+% \SetAlgoCaptionLayout{centerline}
+\renewcommand{\@algocf@capt@plain}{above}
diff --git a/macros/latex/contrib/mindflow/mindflow.dtx b/macros/latex/contrib/mindflow/mindflow.dtx
index 629ceaaf41..987bfc401a 100644
--- a/macros/latex/contrib/mindflow/mindflow.dtx
+++ b/macros/latex/contrib/mindflow/mindflow.dtx
@@ -18,7 +18,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{mindflow}
%<*package>
- [2021/05/07 Mindflow environment]
+ [2021/05/23 mindflow environment]
%</package>
%
%<*driver>
@@ -27,7 +27,7 @@
\usepackage[a4paper,top=1.2in,bottom=1.2in,left=1.6in,right=1.2in]{geometry}
\usepackage{titlesec}
\titleformat{\section}{\large\scshape\centering}{\thesection.}{.5em}{}
-\titleformat{\subsection}{\large}{\thesubsection}{.5em}{}
+\titleformat{\subsection}{\large\itshape}{\thesubsection}{.5em}{}
\usepackage{titling}
\setlength{\droptitle}{-.5in}
\usepackage{enumitem}
@@ -38,6 +38,40 @@
\usepackage[linenumber,rightmarker]{mindflow}
\usepackage{blindtext}
\usepackage{parskip}
+\usepackage{listings}
+\definecolor{maintheme}{RGB}{50,100,150}
+\definecolor{forestgreen}{RGB}{21,122,81}
+\definecolor{lightergray}{gray}{0.99}
+\lstset{language=[LaTeX]TeX,
+ keywordstyle=\color{maintheme},
+ basicstyle=\ttfamily,
+ commentstyle=\color{forestgreen}\ttfamily,
+ stringstyle=\rmfamily,
+ showstringspaces=false,
+ breaklines=true,
+ frame=lines,
+ backgroundcolor=\color{lightergray},
+ flexiblecolumns=true,
+ escapeinside={(*}{*)},
+ % numbers=left,
+ % numberstyle=\scriptsize, stepnumber=1, numbersep=5pt,
+ % firstnumber=last,
+}
+\providecommand{\meta}[1]{$\langle${\normalfont\itshape#1}$\rangle$}
+\lstset{moretexcs=%
+ {linenumbers,nolinenumbers,mindflowLeft,mindflowRight,mindflowTextFont,mindflowNumFont,mindflowMarkerFont,mindflowLineHeight,setlength,colorlet,color,
+ RequirePackage,SetupKeyvalOptions,DeclareBoolOption,ProcessKeyvalOptions,PassOptionsToPackage,
+ if@mindflow@twocolumn,@mindflow@incolumntrue,if@mindflow@linenumber,@mindflow@leftlinenumbertrue,if@mindflow@off,if@mindflow@incolumn,if@mindflow@leftlinenumber,if@mindflow@rightlinenumber,if@mindflow@leftmarker,if@mindflow@rightmarker,
+ ifLNturnsON,LNturnsONtrue,LNturnsONfalse,ifLineNumbers,
+ mindflow,endmindflow,comment,endcomment,
+ mfSepLine,makeLineNumber,LineNumber,
+ ifdefined,linenomathpatch,cspreto,csappto,patchcmd,linenomathpatchAMS,linenomathAMS,linenomathWithnumbers,linenomath,endlinenomath,linenomathNonumbers,linenopenalty
+ }
+}
+\lstnewenvironment{code*}%
+{\setkeys{lst}{columns=fullflexible,keepspaces=true}}{}
+\lstnewenvironment{code}%
+{\setkeys{lst}{columns=fullflexible,keepspaces=true,numbers=left,numberstyle=\scriptsize, stepnumber=1, numbersep=5pt,lastline=137}}{}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
@@ -47,12 +81,12 @@
%</driver>
% \fi
%
-% \CheckSum{197}
+% \CheckSum{0}
%
% \GetFileInfo{mindflow.dtx}
%
%
-% \title{The {\normalfont\textsf{mindflow}} package}
+% \title{{\normalfont\textsf{mindflow}}, write your ideas in a clear way}
% \author{\scshape Jinwen Xu}
% \date{\filedate}
%
@@ -77,11 +111,17 @@
%
% \subsection{Initialization}
% Simply load the package with
-% \begin{verbatim}
-% \usepackage{mindflow}
-% \end{verbatim}
+% \iffalse
+%<*example>
+% \fi
+\begin{code*}
+ \usepackage{mindflow}
+\end{code*}
+% \iffalse
+%</example>
+% \fi
%
-% \vspace{-\baselineskip}
+% \vspace{-.5\baselineskip}
% There are a few options available, which are listed in the next subsection.
%
% \subsection{Options}
@@ -99,19 +139,24 @@
%
% \DescribeEnv{\{mindflow\}}
% Then you can use the \verb|mindflow| environment as
-% \begin{verbatim}
-% \begin{mindflow}
-% ...
-% \end{mindflow}
-% \end{verbatim}
-% \vspace{-\baselineskip}
+% \iffalse
+%<*example>
+% \fi
+\begin{code*}
+ \begin{mindflow}
+ (*\meta{text}*)
+ \end{mindflow}
+\end{code*}
+% \iffalse
+%</example>
+% \fi
%
% \subsection{About the line numbers}
% \linenumbers
%
% You can also add line numbers to the other part of your document in the usual
% way. For example, line numbers have been turned on for this paragraph with
-% \verb|\linenumbers|.
+% \lstinline|\linenumbers|.
%
% \begin{mindflow}
% Line numbers within the \textsf{mindflow} environments are independent from
@@ -127,8 +172,17 @@
% The feature of line numbering is provided by the package \textsf{lineno}. You
% can read its documentation to learn more about it. Notice that, by default,
% displayed equations are not numbered. You can add the following line before
-% \verb|\usepackage{mindflow}|:\\[.5\baselineskip]
-% \null\hspace{1.5em}{\small\verb|\PassOptionsToPackage{mathlines}{lineno}|}\\[.5\baselineskip]
+% \lstinline|\usepackage{mindflow}|:
+% \iffalse
+%<*example>
+% \fi
+\begin{code*}
+ \PassOptionsToPackage{mathlines}{lineno}
+\end{code*}
+% \iffalse
+%</example>
+% \fi
+% \vspace{-.5\baselineskip}
% to enable the line numbers for displayed equations.
%
% \begin{mindflow}\vspace{-\baselineskip}
@@ -143,26 +197,33 @@
%
% \DescribeMacro{\mindflowTextFont}
% \DescribeMacro{\mindflowNumFont}
+% \DescribeMacro{\mindflowMarkerFont}
% The font for text, line numbers and markers within the \verb|mindflow|
-% environments can be specified by redefining \verb|\mindflowTextFont|,
-% \verb|\mindflowNumFont| and \verb|\mindflowMarkerFont|. By default,
+% environments can be specified by redefining \lstinline|\mindflowTextFont|,
+% \lstinline|\mindflowNumFont| and \lstinline|\mindflowMarkerFont|. By default,
% they are defined as:
-% \begin{verbatim}
-% \newcommand{\mindflowTextFont}{\normalfont\footnotesize}
-% \newcommand{\mindflowNumFont}{\normalfont\scriptsize\ttfamily}
-% \newcommand{\mindflowMarkerFont}{\normalfont\scriptsize\ttfamily}
-% \end{verbatim}
+% \iffalse
+%<*example>
+% \fi
+\begin{code*}
+\newcommand{\mindflowTextFont}{\normalfont\footnotesize}
+\newcommand{\mindflowNumFont}{\normalfont\scriptsize\ttfamily}
+\newcommand{\mindflowMarkerFont}{\normalfont\scriptsize\ttfamily}
+\end{code*}
+% \iffalse
+%</example>
+% \fi
% \vspace{-.5\baselineskip}
%
% \DescribeMacro{\mindflowLeft}
% \DescribeMacro{\mindflowRight}
-% The left and right markers can be changed by redefining
-% \verb|\mindflowLeft| and \verb|\mindflowRight|. Both have the default
-% value as ``\verb|*|''.
+% The left and right markers is defined by
+% \lstinline|\mindflowLeft| and \lstinline|\mindflowRight|. Both have the default
+% value ``\verb|*|''.
%
% \DescribeMacro{\mindflowLineHeight}
-% The height of the separation lines is a length macro named \verb|\mindflowLineHeight|,
-% with default value \verb|0.4pt|. You can change this with \verb|\setlength|.
+% The height of the separation lines is a length macro named \lstinline|\mindflowLineHeight|,
+% with default value \verb|0.4pt|. You can change this with \lstinline|\setlength|.
%
% \DescribeMacro{mindflowLine}
% \DescribeMacro{mindflowText}
@@ -178,18 +239,24 @@
% \section{An example}
% With option \verb|leftlinenumber, rightlinenumber, leftmarker, rightmarker| and the
% following settings:
-% \begin{verbatim}
-% \colorlet{mindflowLine}{green!50!black}
-% \colorlet{mindflowText}{blue!50!cyan}
-% \colorlet{mindflowNum}{red!50!orange}
-% \colorlet{mindflowMarker}{orange}
-% \renewcommand{\mindflowTextFont}{\normalfont\footnotesize\sffamily\itshape}
-% \renewcommand{\mindflowNumFont}{\normalfont\small\footnotesize\ttfamily}
-% \renewcommand{\mindflowMarkerFont}{\normalfont\footnotesize\sffamily}
-% \renewcommand{\mindflowLeft}{\hspace{1em}\(\succ\)}
-% \renewcommand{\mindflowRight}{\(\prec\)\hspace{1em}}
-% \setlength{\mindflowLineHeight}{1pt}
-% \end{verbatim}
+% \iffalse
+%<*example>
+% \fi
+\begin{code*}
+\colorlet{mindflowLine}{green!50!black}
+\colorlet{mindflowText}{blue!50!cyan}
+\colorlet{mindflowNum}{red!50!orange}
+\colorlet{mindflowMarker}{orange}
+\renewcommand{\mindflowTextFont}{\normalfont\footnotesize\sffamily\itshape}
+\renewcommand{\mindflowNumFont}{\normalfont\small\footnotesize\ttfamily}
+\renewcommand{\mindflowMarkerFont}{\normalfont\footnotesize\sffamily}
+\renewcommand{\mindflowLeft}{\hspace{1em}\(\succ\)}
+\renewcommand{\mindflowRight}{\(\prec\)\hspace{1em}}
+\setlength{\mindflowLineHeight}{1pt}
+\end{code*}
+% \iffalse
+%</example>
+% \fi
% \vspace{-.5\baselineskip}
% One gets:
% \makeatletter
@@ -215,20 +282,20 @@
% \section{Implementation}
% Below is the complete source code of this package.
%
-% \begin{macrocode}
+% \begin{code}
\RequirePackage{kvoptions}
\SetupKeyvalOptions{%
family = @mindflow,
prefix = @mindflow@
}
-\DeclareBoolOption[false]{off} % Turn off mindflow
-\DeclareBoolOption[false]{leftmarker} % Left marker
-\DeclareBoolOption[false]{rightmarker} % Right marker
-\DeclareBoolOption[false]{linenumber} % Left line numbers
-\DeclareBoolOption[false]{leftlinenumber} % Left line numbers
-\DeclareBoolOption[false]{rightlinenumber} % Right line numbers
-\DeclareBoolOption[false]{twocolumn} % Two column
-\DeclareBoolOption[false]{incolumn} % Separation line fits in the column
+\DeclareBoolOption[false]{off} % Turn off mindflow
+\DeclareBoolOption[false]{leftmarker} % Left marker
+\DeclareBoolOption[false]{rightmarker} % Right marker
+\DeclareBoolOption[false]{linenumber} % Left line numbers
+\DeclareBoolOption[false]{leftlinenumber} % Left line numbers
+\DeclareBoolOption[false]{rightlinenumber} % Right line numbers
+\DeclareBoolOption[false]{twocolumn} % Two column
+\DeclareBoolOption[false]{incolumn} % Separation line fits in column
\ProcessKeyvalOptions*\relax
@@ -353,7 +420,7 @@
\linenomathpatchAMS{alignat}
\linenomathpatchAMS{flalign}
\fi
-% \end{macrocode}
+% \end{code}
%
% \Finale
\endinput
diff --git a/macros/latex/contrib/mindflow/mindflow.pdf b/macros/latex/contrib/mindflow/mindflow.pdf
index e861974e19..be52cded1b 100644
--- a/macros/latex/contrib/mindflow/mindflow.pdf
+++ b/macros/latex/contrib/mindflow/mindflow.pdf
Binary files differ
diff --git a/support/ltximg/README.md b/support/ltximg/README.md
index 955b3b7598..8ac445354b 100644
--- a/support/ltximg/README.md
+++ b/support/ltximg/README.md
@@ -1,6 +1,6 @@
## LTXimg &ndash; LaTeX environments to image and standalone files
-Release v2.0 \[2021-01-24\]
+Release v2.1 \[2021-05-21\]
## Description
@@ -42,7 +42,7 @@ and saved in the `./images` directory using `pdflatex` and `preview` package to
```
[default]
-h, --help Display command line help and exit [off]
--v, --version Display current version (2.0) and exit [off]
+-v, --version Display current version (2.1) and exit [off]
-V, --verbose Verbose printing information [off]
-l, --log Write .log file with debug information [off]
-t, --tif Create .tif files using ghostscript [gs]
@@ -127,7 +127,7 @@ Pablo González L, `<pablgonz@yahoo.com>`.
## Copyright and Licence
-Copyright 2013 - 2020 Pablo González L `<pablgonz@yahoo.com>`.
+Copyright 2013 - 2021 Pablo González L `<pablgonz@yahoo.com>`.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation; either version 3 of the License,
diff --git a/support/ltximg/ltximg-doc.pdf b/support/ltximg/ltximg-doc.pdf
index 0a6f44fe49..377d2ae9bb 100644
--- a/support/ltximg/ltximg-doc.pdf
+++ b/support/ltximg/ltximg-doc.pdf
Binary files differ
diff --git a/support/ltximg/ltximg-doc.tex b/support/ltximg/ltximg-doc.tex
index 3d41f5c6cb..72908c0233 100644
--- a/support/ltximg/ltximg-doc.tex
+++ b/support/ltximg/ltximg-doc.tex
@@ -85,8 +85,8 @@
% Identification
\def\myscript{ltximg}
-\def\fileversion{2.0}
-\def\filedate{2021-01-24}
+\def\fileversion{2.1}
+\def\filedate{2021-05-21}
% Logo with fetamont and libertuns font
\ExplSyntaxOn
@@ -400,7 +400,17 @@
\SortIndex{#2}{\texttt{\small\textbackslash#2}}
}
-% file extention
+% \module{m}
+\NewDocumentCommand{\module}{m}
+ {
+ \SortIndex{Perl ~ module}{Perl ~ module >\small\texttt{#1}}
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ \regex_replace_all:nnN { (\:\:) } { \c{textcolor}\cB\{MediumOrchid\cE\}\cB\{\1\cE\} } \l_tmpa_tl
+ \textcolor{blue!75}{\ttfamily{\tl_use:N \l_tmpa_tl}}
+ %\SortIndex{Perl ~ module}{Perl ~ module >\small\texttt{\tl_use:N \l_tmpa_tl}}
+ }
+
+% File extention
\NewDocumentCommand{\fext}{m}
{
\mbox{\textcolor{OrangeRed}{\texttt{.#1}}}
@@ -414,8 +424,7 @@
\SortIndex{file}{File >\small\texttt{#1.#2}}
}
-
-% image format/extention
+% Image format/extention
\NewDocumentCommand{\iext}{m}
{
\textcolor{optcolor}{\texttt{#1}}
@@ -572,8 +581,8 @@
% Important words 2 (macros)
keywordstyle=[2]{\color{blue!75}},%
keywords=[2]{graphicspath,RequirePackage,renewcommand,includegraphics,coordinate,draw,approx,%
- PreviewBbAdjust,setlength,parindent,usetikzlibrary,tikzexternalize,psset,tikzset,PrependGraphicsExtensions,%
- DefineShortVerb,lstMakeShortInline,MakeSpecialShortVerb,UndefineShortVerb,verb,myverb,macro,put,line},%
+ PreviewBbAdjust,setlength,parindent,usetikzlibrary,tikzexternalize,psset,tikzset,PrependGraphicsExtensions,cmd,%
+ DefineShortVerb,lstMakeShortInline,MakeSpecialShortVerb,UndefineShortVerb,verb,myverb,macro,put,line,Win32::Console::ANSI},%
% Important words 3, options in input file
keywordstyle=[3]{\color{optcolor!85}},%
keywords=[3]{extrenv,deltenv,skipenv,options,arara,extensions,luatex,env,norun,%
@@ -756,16 +765,19 @@ to \emph{any type} of environment covering three central points:
\item Generate a standalone files with only the extracted environments.
\item Generate a file replacing the environments by \ics{includegraphics}.
+
\end{enumerate}
-From the side of \hologo{TeX} there are some packages that cover several of these
-points such as the \pkgname{preview}\cite{preview}, \pkgname{xcomment}\cite{xcomment}, \pkgname{extract}\cite{extract}
-and \pkgname{cachepic}\cite{cachepic} packages among others, but none covered all points.
+From the side of \hologo{TeX} there are some packages that cover
+several of these points such as the \pkgname{preview}\cite{preview},
+\pkgname{xcomment}\cite{xcomment}, \pkgname{extract}\cite{extract} and
+\pkgname{cachepic}\cite{cachepic} packages among others, but none
+covered all points.
-In the network there are some solutions in \texttt{bash} that were able to
-extract and convert environments, but in general they presented problems
-when the document contained \emph{\enquote{verbatim style}} code or were only
-available for \OSsystem{Linux}.
+In the network there are some solutions in \texttt{bash} that were able
+to extract and convert environments, but in general they presented
+problems when the document contained \emph{\enquote{verbatim style}}
+code or were only available for \OSsystem{Linux}.
\thispagestyle{plain}
@@ -773,9 +785,9 @@ available for \OSsystem{Linux}.
\pagestyle{myheader}
-Analysed the situation the best thing was to create a new \emph{\enquote{script}} that
-was able to cover the three points and was multi platform, the union of all
-these ideas is born \ltximg.
+Analysed the situation the best thing was to create a new
+\emph{\enquote{script}} that was able to cover the three points and was
+multi platform, the union of all these ideas is born \ltximg.
This script would not be possible without the great work of Herbert Voß
author of \scriptname{pst2pdf}\footnote{\url{https://ctan.org/pkg/pst2pdf}}
@@ -791,49 +803,91 @@ a version equal to or greater than \liningnums{5.28} of \prgname{perl}, a
version equal to or greater than \liningnums{9.52} of \prgname{ghostscript}, a
version equal to or greater than \liningnums{1.40} of \scriptname{pdfcrop}
and have a version equal to or greater than \liningnums{0.52} of %
-\prgname{poppler-utils}.
-
-The script uses only packages from the core of the \prgname{perl}, the
-distribution encapsulated in \hologo{TeX} Live 2020 for \OSsystem{Windows}
-does not have the \verb|Win32::Console::ANSI| package, this does not
-affect the operation of the script, but it does affect the presentation
-of the messages when invoked from \verb|cmd|, it is recommended to use
-a more modern (and comfortable) application such as \prgname{Windows Terminal}.
-\hologo{MiKTeX} users must install the appropriate software for full
-operation.
-
-The script auto detects the \prgname{ghostscript}, but not \prgname{poppler-utils}.
+\prgname{poppler-utils}. \hologo{MiKTeX} and \prgname{cygwin} users
+must install the appropriate software for full operation.
+
+\ltximg{} auto detects the \prgname{ghostscript}, but not \prgname{poppler-utils}.
You should keep this in mind if you are using the script directly and not
the version provided in your \hologo{TeX} distribution.
-The script has been tested on \OSsystem{Windows} v10, \prgname{cygwin} v3.1.6, \prgname{Git for Windows} v2.30 and %
-\OSsystem{Linux} (fedora 33) using \prgname{ghostscript} v9.53.3, \prgname{poppler-utils} v0.90, \prgname{perl} v5.32
-and the standard classes offers by \hologo{LaTeX}: \myclass{book}, \myclass{report}, \myclass{article} and
-\myclass{letter}. The \pkgname{preview}\cite{preview} and \pkgname{pst-pdf}\cite{pst-pdf} packages are
-required to process the \meta{input file} and if an \meta{output file} is generated, the \pkgname{graphicx}\cite{graphicx}
-and \pkgname{grfext}\cite{grfext} packages will be needed.
+The script has been tested on \OSsystem{Windows} 10, \prgname{cygwin}
+3.1.6, \prgname{Git for Windows} 2.30 and \OSsystem{Linux} (fedora 34)
+using \prgname{ghostscript} 9.53.3, \prgname{poppler-utils} 0.90,
+\prgname{perl} 5.32 and the standard classes offers by \hologo{LaTeX}:
+\myclass{book}, \myclass{report}, \myclass{article} and
+\myclass{letter}. The \pkgname{preview}\cite{preview} and
+\pkgname{pst-pdf}\cite{pst-pdf} packages are required to process the
+\meta{input file} and if an \meta{output file} is generated, the
+\pkgname{graphicx}\cite{graphicx} and \pkgname{grfext}\cite{grfext}
+packages will be needed.
+
+
+\subsection{Modules required}
+
+\ltximg{} uses only packages from the core of the \prgname{perl}, the
+distribution encapsulated in \hologo{TeX} Live 2020 for
+\OSsystem{Windows} does not have the module
+\module{Win32::Console::ANSI}, this does not affect the operation of
+the script, but it does affect the presentation of the messages when
+invoked from \emph{standart} \prgname{cmd}, it is recommended to use a
+more modern (and comfortable) application such as \prgname{Windows
+Terminal}.
+
+\setlength{\multicolsep}{2ex}
+\begin{multicols}{2}
+\begin{itemize}[font=\sffamily\small,first=\small,partopsep=5pt,parsep=5pt,nosep,leftmargin=*]
+ \item \module{Getopt::Long}
+ \item \module{File::Spec::Functions}
+ \item \module{File::Basename}
+ \item \module{Archive::Tar}
+ \item \module{Data::Dumper}
+ \item \module{FileHandle}
+ \item \module{IO::Compress::Zip}
+ \item \module{File::Path}
+ \item \module{File::Temp}
+ \item \module{POSIX}
+ \item \module{File::Copy}
+ \item \module{File::Find}
+ \item \module{Env}
+ \item \module{autodie}
+ \item \module{Config}
+ \item \module{Cwd}
+ \item \module{Term::ANSIColor}
+ \item \module{Module::Load::Conditional}
+ \item Only on \OSsystem{Windows}:
+ \begin{itemize}[font=\sffamily\small,first=\small,nosep]
+ \item \module{Win32}
+ \item \module{Win32::Console::ANSI}
+ \item \module{Win32::TieRegistry}
+ \end{itemize}
+\end{itemize}
+\end{multicols}
\section{How it works}
\label{sec:howtowork}
-It is important to have a general idea of how the \emph{\enquote{extraction and conversion}}
-process works and the requirements that must be fulfilled so
-that everything works correctly, for this we must be clear about some
-concepts related to how to work with the \meta[cf=optcolor]{input file}, the \meta{verbatim content}
+It is important to have a general idea of how the
+\emph{\enquote{extraction and conversion}} process works and the
+requirements that must be fulfilled so that everything works correctly,
+for this we must be clear about some concepts related to how to work
+with the \meta[cf=optcolor]{input file}, the \meta{verbatim content}
and the \meta{steps process}.
\subsection{The input file}
\label{sec:inputfile}
-The \meta[cf=optcolor]{input file} must comply with \emph{certain characteristics} in order to
-be processed, the content at the beginning and at the end of the \meta{input
-file} is treated in a special way, before \lstinline|\documentclass| and after
-\lstinline|\end{document}| can go any type of content, internally the script will
-\emph{\enquote{split}} the \meta[cf=optcolor]{input file} at this points.
-
-If the \meta[cf=optcolor]{input file} contains files using \ics{input}\marg[type=tt]{file} or
-\ics{include}\marg[type=tt]{file} these will not be processed, from the side of
-the \emph{script} they only represent lines within the file, if you want
+The \meta[cf=optcolor]{input file} must comply with \emph{certain
+characteristics} in order to be processed, the content at the beginning
+and at the end of the \meta{input file} is treated in a special way,
+before \lstinline|\documentclass| and after \lstinline|\end{document}|
+can go any type of content, internally the script will
+\emph{\enquote{split}} the \meta[cf=optcolor]{input file} at this
+points.
+
+If the \meta[cf=optcolor]{input file} contains files using
+\ics{input}\marg[type=tt]{file} or \ics{include}\marg[type=tt]{file}
+these will not be processed, from the side of the \emph{script} they
+only represent lines within the file, if you want
them to be processed it is better to use the \scriptname{latexpand}\footnote{\url{https://www.ctan.org/pkg/latexpand}}
first and then process the file.
@@ -865,22 +919,22 @@ parts and then processing them:
% Part Four: Everything after \end{document}
\end{examplecode}
-If for some reason you have an environment \LWenv{filecontens} before \lstinline|\documentclass| or
-in the preamble of the \meta{input file} that contains a \emph{sub-document} or \emph{environment}
-you want to extract, the script will ignore them. Similarly, the content after \lstinline|\end{document}|
-is ignored in the extraction process.
-
-\newpage
+If for some reason you have an environment \LWenv{filecontents} before
+\lstinline|\documentclass| or in the preamble of the \meta{input file}
+that contains a \emph{sub-document} or \emph{environment} you want to
+extract, the script will ignore them. Similarly, the content after
+\lstinline|\end{document}| is ignored in the extraction process.
\subsection{Verbatim contents}
\label{sec:verbatim}
-One of the greatest capabilities of this script is to \emph{\enquote{skip}}
-the complications that \meta{verbatim content} produces with the extraction
-of environments using tools outside the \enquote{\hologo{TeX} world}\footnote{Only \hologo{TeX} can
-understand \hologo{TeX}, all other languages and programs are just lines in a file.}.
-In order to \emph{\enquote{skip}} the complications, the \meta{verbatim content} is classified into
-three types:
+One of the greatest capabilities of this script is to
+\emph{\enquote{skip}} the complications that \meta{verbatim content}
+produces with the extraction of environments using tools outside the
+\enquote{\hologo{TeX} world}\footnote{Only \hologo{TeX} can understand
+\hologo{TeX}, all other languages and programs are just lines in a
+file.}. In order to \emph{\enquote{skip}} the complications, the
+\meta{verbatim content} is classified into three types:
\begin{itemize}[nosep]
\item Verbatim in line.
@@ -936,9 +990,9 @@ it correctly. The solution is quite simple, just add in \meta[cf=optcolor]{input
\DefineShortVerb{\|}
\end{examplecode}
-depending on the package you are using. If your \emph{\enquote{verbatim macro}} is not
-supported by default or can not detect, use the options described in \ref%
-{sec:optline} and \ref{sec:optfile}.
+depending on the package you are using. If your \emph{\enquote{verbatim macro}}
+is not supported by default or can not detect, use the options
+described in \ref{sec:optline} and \ref{sec:optfile}.
\subsection*{Verbatim standard}
\label{sec:verbatim:std}
@@ -1110,8 +1164,6 @@ and create a temporary directory \sysdir{/tmp/hG45uVklv9}.
The entire \sysfile{test.tex} file is loaded into memory and \emph{\enquote{split}} to start the extraction process.
-\newpage
-
\subsection*{Comment and ignore}
In the second step, once the file \sysfile{test.tex} is loaded and divided in memory,
proceeds (in general terms) as follows:
@@ -1283,7 +1335,7 @@ package with the [\pkgopt{swpl}] or [\pkgopt{tcb}] option and run the script
using \cmdopt{latex}{} or \cmdopt{xetex}. This environment is reserved for the internal process of extraction and conversion, it
cannot be passed as an argument to the option \cmdopt{skipenv}{}.
-\vspace{0.25\baselineskip}
+\newpage
\DescribeTE{pspicture}
Environment provide by \pkgname{PStricks}\cite{pstricks} package. The plain \hologo{TeX}
@@ -1297,7 +1349,7 @@ Environment provide by \pkgname{pst-plot}\cite{pst-plot} package. The plain \hol
its converted to \hologo{LaTeX} syntax \lstinline|\begin{psgraph} ... \end{psgraph}| if
not within the \env{PSTexample} or \env{postscript} environments.
-\newpage
+\vspace{0.75\baselineskip}
\DescribeTE{tikzpicture}
Environment provide by \pkgname{TikZ}\cite{tikz} package. The plain \hologo{TeX} syntax \lstinline|\tikzpicture ... \tikzpicture|
@@ -1344,8 +1396,6 @@ unless the option \cmdopt[n]{noprew}{} is used. This environment is
reserved for the internal process of extraction and conversion, it
cannot be passed as an argument to the option \cmdopt{extrenv}.
-\vspace{\baselineskip}
-
\DescribeTE*{noltximg}
All content betwen \lstinline|%<*noltximg> ... %</noltximg>| are ignored and no extract.
The tags can \emph{not} be nested and should be at the beginning of the line and in separate lines.
@@ -1395,6 +1445,8 @@ The image format generated using \prgname{pdftoeps}. The line executed by the sy
[user@machine ~:]§ pdftops -q -eps
\end{examplecmd}
+\newpage
+
\DescribeIF{png}
The image format generated using \prgname{ghostscript}. The line executed by the system is:
@@ -1467,7 +1519,6 @@ Options that accept a \meta{value} require either a blank space \verb*| | or \te
between the option and the \meta{value}. Multiple short options can be bundling and if the last option takes a
\meta{comma separated list} you need \textcolor{optcolor}{\bfseries\texttt{-\/-}} at the end.
-\vspace{\baselineskip}
\DescribeCmd[h]{help}{boolean}{off}
Display a command line help and exit.
@@ -1587,7 +1638,7 @@ and \meta[cf=optcolor]{output file}, is mutually exclusive with \emph{\enquote{a
Using \prgname*{xelatex} compiler \meta[cf=optcolor]{input file} and \meta[cf=optcolor]{output file}.
In the execution \prgname*{xelatex} is called with the \prgopt*{no-pdf} option
generating a \fext{xvd} file and then it is processed using \prgname*{xdvipdfmx},
-this is only to execute \emph{faster} the conversion of environments to images
+this is only to execute \emph{faster} conversion of environments to images
and it is only done on the \meta[cf=optcolor]{input file}.
\DescribeCmd{latex}{boolean}{off}
@@ -1653,6 +1704,8 @@ at the end. The environments \env{PSTexample} and \env{preview} are not supporte
Add \meta{verbatim standard} environment support, if it's the last option
passed need \textcolor{optcolor}{\textbf{\texttt{-\/-}}} at the end.\par
+\newpage
+
\DescribeCmd{writenv}{comma separated list}{empty}
Add \meta{verbatim write} environment support, if it's the last option
passed need \textcolor{optcolor}{\textbf{\texttt{-\/-}}} at the end.\par
@@ -1670,6 +1723,7 @@ An example of usage from command line:
\begin{examplecmd}
[user@machine ~:]§ ltximg --latex -s -o test-out test-in.ltx
\end{examplecmd}
+
Create a \sysdir{./images} directory (if it does not exist) with all extracted environments converted to image
formats (\iext{pdf}, \iext{svg}) in individual files, an output file \meta[ac=LightSlateGrey,cf=OrangeRed]{test-out.ltx}
with all extracted environments converted to \ics{includegraphics} and a single file
@@ -1717,7 +1771,7 @@ This line is to indicate to the script which environments are deleted.
\DescribeOptFile{options}{option one = value, option two = value, option three = value, \ldots}
This line is to indicate to the script which options(other than those listed above) need to process.
-The options passed from the \meta[cf=optcolor]{input file} are validated by the script after they are read. If you are going to
+All options passed from the \meta[cf=optcolor]{input file} are validated by the \ltximg{} after they are read. If you are going to
create an \meta[cf=optcolor]{output file} and you do not want these lines to remain, it is better to
place them inside the \lstinline|%<*remove> ... %</remove>|. Like this:
@@ -1752,7 +1806,8 @@ and \meta[ac=LightSlateGrey,cf=OrangeRed]{file-out.tex}.
\section{The way of \texttt{arara}}
\label{sec:arara}
-By design, the script only runs \emph{\enquote{one or more compilation}} on top
+
+By design, \ltximg{} only runs \emph{\enquote{one or more compilation}} on top
of the \meta[cf=optcolor]{input file}, but, sometimes you need to process in a specific mode the \meta[cf=optcolor]{input file}
or needs to be processed with something other than \hologo{LaTeX}, \hologo{XeLaTeX}, \hologo{pdfLaTeX} or \hologo{LuaLaTeX} engine.
This is where \arara\cite{arara} comes in, this \emph{\enquote{great little tool}},
@@ -1880,7 +1935,6 @@ to generate an image in \iext{svg}, \iext{png} and \iext{pdf} format from enviro
\begin{document}
\section{How to get Tikzmark to work}
By taking logarithms of both sides:
-
\[
t = \frac{30\cdot\ln(3/22)}{\ln(15/22)}
\tikzmark{calculator}\approx\tikzmark{otherside}
@@ -1890,7 +1944,6 @@ By taking logarithms of both sides:
\coordinate (target) at ($(pic cs:calculator)!1/2!(pic cs:otherside) - (0,.5ex)$);
\draw[arrows=->] (target) ++(0,-2ex) node [anchor=north] {use calculator} -- (target);
\end{tikzpicture}
-
\section{Draw an aircraft with Tikz}
The best airplane ever drawn by David Carlise. No TikZ used, just the
classic and perhaps forgotten \verb|\begin{picture} ... \end{picture}|.
@@ -1957,6 +2010,11 @@ versions, both development (devp) and public (ctan).
\begin{description}[font=\small\sffamily,style=nextline,nosep,noitemsep]
\item [v\fileversion\ (ctan), \filedate] \leavevmode\vspace{-\baselineskip}
\begin{itemize}
+ \item Maintenance update.
+ \item Fix internal \texttt{hash} for regex.
+ \end{itemize}
+\item [v2.0 (ctan), 2021-01-24] \leavevmode\vspace{-\baselineskip}
+ \begin{itemize}
\item Add \texttt{-dALLOWPSTRANSPARENCY} to \texttt{ps2pdf}.
\item The \texttt{--xetex} option now uses \texttt{xelatex} and then \texttt{xdvipdfmx}.
\item Fix module detection under \hologo{TeX} Live on Windows.
diff --git a/support/ltximg/ltximg.1 b/support/ltximg/ltximg.1
index 81545b5470..918b2626dd 100644
--- a/support/ltximg/ltximg.1
+++ b/support/ltximg/ltximg.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
+.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -71,7 +71,7 @@
.\" ========================================================================
.\"
.IX Title "ltximg 1"
-.TH ltximg 1 "2021-01-24" "2.0" "General Commands Manual"
+.TH ltximg 1 "2021-05-21" "2.1" "General Commands Manual"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/support/ltximg/ltximg.man1.pdf b/support/ltximg/ltximg.man1.pdf
index 0cb98fe28c..57f87af07b 100644
--- a/support/ltximg/ltximg.man1.pdf
+++ b/support/ltximg/ltximg.man1.pdf
Binary files differ
diff --git a/support/ltximg/ltximg.pl b/support/ltximg/ltximg.pl
index 791c931685..2582d2d61d 100644
--- a/support/ltximg/ltximg.pl
+++ b/support/ltximg/ltximg.pl
@@ -31,7 +31,7 @@ use Config;
use Cwd;
use if $^O eq 'MSWin32', 'Win32';
use if $^O eq 'MSWin32', 'Module::Load::Conditional' => qw(can_load check_install requires);
-# Need on Windows cmd for colors, TeX Live not provide 'Win32::Console::ANSI'
+# Need for colors in Windows cmd, TeX Live not provide 'Win32::Console::ANSI'
if($^O eq 'MSWin32' && check_install( module => 'Win32::Console::ANSI')) {
require Win32::Console::ANSI;
}
@@ -44,8 +44,8 @@ my $workdir = cwd;
### Script identification
my $scriptname = 'ltximg';
my $program = 'LTXimg';
-my $nv = 'v2.0';
-my $date = '2021-01-24';
+my $nv = 'v2.1';
+my $date = '2021-05-21';
my $copyright = <<"END_COPYRIGHT" ;
[$date] - LaTeX environments to image and standalone files
END_COPYRIGHT
@@ -601,7 +601,7 @@ sub SearchRegistry {
return $found;
} # end GS search registry
-### This part is only necessary if you're using Git on windows and don't
+### This part is only necessary if you're using Git-bash on windows and don't
### have gs configured in PATH. Git for windows don't have a Win32::TieRegistry
### module for perl (is not supported in the current versions of msys).
sub Searchbyregquery {
@@ -2544,17 +2544,13 @@ if (@pst_exa and $outfile) {
$PALABRAS = qr/\b (?: pst-\w+ | pstricks (?: -add | -pdf )? | psfrag |psgo |vaucanson-g| auto-pst-pdf(?: -lua )? )/x;
$FAMILIA = qr/\{ \s* $PALABRAS (?: \s* [,] \s* $PALABRAS )* \s* \}(\%*)?/x;
-### Clean PST content in preamble
+### Clean PSTricks content in preamble
if ($clean{pst} and $outfile) {
Log("Remove pstricks packages in preamble for $opts_cmd{string}{output}$outext");
$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
^ $USEPACK (?: $CORCHETES )? $FAMILIA \s*//msxg;
$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
(?: ^ $USEPACK \{ | \G) [^}]*? \K (,?) \s* $PALABRAS (\s*) (,?) /$1 and $3 ? ',' : $1 ? $2 : ''/gemsx;
- if (@pst_exa) {
- Log("Uncomment pst-exa package in preamble for $opts_cmd{string}{output}$outext");
- $preamble =~ s/(?:\%)(\\usepackage\[\s*)(swpl|tcb)(,pdf\s*\]\{pst-exa\})/$1$2$3/msxg;
- }
Log("Remove \\psset\{...\} in preamble for $opts_cmd{string}{output}$outext");
$preamble =~ s/\%<\*$dtxverb> .+?\%<\/$dtxverb>(*SKIP)(*F)|
\\psset\{(?:\{.*?\}|[^\{])*\}(?:[\t ]*(?:\r?\n|\r))+//gmsx;
@@ -2566,6 +2562,12 @@ if ($clean{pst} and $outfile) {
^\\usepackage\{\}(?:[\t ]*(?:\r?\n|\r))+/\n/gmsx;
}
+### Uncomment pst-exa package
+if (@pst_exa and $outfile) {
+ Log("Uncomment pst-exa package in preamble for $opts_cmd{string}{output}$outext");
+ $preamble =~ s/(?:\%)(\\usepackage\[\s*)(swpl|tcb)(,pdf\s*\]\{pst-exa\})/$1$2$3/msxg;
+}
+
### To be sure that the package graphicx and \graphicspath is in the main
### document and not in a verbatim write environment we make the changes
my %tmpreplace = (
@@ -2807,9 +2809,10 @@ if ($outfile) {
}
# Remove internal mark for verbatim and verbatim write environments
$out_file =~ s/\%<\*$dtxverb>\s*(.+?)\s*\%<\/$dtxverb>/$1/gmsx;
- %replace = (%changes_out);
+ %replace = (%changes_out,%tmpoutreplace);
$find = join q{|}, map {quotemeta} sort { length $a <=> length $b } keys %replace;
$out_file =~ s/($find)/$replace{$1}/g;
+ # Write <output file>
if (-e "$opts_cmd{string}{output}$outext") {
Log("Rewriting the file $opts_cmd{string}{output}$outext in $workdir");
Infocolor('Warning', "The file [$opts_cmd{string}{output}$outext] already exists and will be rewritten");
@@ -2818,7 +2821,6 @@ if ($outfile) {
Infoline("Creating the file $opts_cmd{string}{output}$outext");
Log("Write the file $opts_cmd{string}{output}$outext in $workdir");
}
- # Write <output file>
open my $OUTfile, '>', "$opts_cmd{string}{output}$outext";
print {$OUTfile} $out_file;
close $OUTfile;
@@ -3281,4 +3283,3 @@ General Public License for more details.
gs(1), dvips(1), ps2pdf(1), pdfcrop(1), pdftops(1), pdftocairo(1), pdftoppm(1)
=cut
-
diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md
index 70863a7c18..df4134084d 100644
--- a/support/texlab/CHANGELOG.md
+++ b/support/texlab/CHANGELOG.md
@@ -5,6 +5,52 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [3.0.1] - 22.05.2021
+
+### Fixed
+
+- Sometimes the log parser does not pick up errors from the log file ([#426](https://github.com/latex-lsp/texlab/issues/426))
+- Fix a bug involving characters that are not part of the ASCII charset ([#428](https://github.com/latex-lsp/texlab/issues/428))
+
+## [3.0.0] - 16.05.2021
+
+### Added
+
+- Basic error analysis for LaTeX files ([#323](https://github.com/latex-lsp/texlab/issues/323))
+- Parse LaTeX3 commands correctly ([#410](https://github.com/latex-lsp/texlab/issues/410))
+- Allow configuring ChkTeX using a `chktexrc` file ([#309](https://github.com/latex-lsp/texlab/issues/309))
+- Implement goto definition for includes ([#386](https://github.com/latex-lsp/texlab/issues/386))
+- Provide completion for `\citeA{...}` ([#409](https://github.com/latex-lsp/texlab/issues/409))
+- Allow passing additional arguments to `latexindent` ([#365](https://github.com/latex-lsp/texlab/issues/365))
+- Document symbols and label completion now correctly handle `subequations`.
+
+### Changed
+
+- _BREAKING_: The configuration format has changed.
+ Every setting is now under the `texlab` scope instead of the two scopes `latex` and `bibtex`. For a list of possible options, please see [here](docs/options.md).
+ The `latex.build.onSave` setting has been removed in favor of `-pvc` of `latexmk`. In the VSCode extension, the `latex.build.onSave` setting is still available along with the `latex.build.forwardSearchAfter` setting. The reasoning is that that `latex.build.forwardSearchAfter` cannot reliably implemented in the server because it requires the current cursor position, which the LSP spec does not offer. In previous versions, TexLab had to guess the cursor position. We encourage editor extensions, to still support these settings under the `texlab` scope.
+- _BREAKING_: Previewing equations has been removed for now until
+ a better solution is found. The existing approach is way too slow and does not work reliably.
+- Distribution detection no longer produces an error message in the client.
+ Instead, a log message is generated. A TeX distribution is only required to compile documents.
+- Improve compile times a bit.
+
+### Fixed
+
+- Do not send snippets if the client does not support them ([#413](https://github.com/latex-lsp/texlab/issues/413))
+- Fix protocol violation when exiting the server ([#310](https://github.com/latex-lsp/texlab/issues/310))
+- Fix reporting compile-time diagnostics using file watching ([#339](https://github.com/latex-lsp/texlab/issues/339))
+- Fix compilation warnings ([#359](https://github.com/latex-lsp/texlab/issues/359))
+- Fix crash when exiting with NeoVim LSP client ([#405](https://github.com/latex-lsp/texlab/issues/405))
+- Hopefully fixes the ChkTeX spamming issue ([#186](https://github.com/latex-lsp/texlab/issues/186))
+- Reduce CPU-load when idle ([#400](https://github.com/latex-lsp/texlab/issues/400))
+
+## [2.2.2] - 10.01.2021
+
+### Fixed
+
+- Fix compilation on `arm64-apple-darwin` (Apple Silicon) ([#343](https://github.com/latex-lsp/texlab/issues/343))
+
## [2.2.1] - 06.01.2021
### Added
diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock
index 953089e524..c224bce2d3 100644
--- a/support/texlab/Cargo.lock
+++ b/support/texlab/Cargo.lock
@@ -1,16 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
-name = "adler32"
-version = "1.0.4"
+name = "ahash"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
+checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]]
name = "aho-corasick"
-version = "0.7.10"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
@@ -21,24 +21,14 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
-name = "aovec"
-version = "1.1.0"
+name = "anyhow"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6cfde8df73bd42d9bcbfd8fa4578d4d2a37512efe0436351739e025ab791cd9"
-dependencies = [
- "parking_lot 0.4.8",
- "smallvec 0.4.5",
-]
-
-[[package]]
-name = "arc-swap"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff"
+checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]]
name = "arrayref"
@@ -48,24 +38,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
-dependencies = [
- "nodrop",
-]
-
-[[package]]
-name = "arrayvec"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
-
-[[package]]
-name = "ascii"
-version = "0.9.3"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "ascii-canvas"
@@ -77,25 +52,14 @@ dependencies = [
]
[[package]]
-name = "async-trait"
-version = "0.1.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0"
-dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
-]
-
-[[package]]
name = "atty"
-version = "0.2.11"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
+ "hermit-abi",
"libc",
- "termion",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -106,51 +70,45 @@ checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
[[package]]
name = "autocfg"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
-
-[[package]]
-name = "base64"
-version = "0.11.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
-version = "0.12.3"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
-name = "base64"
-version = "0.13.0"
+name = "beef"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+checksum = "6736e2428df2ca2848d846c43e88745121a6654696e349ce0054a420815a7409"
[[package]]
name = "bibutils-sys"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e96544dd4aadc8416a2fdd0205a886664b6eb0c17704de46c836373e9c515"
+checksum = "701178dfb147521ab87f4729feff1c21b69449b3f09fc263dd429aa43afb4f5c"
dependencies = [
"cc",
]
[[package]]
name = "bit-set"
-version = "0.5.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
+checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
-version = "0.5.1"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
@@ -159,105 +117,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
-name = "bitvec"
-version = "0.19.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
-dependencies = [
- "funty",
- "radium",
- "tap",
- "wyz",
-]
-
-[[package]]
name = "blake2b_simd"
-version = "0.5.10"
+version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
+checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
- "arrayvec 0.5.1",
+ "arrayvec",
"constant_time_eq",
]
[[package]]
-name = "block-buffer"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
-dependencies = [
- "block-padding",
- "byte-tools",
- "byteorder",
- "generic-array",
-]
-
-[[package]]
-name = "block-padding"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
-dependencies = [
- "byte-tools",
-]
-
-[[package]]
-name = "bstr"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata",
- "serde",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742"
-
-[[package]]
-name = "byte-tools"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
-
-[[package]]
-name = "bytemuck"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
-
-[[package]]
name = "byteorder"
-version = "1.3.4"
+version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
-version = "0.5.6"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
-name = "cast"
-version = "0.2.3"
+name = "cancellation"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
-dependencies = [
- "rustc_version",
-]
+checksum = "f7a879c84c21f354f13535f87ad119ac3be22ebb9097b552a0af6a78f86628c4"
[[package]]
name = "cc"
-version = "1.0.52"
+version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
+checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cesu8"
@@ -361,21 +253,21 @@ dependencies = [
"salsa",
"serde",
"serde_derive",
- "smallvec 0.6.13",
+ "smallvec 0.6.14",
"strum",
"ucd-trie",
]
[[package]]
name = "clap"
-version = "2.33.0"
+version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
+checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
- "strsim 0.8.0",
+ "strsim",
"textwrap",
"unicode-width",
"vec_map",
@@ -391,29 +283,27 @@ dependencies = [
]
[[package]]
-name = "color_quant"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
-
-[[package]]
name = "combine"
-version = "3.8.1"
+version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
+checksum = "cc4369b5e4c0cddf64ad8981c0111e7df4f7078f4d6ba98fb31f2e17c4c57b7e"
dependencies = [
- "ascii",
- "byteorder",
- "either",
+ "bytes",
"memchr",
- "unreachable",
]
[[package]]
-name = "const_fn"
-version = "0.4.3"
+name = "console"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab"
+checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "terminal_size",
+ "winapi",
+]
[[package]]
name = "constant_time_eq"
@@ -422,49 +312,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
-name = "crc32fast"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
-dependencies = [
- "cfg-if 0.1.10",
-]
-
-[[package]]
-name = "criterion"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70daa7ceec6cf143990669a04c7df13391d55fb27bd4079d252fca774ba244d8"
-dependencies = [
- "atty",
- "cast",
- "clap",
- "criterion-plot",
- "csv",
- "itertools 0.9.0",
- "lazy_static",
- "num-traits",
- "oorandom",
- "plotters",
- "rayon",
- "regex",
- "serde",
- "serde_cbor",
- "serde_derive",
- "serde_json",
- "tinytemplate",
- "walkdir",
-]
-
-[[package]]
-name = "criterion-plot"
-version = "0.4.3"
+name = "convert_case"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
-dependencies = [
- "cast",
- "itertools 0.9.0",
-]
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "crossbeam"
@@ -473,7 +324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
dependencies = [
"cfg-if 0.1.10",
- "crossbeam-channel 0.4.2",
+ "crossbeam-channel 0.4.4",
"crossbeam-deque 0.7.3",
"crossbeam-epoch 0.8.2",
"crossbeam-queue",
@@ -482,9 +333,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
-version = "0.4.2"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
+checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
dependencies = [
"crossbeam-utils 0.7.2",
"maybe-uninit",
@@ -492,12 +343,12 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
-version = "0.5.0"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if 1.0.0",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils 0.8.3",
]
[[package]]
@@ -518,8 +369,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
dependencies = [
"cfg-if 1.0.0",
- "crossbeam-epoch 0.9.0",
- "crossbeam-utils 0.8.0",
+ "crossbeam-epoch 0.9.3",
+ "crossbeam-utils 0.8.3",
]
[[package]]
@@ -528,37 +379,37 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
"lazy_static",
"maybe-uninit",
- "memoffset",
+ "memoffset 0.5.6",
"scopeguard",
]
[[package]]
name = "crossbeam-epoch"
-version = "0.9.0"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
+checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
dependencies = [
"cfg-if 1.0.0",
- "const_fn",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils 0.8.3",
"lazy_static",
- "memoffset",
+ "memoffset 0.6.3",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
-version = "0.2.1"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
+checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
+ "maybe-uninit",
]
[[package]]
@@ -567,24 +418,29 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
"cfg-if 0.1.10",
"lazy_static",
]
[[package]]
name = "crossbeam-utils"
-version = "0.8.0"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
+checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
"cfg-if 1.0.0",
- "const_fn",
"lazy_static",
]
[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
name = "csl"
version = "0.0.1"
source = "git+https://github.com/cormacrelf/citeproc-rs?rev=68c7a7c16088b5d7751641ab37299ad064cdb221#68c7a7c16088b5d7751641ab37299ad064cdb221"
@@ -602,46 +458,39 @@ dependencies = [
]
[[package]]
-name = "csv"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
-dependencies = [
- "bstr",
- "csv-core",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "csv-core"
-version = "0.1.10"
+name = "cstree"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
+checksum = "88c3cc8aae0153c915c6752c6a8ab5ea741930f32011b1fe453bdf5c57e9c1ed"
dependencies = [
- "memchr",
+ "fxhash",
+ "lasso",
+ "parking_lot 0.11.1",
+ "text-size",
+ "triomphe",
]
[[package]]
-name = "deflate"
-version = "0.8.4"
+name = "derive-new"
+version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7"
+checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
dependencies = [
- "adler32",
- "byteorder",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
-name = "derive-new"
-version = "0.5.8"
+name = "derive_more"
+version = "0.99.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
+checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "convert_case",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
@@ -651,15 +500,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
-name = "digest"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -667,50 +507,53 @@ checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
-name = "docopt"
-version = "1.1.0"
+name = "dtoa"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
-dependencies = [
- "lazy_static",
- "regex",
- "serde",
- "strsim 0.9.3",
-]
+checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
[[package]]
name = "either"
-version = "1.5.3"
+version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "ena"
-version = "0.13.1"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36"
+checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
dependencies = [
"log",
]
[[package]]
-name = "error-chain"
-version = "0.12.2"
+name = "encode_unicode"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd"
+checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
dependencies = [
- "version_check 0.9.1",
+ "cfg-if 1.0.0",
]
[[package]]
-name = "fake-simd"
-version = "0.1.2"
+name = "encoding_rs_io"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
+checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
+dependencies = [
+ "encoding_rs",
+]
[[package]]
name = "fern"
@@ -722,6 +565,18 @@ dependencies = [
]
[[package]]
+name = "filetime"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "redox_syscall 0.2.5",
+ "winapi",
+]
+
+[[package]]
name = "fixedbitset"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -740,32 +595,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
-name = "fuchsia-cprng"
-version = "0.1.1"
+name = "form_urlencoded"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding",
+]
[[package]]
-name = "fuchsia-zircon"
-version = "0.3.3"
+name = "fsevent"
+version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+checksum = "97f347202c95c98805c216f9e1df210e8ebaec9fdb2365700a43c10797a35e63"
dependencies = [
"bitflags",
- "fuchsia-zircon-sys",
+ "fsevent-sys",
]
[[package]]
-name = "fuchsia-zircon-sys"
-version = "0.3.3"
+name = "fsevent-sys"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+checksum = "ca6f5e6817058771c10f0eb0f05ddf1e35844266f972004fe8e4b21fda295bd5"
+dependencies = [
+ "libc",
+]
[[package]]
-name = "funty"
-version = "1.0.1"
+name = "fuchsia-cprng"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8"
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "futf"
@@ -778,177 +640,86 @@ dependencies = [
]
[[package]]
-name = "futures"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
-
-[[package]]
-name = "futures-macro"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
-dependencies = [
- "proc-macro-hack",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
-
-[[package]]
-name = "futures-task"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "futures-util"
-version = "0.3.5"
+name = "fuzzy-matcher"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
+checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project",
- "pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
- "slab",
+ "thread_local",
]
[[package]]
-name = "fuzzy-matcher"
-version = "0.3.4"
+name = "fxhash"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75a03d6d8629fcd151ece9d3a7f59a87fc38a620ab0290bf2888c2ad73821170"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
- "thread_local",
+ "byteorder",
]
[[package]]
name = "generational-arena"
-version = "0.2.7"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e40d0cee2e2fb4fba18b55a27bf96faf49fa86d49f178695bd3bf4500b156b4"
+checksum = "8e1d3b771574f62d0548cee0ad9057857e9fc25d7a3335f140c84f6acd0bf601"
dependencies = [
"cfg-if 0.1.10",
]
[[package]]
-name = "generic-array"
-version = "0.12.3"
+name = "getrandom"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
- "typenum",
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
-version = "0.1.14"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"libc",
- "wasi",
+ "wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
-name = "gif"
-version = "0.10.3"
+name = "hashbrown"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af"
+checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
- "color_quant",
- "lzw",
+ "ahash",
]
[[package]]
-name = "half"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177"
-
-[[package]]
name = "heck"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
-version = "0.1.8"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "html2md"
-version = "0.2.10"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc63d976a14675a0be3c02eb5d0d233f5d51cf6cb6e8277521abef883380f190"
+checksum = "65122619e0f12bd9c4d061415265d5835bc36499d3ae24a83b5451ea8ba28444"
dependencies = [
"html5ever 0.25.1",
"jni",
@@ -967,9 +738,9 @@ dependencies = [
"log",
"mac",
"markup5ever 0.9.0",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
@@ -980,17 +751,17 @@ checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b"
dependencies = [
"log",
"mac",
- "markup5ever 0.10.0",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "markup5ever 0.10.1",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
name = "idna"
-version = "0.2.0"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
+checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
dependencies = [
"matches",
"unicode-bidi",
@@ -998,30 +769,13 @@ dependencies = [
]
[[package]]
-name = "image"
-version = "0.23.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "543904170510c1b5fb65140485d84de4a57fddb2ed685481e9020ce3d2c9f64c"
-dependencies = [
- "bytemuck",
- "byteorder",
- "gif",
- "jpeg-decoder",
- "num-iter",
- "num-rational",
- "num-traits",
- "png",
- "scoped_threadpool",
- "tiff",
-]
-
-[[package]]
name = "indexmap"
-version = "1.3.2"
+version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
+checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
+ "hashbrown",
]
[[package]]
@@ -1034,15 +788,50 @@ dependencies = [
]
[[package]]
-name = "iovec"
-version = "0.1.4"
+name = "inotify"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d19f57db1baad9d09e43a3cd76dcf82ebdafd37d75c9498b87762dba77c93f15"
+dependencies = [
+ "bitflags",
+ "inotify-sys",
+ "libc",
+]
+
+[[package]]
+name = "inotify-sys"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
+checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
dependencies = [
"libc",
]
[[package]]
+name = "insta"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1b21a2971cea49ca4613c0e9fe8225ecaf5de64090fddc6002284726e9244"
+dependencies = [
+ "console",
+ "lazy_static",
+ "serde",
+ "serde_json",
+ "serde_yaml",
+ "similar",
+ "uuid",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
name = "itertools"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1053,30 +842,30 @@ dependencies = [
[[package]]
name = "itertools"
-version = "0.9.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
+checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
dependencies = [
"either",
]
[[package]]
name = "itoa"
-version = "0.4.5"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "jni"
-version = "0.14.0"
+version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1981310da491a4f0f815238097d0d43d8072732b5ae5f8bd0d8eadf5bf245402"
+checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec"
dependencies = [
"cesu8",
"combine",
- "error-chain",
"jni-sys",
"log",
+ "thiserror",
"walkdir",
]
@@ -1087,140 +876,133 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
-name = "jpeg-decoder"
-version = "0.1.18"
+name = "lalrpop"
+version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451"
+checksum = "46962a8c71b91c3524b117dfdd70844d4265a173c4c9109f98171aebdcf1195f"
dependencies = [
- "byteorder",
- "rayon",
+ "ascii-canvas",
+ "atty",
+ "bit-set",
+ "diff",
+ "ena",
+ "itertools 0.10.0",
+ "lalrpop-util",
+ "petgraph 0.5.1",
+ "pico-args",
+ "regex",
+ "regex-syntax",
+ "string_cache 0.8.1",
+ "term",
+ "tiny-keccak",
+ "unicode-xid 0.2.1",
]
[[package]]
-name = "js-sys"
-version = "0.3.36"
+name = "lalrpop-util"
+version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5"
+checksum = "7a708007b751af124d09e9c5d97515257902bc6b486a56b40bcafd939e8ff467"
dependencies = [
- "wasm-bindgen",
+ "regex",
]
[[package]]
-name = "jsonrpc"
-version = "0.1.0"
+name = "lasso"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4efb7b456e95cc1ae2de7b18b1e4d791467b46f0a3d02464e5a16ea502091640"
dependencies = [
- "async-trait",
- "chashmap",
- "futures",
- "log",
- "serde",
- "serde_json",
- "serde_repr",
- "tokio",
+ "hashbrown",
]
[[package]]
-name = "jsonrpc-derive"
-version = "0.1.0"
-dependencies = [
- "quote 1.0.7",
- "syn 1.0.39",
-]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
-name = "kernel32-sys"
-version = "0.2.2"
+name = "libc"
+version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
+checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
[[package]]
-name = "lalrpop"
-version = "0.18.1"
+name = "linked-hash-map"
+version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de5e019883a6e9734d093f34216a3857160c6bc2a9a1ec196a177aaa737c74af"
-dependencies = [
- "ascii-canvas",
- "atty",
- "bit-set",
- "diff",
- "docopt",
- "ena",
- "itertools 0.8.2",
- "lalrpop-util",
- "petgraph 0.4.13",
- "regex",
- "regex-syntax",
- "serde",
- "serde_derive",
- "sha2",
- "string_cache 0.7.5",
- "term",
- "unicode-xid 0.2.0",
-]
+checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
-name = "lalrpop-util"
-version = "0.18.1"
+name = "lock_api"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d6e9bc1801eb54529fd6a020aaf9514e8193bb6b42d96d0fe7da99187efa93d"
+checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
dependencies = [
- "regex",
+ "scopeguard",
]
[[package]]
-name = "lazy_static"
-version = "1.4.0"
+name = "lock_api"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
+dependencies = [
+ "scopeguard",
+]
[[package]]
-name = "lexical-core"
-version = "0.6.2"
+name = "log"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7043aa5c05dd34fb73b47acb8c3708eac428de4545ea3682ed2f11293ebd890"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
- "arrayvec 0.4.12",
- "cfg-if 0.1.10",
- "rustc_version",
- "ryu",
- "static_assertions",
+ "cfg-if 1.0.0",
]
[[package]]
-name = "libc"
-version = "0.2.67"
+name = "logos"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
+checksum = "427e2abca5be13136da9afdbf874e6b34ad9001dd70f2b103b083a85daa7b345"
+dependencies = [
+ "logos-derive",
+]
[[package]]
-name = "lock_api"
-version = "0.3.3"
+name = "logos-derive"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b"
+checksum = "56a7d287fd2ac3f75b11f19a1c8a874a7d55744bd91f7a1b3e7cf87d4343c36d"
dependencies = [
- "scopeguard",
+ "beef",
+ "fnv",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "regex-syntax",
+ "syn 1.0.65",
+ "utf8-ranges",
]
[[package]]
-name = "log"
-version = "0.4.11"
+name = "lsp-server"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+checksum = "6825d7042d5ca1825a366c40c9446928ec7b30e2be97243a13b164aee6583992"
dependencies = [
- "cfg-if 0.1.10",
+ "crossbeam-channel 0.5.1",
+ "log",
+ "serde",
+ "serde_json",
]
[[package]]
name = "lsp-types"
-version = "0.74.1"
+version = "0.89.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57c0e6a2b8837d27b29deb3f3e6dc1c6d2f57947677f9be1024e482ec5b59525"
+checksum = "07731ecd4ee0654728359a5b95e2a254c857876c04b85225496a35d60345daa7"
dependencies = [
- "base64 0.12.3",
"bitflags",
"serde",
"serde_json",
@@ -1229,12 +1011,6 @@ dependencies = [
]
[[package]]
-name = "lzw"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
-
-[[package]]
name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1259,17 +1035,14 @@ dependencies = [
[[package]]
name = "markup5ever"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aae38d669396ca9b707bfc3db254bc382ddb94f57cc5c235f34623a669a01dab"
+checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd"
dependencies = [
"log",
"phf 0.8.0",
"phf_codegen 0.8.0",
- "serde",
- "serde_derive",
- "serde_json",
- "string_cache 0.8.0",
+ "string_cache 0.8.1",
"string_cache_codegen 0.5.1",
"tendril",
]
@@ -1281,7 +1054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f015da43bcd8d4f144559a3423f4591d69b8ce0652c905374da7205df336ae2b"
dependencies = [
"html5ever 0.25.1",
- "markup5ever 0.10.0",
+ "markup5ever 0.10.1",
"tendril",
"xml5ever",
]
@@ -1300,9 +1073,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
-version = "2.3.3"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "memoffset"
@@ -1310,91 +1083,47 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
]
[[package]]
-name = "miniz_oxide"
-version = "0.3.6"
+name = "memoffset"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
+checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
dependencies = [
- "adler32",
+ "autocfg 1.0.1",
]
[[package]]
name = "mio"
-version = "0.6.21"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
+checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
dependencies = [
- "cfg-if 0.1.10",
- "fuchsia-zircon",
- "fuchsia-zircon-sys",
- "iovec",
- "kernel32-sys",
"libc",
"log",
- "miow 0.2.1",
- "net2",
- "slab",
- "winapi 0.2.8",
-]
-
-[[package]]
-name = "mio-named-pipes"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"
-dependencies = [
- "log",
- "mio",
- "miow 0.3.3",
- "winapi 0.3.8",
-]
-
-[[package]]
-name = "mio-uds"
-version = "0.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
-dependencies = [
- "iovec",
- "libc",
- "mio",
-]
-
-[[package]]
-name = "miow"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
-dependencies = [
- "kernel32-sys",
- "net2",
- "winapi 0.2.8",
- "ws2_32-sys",
+ "miow",
+ "ntapi",
+ "winapi",
]
[[package]]
name = "miow"
-version = "0.3.3"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
+checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
- "socket2",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
-name = "net2"
-version = "0.2.33"
+name = "multimap"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
+checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "winapi 0.3.8",
+ "serde",
]
[[package]]
@@ -1404,12 +1133,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
-name = "nodrop"
-version = "0.1.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
-
-[[package]]
name = "nom"
version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1426,95 +1149,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"memchr",
- "version_check 0.9.1",
-]
-
-[[package]]
-name = "nom"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4489ccc7d668957ddf64af7cd027c081728903afa6479d35da7e99bf5728f75f"
-dependencies = [
- "bitvec",
- "lexical-core",
- "memchr",
- "version_check 0.9.1",
+ "version_check 0.9.3",
]
[[package]]
-name = "num-integer"
-version = "0.1.42"
+name = "notify"
+version = "5.0.0-pre.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
+checksum = "46bbbcd078f1f00ddb7a9abe70b96e91229b44b0b3afdec610f8e5137f8f014b"
dependencies = [
- "autocfg 1.0.0",
- "num-traits",
-]
-
-[[package]]
-name = "num-iter"
-version = "0.1.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
-dependencies = [
- "autocfg 1.0.0",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
-dependencies = [
- "autocfg 1.0.0",
- "num-integer",
- "num-traits",
+ "bitflags",
+ "crossbeam-channel 0.5.1",
+ "filetime",
+ "fsevent",
+ "fsevent-sys",
+ "inotify",
+ "libc",
+ "mio",
+ "walkdir",
+ "winapi",
]
[[package]]
-name = "num-traits"
-version = "0.2.11"
+name = "ntapi"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
+checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
- "autocfg 1.0.0",
+ "winapi",
]
[[package]]
name = "num_cpus"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
-name = "numtoa"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
-
-[[package]]
name = "once_cell"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
-
-[[package]]
-name = "oorandom"
-version = "11.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405"
-
-[[package]]
-name = "opaque-debug"
-version = "0.2.3"
+version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "ordermap"
@@ -1547,12 +1226,23 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
dependencies = [
- "lock_api",
+ "lock_api 0.3.4",
"parking_lot_core 0.6.2",
"rustc_version",
]
[[package]]
+name = "parking_lot"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
+dependencies = [
+ "instant",
+ "lock_api 0.4.2",
+ "parking_lot_core 0.8.3",
+]
+
+[[package]]
name = "parking_lot_core"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1560,8 +1250,8 @@ checksum = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
dependencies = [
"libc",
"rand 0.4.6",
- "smallvec 0.6.13",
- "winapi 0.3.8",
+ "smallvec 0.6.14",
+ "winapi",
]
[[package]]
@@ -1573,10 +1263,24 @@ dependencies = [
"cfg-if 0.1.10",
"cloudabi",
"libc",
- "redox_syscall",
+ "redox_syscall 0.1.57",
"rustc_version",
- "smallvec 0.6.13",
- "winapi 0.3.8",
+ "smallvec 0.6.14",
+ "winapi",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
+dependencies = [
+ "cfg-if 1.0.0",
+ "instant",
+ "libc",
+ "redox_syscall 0.2.5",
+ "smallvec 1.6.1",
+ "winapi",
]
[[package]]
@@ -1603,8 +1307,6 @@ checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [
"fixedbitset 0.2.0",
"indexmap",
- "serde",
- "serde_derive",
]
[[package]]
@@ -1676,9 +1378,9 @@ dependencies = [
"phf_generator 0.8.0",
"phf_shared 0.8.0",
"proc-macro-hack",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
@@ -1696,70 +1398,20 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
- "siphasher 0.3.1",
-]
-
-[[package]]
-name = "pin-project"
-version = "0.4.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "0.4.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb"
-dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "plotters"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb"
-dependencies = [
- "js-sys",
- "num-traits",
- "wasm-bindgen",
- "web-sys",
+ "siphasher 0.3.5",
]
[[package]]
-name = "png"
-version = "0.16.7"
+name = "pico-args"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970"
-dependencies = [
- "bitflags",
- "crc32fast",
- "deflate",
- "miniz_oxide",
-]
+checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d"
[[package]]
name = "ppv-lite86"
-version = "0.2.6"
+version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "precomputed-hash"
@@ -1769,46 +1421,33 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro-error"
-version = "1.0.2"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
- "version_check 0.9.1",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
+ "version_check 0.9.3",
]
[[package]]
name = "proc-macro-error-attr"
-version = "1.0.2"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
- "syn-mid",
- "version_check 0.9.1",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "version_check 0.9.3",
]
[[package]]
name = "proc-macro-hack"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
-dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
-]
-
-[[package]]
-name = "proc-macro-nested"
-version = "0.1.3"
+version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
@@ -1821,11 +1460,11 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.13"
+version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53f5ffe53a6b28e37c9c1ce74893477864d64f74778a93a4beb43c8fa167f639"
+checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
- "unicode-xid 0.2.0",
+ "unicode-xid 0.2.1",
]
[[package]]
@@ -1839,20 +1478,14 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.7"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
- "proc-macro2 1.0.13",
+ "proc-macro2 1.0.24",
]
[[package]]
-name = "radium"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
-
-[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1862,7 +1495,7 @@ dependencies = [
"libc",
"rand_core 0.3.1",
"rdrand",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -1881,7 +1514,7 @@ dependencies = [
"rand_os",
"rand_pcg 0.1.2",
"rand_xorshift",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -1890,7 +1523,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
- "getrandom",
+ "getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
@@ -1899,6 +1532,18 @@ dependencies = [
]
[[package]]
+name = "rand"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.0",
+ "rand_core 0.6.2",
+ "rand_hc 0.3.0",
+]
+
+[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1919,6 +1564,16 @@ dependencies = [
]
[[package]]
+name = "rand_chacha"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.2",
+]
+
+[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1939,7 +1594,16 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
- "getrandom",
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
+dependencies = [
+ "getrandom 0.2.2",
]
[[package]]
@@ -1961,6 +1625,15 @@ dependencies = [
]
[[package]]
+name = "rand_hc"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
+dependencies = [
+ "rand_core 0.6.2",
+]
+
+[[package]]
name = "rand_isaac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1977,7 +1650,7 @@ checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
dependencies = [
"libc",
"rand_core 0.4.2",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -1991,7 +1664,7 @@ dependencies = [
"libc",
"rand_core 0.4.2",
"rdrand",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -2028,7 +1701,7 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
"crossbeam-deque 0.8.0",
"either",
"rayon-core",
@@ -2040,9 +1713,9 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
dependencies = [
- "crossbeam-channel 0.5.0",
+ "crossbeam-channel 0.5.1",
"crossbeam-deque 0.8.0",
- "crossbeam-utils 0.8.0",
+ "crossbeam-utils 0.8.3",
"lazy_static",
"num_cpus",
]
@@ -2058,64 +1731,54 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.1.56"
+version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
+checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
-name = "redox_termios"
-version = "0.1.1"
+name = "redox_syscall"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
+checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
dependencies = [
- "redox_syscall",
+ "bitflags",
]
[[package]]
name = "redox_users"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
+checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
- "getrandom",
- "redox_syscall",
+ "getrandom 0.1.16",
+ "redox_syscall 0.1.57",
"rust-argon2",
]
[[package]]
name = "regex"
-version = "1.3.9"
+version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
- "thread_local",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
-dependencies = [
- "byteorder",
]
[[package]]
name = "regex-syntax"
-version = "0.6.18"
+version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
-version = "0.5.2"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -2129,14 +1792,14 @@ dependencies = [
[[package]]
name = "rust-argon2"
-version = "0.7.0"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
+checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
dependencies = [
- "base64 0.11.0",
+ "base64",
"blake2b_simd",
"constant_time_eq",
- "crossbeam-utils 0.7.2",
+ "crossbeam-utils 0.8.3",
]
[[package]]
@@ -2156,9 +1819,9 @@ dependencies = [
[[package]]
name = "ryu"
-version = "1.0.3"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "salsa"
@@ -2174,7 +1837,7 @@ dependencies = [
"rand 0.7.3",
"rustc-hash",
"salsa-macros",
- "smallvec 0.6.13",
+ "smallvec 0.6.14",
]
[[package]]
@@ -2184,9 +1847,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac182212d3a1db75ddc42399ff1461b258a694b8318ee7e0baf6c976e39efee"
dependencies = [
"heck",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
@@ -2199,12 +1862,6 @@ dependencies = [
]
[[package]]
-name = "scoped_threadpool"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
-
-[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2227,39 +1884,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
-version = "1.0.115"
+version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
+checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
dependencies = [
"serde_derive",
]
[[package]]
-name = "serde_cbor"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
-dependencies = [
- "half",
- "serde",
-]
-
-[[package]]
name = "serde_derive"
-version = "1.0.115"
+version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
+checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
name = "serde_json"
-version = "1.0.57"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
+checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
dependencies = [
"itoa",
"ryu",
@@ -2268,36 +1915,32 @@ dependencies = [
[[package]]
name = "serde_repr"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
+checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
-name = "sha2"
-version = "0.8.1"
+name = "serde_yaml"
+version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
+checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23"
dependencies = [
- "block-buffer",
- "digest",
- "fake-simd",
- "opaque-debug",
+ "dtoa",
+ "linked-hash-map",
+ "serde",
+ "yaml-rust",
]
[[package]]
-name = "signal-hook-registry"
-version = "1.2.0"
+name = "similar"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
-dependencies = [
- "arc-swap",
- "libc",
-]
+checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec"
[[package]]
name = "siphasher"
@@ -2307,60 +1950,39 @@ checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
[[package]]
name = "siphasher"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83da420ee8d1a89e640d0948c646c1c088758d3a3c538f943bfa97bdac17929d"
-
-[[package]]
-name = "slab"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
-
-[[package]]
-name = "smallvec"
-version = "0.4.5"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10"
+checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
[[package]]
name = "smallvec"
-version = "0.6.13"
+version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
+checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
dependencies = [
"maybe-uninit",
]
[[package]]
name = "smallvec"
-version = "1.4.0"
+version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
+checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
-name = "socket2"
-version = "0.3.11"
+name = "smol_str"
+version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85"
+checksum = "6ca0f7ce3a29234210f0f4f0b56f8be2e722488b95cb522077943212da3b32eb"
dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "redox_syscall",
- "winapi 0.3.8",
+ "serde",
]
[[package]]
name = "stable_deref_trait"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
-
-[[package]]
-name = "static_assertions"
-version = "0.3.4"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "string_cache"
@@ -2379,9 +2001,9 @@ dependencies = [
[[package]]
name = "string_cache"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a"
+checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a"
dependencies = [
"lazy_static",
"new_debug_unreachable",
@@ -2398,8 +2020,8 @@ checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6"
dependencies = [
"phf_generator 0.7.24",
"phf_shared 0.7.24",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
"string_cache_shared",
]
@@ -2411,8 +2033,8 @@ checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97"
dependencies = [
"phf_generator 0.8.0",
"phf_shared 0.8.0",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
]
[[package]]
@@ -2434,16 +2056,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
-name = "strsim"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
-
-[[package]]
name = "structopt"
-version = "0.3.20"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8"
+checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
dependencies = [
"clap",
"lazy_static",
@@ -2452,15 +2068,15 @@ dependencies = [
[[package]]
name = "structopt-derive"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8"
+checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
dependencies = [
"heck",
"proc-macro-error",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
@@ -2494,51 +2110,34 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.39"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9"
-dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "unicode-xid 0.2.0",
-]
-
-[[package]]
-name = "syn-mid"
-version = "0.5.0"
+version = "1.0.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
+checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "unicode-xid 0.2.1",
]
[[package]]
-name = "tap"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e"
-
-[[package]]
name = "tempfile"
-version = "3.1.0"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"libc",
- "rand 0.7.3",
- "redox_syscall",
+ "rand 0.8.3",
+ "redox_syscall 0.2.5",
"remove_dir_all",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
name = "tendril"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b"
+checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33"
dependencies = [
"futf",
"mac",
@@ -2553,71 +2152,78 @@ checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
dependencies = [
"byteorder",
"dirs",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
-name = "termion"
-version = "1.5.5"
+name = "terminal_size"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
+checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
dependencies = [
"libc",
- "numtoa",
- "redox_syscall",
- "redox_termios",
+ "winapi",
]
[[package]]
name = "texlab"
-version = "2.2.1"
+version = "3.0.1"
dependencies = [
- "aovec",
- "async-trait",
- "base64 0.13.0",
+ "anyhow",
"bibutils-sys",
"byteorder",
- "bytes",
- "cfg-if 0.1.10",
+ "cancellation",
+ "cfg-if 1.0.0",
"chashmap",
"citeproc",
"citeproc-db",
"citeproc-io",
- "criterion",
+ "crossbeam-channel 0.5.1",
"csl",
+ "cstree",
+ "derive_more",
+ "encoding_rs",
+ "encoding_rs_io",
"fern",
"fnv",
- "futures",
"fuzzy-matcher",
"html2md",
- "image",
"indoc",
- "itertools 0.9.0",
- "jsonrpc",
- "jsonrpc-derive",
+ "insta",
+ "itertools 0.10.0",
"lalrpop",
"lalrpop-util",
"log",
+ "logos",
+ "lsp-server",
"lsp-types",
- "nom 6.0.0",
+ "multimap",
+ "notify",
"once_cell",
"petgraph 0.5.1",
"rayon",
"regex",
+ "rustc-hash",
"serde",
"serde_json",
"serde_repr",
+ "smol_str",
"structopt",
"tempfile",
- "thiserror",
+ "threadpool",
"titlecase",
- "tokio",
- "tokio-util",
+ "typed-builder",
+ "unindent",
"url",
- "uuid",
]
[[package]]
+name = "text-size"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a"
+
+[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2628,126 +2234,107 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.19"
+version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344"
+checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.19"
+version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
+checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
name = "thread_local"
-version = "1.0.1"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
- "lazy_static",
+ "once_cell",
]
[[package]]
-name = "tiff"
-version = "0.5.0"
+name = "threadpool"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f"
+checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
- "byteorder",
- "lzw",
- "miniz_oxide",
+ "num_cpus",
]
[[package]]
name = "time"
-version = "0.1.42"
+version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
+checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
- "redox_syscall",
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
-name = "tinytemplate"
-version = "1.1.0"
+name = "tiny-keccak"
+version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d3dc76004a03cec1c5932bca4cdc2e39aaa798e3f82363dd94f9adf6098c12f"
+checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
- "serde",
- "serde_json",
+ "crunchy",
]
[[package]]
-name = "titlecase"
-version = "1.1.0"
+name = "tinyvec"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f565e410cfc24c2f2a89960b023ca192689d7f77d3f8d4f4af50c2d8affe1117"
+checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
dependencies = [
- "lazy_static",
- "regex",
+ "tinyvec_macros",
]
[[package]]
-name = "tokio"
-version = "0.2.21"
+name = "tinyvec_macros"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58"
-dependencies = [
- "bytes",
- "futures-core",
- "lazy_static",
- "libc",
- "memchr",
- "mio",
- "mio-named-pipes",
- "mio-uds",
- "pin-project-lite",
- "signal-hook-registry",
- "slab",
- "tokio-macros",
- "winapi 0.3.8",
-]
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
-name = "tokio-macros"
-version = "0.2.5"
+name = "titlecase"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
+checksum = "f565e410cfc24c2f2a89960b023ca192689d7f77d3f8d4f4af50c2d8affe1117"
dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "lazy_static",
+ "regex",
]
[[package]]
-name = "tokio-util"
-version = "0.3.1"
+name = "triomphe"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
+checksum = "6e9d872053cf9e5a833d8c1dd772cdc38ab66a908129d6f73c049c986161d07c"
dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "log",
- "pin-project-lite",
- "tokio",
+ "memoffset 0.5.6",
+ "serde",
+ "stable_deref_trait",
]
[[package]]
-name = "typenum"
-version = "1.11.2"
+name = "typed-builder"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
+checksum = "345426c7406aa355b60c5007c79a2d1f5b605540072795222f17f6443e6a9c6f"
+dependencies = [
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
+]
[[package]]
name = "ucd-trie"
@@ -2816,24 +2403,24 @@ dependencies = [
[[package]]
name = "unicode-normalization"
-version = "0.1.12"
+version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
+checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
dependencies = [
- "smallvec 1.4.0",
+ "tinyvec",
]
[[package]]
name = "unicode-segmentation"
-version = "1.6.0"
+version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]]
name = "unicode-width"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
+checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
@@ -2843,9 +2430,9 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "unicode-xid"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "unindent"
@@ -2854,20 +2441,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
[[package]]
-name = "unreachable"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
-dependencies = [
- "void",
-]
-
-[[package]]
name = "url"
-version = "2.1.1"
+version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
+ "form_urlencoded",
"idna",
"matches",
"percent-encoding",
@@ -2876,18 +2455,21 @@ dependencies = [
[[package]]
name = "utf-8"
-version = "0.7.5"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "utf8-ranges"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
[[package]]
name = "uuid"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
-dependencies = [
- "rand 0.7.3",
-]
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
[[package]]
name = "v_escape"
@@ -2905,9 +2487,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae"
dependencies = [
"nom 4.2.3",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
+ "proc-macro2 1.0.24",
+ "quote 1.0.9",
+ "syn 1.0.65",
]
[[package]]
@@ -2922,9 +2504,9 @@ dependencies = [
[[package]]
name = "vec_map"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
@@ -2934,24 +2516,18 @@ checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
[[package]]
name = "version_check"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
-
-[[package]]
-name = "void"
-version = "1.0.2"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "walkdir"
-version = "2.3.1"
+version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
- "winapi 0.3.8",
+ "winapi",
"winapi-util",
]
@@ -2962,92 +2538,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
-name = "wasm-bindgen"
-version = "0.2.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d"
-dependencies = [
- "cfg-if 0.1.10",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8"
-dependencies = [
- "bumpalo",
- "lazy_static",
- "log",
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205"
-dependencies = [
- "quote 1.0.7",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d"
-dependencies = [
- "proc-macro2 1.0.13",
- "quote 1.0.7",
- "syn 1.0.39",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8"
-
-[[package]]
-name = "web-sys"
-version = "0.3.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "winapi"
-version = "0.2.8"
+name = "wasi"
+version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
-name = "winapi-build"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
-
-[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3055,11 +2561,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.3"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
- "winapi 0.3.8",
+ "winapi",
]
[[package]]
@@ -3069,22 +2575,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
-name = "ws2_32-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
-[[package]]
-name = "wyz"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
-
-[[package]]
name = "xml5ever"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3092,7 +2582,7 @@ checksum = "0b1b52e6e8614d4a58b8e70cf51ec0cc21b256ad8206708bcff8139b5bbd6a59"
dependencies = [
"log",
"mac",
- "markup5ever 0.10.0",
+ "markup5ever 0.10.1",
"time",
]
@@ -3101,3 +2591,12 @@ name = "xmlparser"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8110496c5bcc0d966b0b2da38d5a791aa139eeb0b80e7840a7463c2b806921eb"
+
+[[package]]
+name = "yaml-rust"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+dependencies = [
+ "linked-hash-map",
+]
diff --git a/support/texlab/Cargo.toml b/support/texlab/Cargo.toml
index 3855dbf32d..56317c7f9c 100644
--- a/support/texlab/Cargo.toml
+++ b/support/texlab/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "texlab"
description = "LaTeX Language Server"
-version = "2.2.1"
+version = "3.0.1"
license = "GPL-3.0"
readme = "README.md"
authors = [
@@ -11,101 +11,66 @@ authors = [
edition = "2018"
homepage = "https://texlab.netlify.app"
-[workspace]
-members = ["crates/*"]
-
[lib]
doctest = false
[features]
-default = [
- "citation",
- "server",
- "test",
-]
-citation = [
- "bibutils-sys",
- "citeproc",
- "citeproc-db",
- "citeproc-io",
- "csl",
- "fnv",
- "html2md",
- "lalrpop/lexer",
- "lalrpop-util",
-]
-server = [
- "bytes",
- "jsonrpc",
- "jsonrpc-derive",
- "nom",
- "tokio-util/codec",
-]
-test = [
- "server",
- "aovec",
-]
-
-[[bin]]
-name = "texlab"
-required-features = ["server"]
-
-[[test]]
-name = "integration"
-required-features = ["test"]
+default = ["citation", "completion"]
+completion = ["fuzzy-matcher"]
+citation = ["bibutils-sys", "citeproc", "citeproc-db", "citeproc-io", "csl", "fnv", "html2md", "lalrpop-util", "lalrpop"]
+semantic = []
[dependencies]
-async-trait = "0.1"
-aovec = { version = "1.1", optional = true }
-base64 = "0.13"
-bibutils-sys = { version = "0.1", optional = true }
-byteorder = "1.3"
-bytes = { version = "0.5", optional = true }
-chashmap = "2.2"
-cfg-if = "0.1"
+anyhow = "1.0.40"
+bibutils-sys = { version = "0.1.1", optional = true }
+byteorder = "1.4.3"
+cancellation = "0.1"
+cfg-if = "1.0.0"
+chashmap = "2.2.2"
citeproc = { git = "https://github.com/cormacrelf/citeproc-rs", rev = "68c7a7c16088b5d7751641ab37299ad064cdb221", optional = true }
citeproc-db = { git = "https://github.com/cormacrelf/citeproc-rs", rev = "68c7a7c16088b5d7751641ab37299ad064cdb221", optional = true }
citeproc-io = { git = "https://github.com/cormacrelf/citeproc-rs", rev = "68c7a7c16088b5d7751641ab37299ad064cdb221", optional = true }
csl = { git = "https://github.com/cormacrelf/citeproc-rs", rev = "68c7a7c16088b5d7751641ab37299ad064cdb221", optional = true }
+crossbeam-channel = "0.5.1"
+cstree = "0.5.0"
+derive_more = "0.99.14"
+encoding_rs = "0.8.28"
+encoding_rs_io = "0.1.7"
fern = "0.6"
fnv = { version = "1.0", optional = true }
-futures = "0.3"
-fuzzy-matcher = "0.3"
-html2md = { version = "0.2", optional = true }
-image = "0.23"
-itertools = "0.9"
-jsonrpc = { path = "crates/jsonrpc", optional = true }
-jsonrpc-derive = { path = "crates/jsonrpc_derive", optional = true }
-lalrpop-util = { version = "0.18", optional = true }
-log = "0.4"
-lsp-types = { version = "0.74.1" }
-nom = { version = "6.0", optional = true }
-once_cell = "1.4"
-petgraph = { version = "0.5", features = ["serde-1"] }
-rayon = "1.5"
-regex = "1.3"
-serde = { version = "1.0", features = ["derive", "rc"] }
-serde_json = "1.0"
-serde_repr = "0.1"
+fuzzy-matcher = { version = "0.3.7", optional = true }
+html2md = { version = "0.2.11", optional = true }
+itertools = "0.10.0"
+lalrpop-util = { version = "0.19.5", optional = true }
+log = "0.4.14"
+logos = "0.12.0"
+lsp-server = "0.5"
+lsp-types = "0.89.0"
+multimap = "0.8.3"
+notify = "5.0.0-pre.8"
+once_cell = "1.7.2"
+petgraph = "0.5.1"
+rayon = "1.5.0"
+regex = "1.5.4"
+rustc-hash = "1.1.0"
+serde = "1.0.126"
+serde_json = "1.0.64"
+serde_repr = "0.1.7"
+smol_str = { version = "0.1.17", features = ["serde"] }
structopt = "0.3"
-tempfile = "3.1"
-thiserror = "1.0"
-titlecase = "1.1"
-tokio = { version = "0.2", features = ["fs", "io-std", "macros", "process", "rt-core", "time"] }
-tokio-util = { version = "0.3", optional = true }
-url = "2.1"
-uuid = { version = "0.8", features = ["v4"] }
+tempfile = "3.2.0"
+threadpool = "1.8.1"
+titlecase = "1.1.0"
+url = "2.2.2"
[dev-dependencies]
-criterion = "0.3"
-indoc = "1.0"
+indoc = "1.0.3"
+insta = "1.7.1"
+typed-builder = "0.9.0"
+unindent = "0.1.7"
[build-dependencies]
-lalrpop = { version = "0.18", optional = true }
+lalrpop = { version = "0.19.5", features = ["lexer"], optional = true }
[profile.release]
-lto = true
-
-[[bench]]
-name = "bench_main"
-harness = false
+lto = true \ No newline at end of file
diff --git a/support/texlab/README.md b/support/texlab/README.md
index f07fcd0bd9..b2edc3f2b4 100644
--- a/support/texlab/README.md
+++ b/support/texlab/README.md
@@ -15,19 +15,33 @@
A cross-platform implementation of the [Language Server Protocol](https://microsoft.github.io/language-server-protocol)
providing rich cross-editing support for the [LaTeX](https://www.latex-project.org/) typesetting system.
-We provide an [extension](https://github.com/latex-lsp/texlab-vscode) for [Visual Studio Code](https://code.visualstudio.com).
+The server may be used with [any editor that implements the Language Server Protocol](https://microsoft.github.io/language-server-protocol/implementors/tools/).
-Learn more about the project on our [website](https://texlab.netlify.app).
+![Demo](docs/demo.gif)
## Getting Started
-See the [installation chapter](https://texlab.netlify.app/docs) from our docs.
+If your editor extension like does not install the TexLab server automatically,
+you will need to install it manually.
+We provide [precompiled binaries](https://github.com/latex-lsp/texlab/releases)
+for Windows, Linux and macOS.
+Alternatively, you can build TexLab from source or install it using your package manager.
+For a list of supported package managers, you can take a look at [Repology](https://repology.org/project/texlab/versions).
-## Building from Source
+### Requirements
+
+A [TeX distribution](https://www.latex-project.org/get/#tex-distributions) is _not_ strictly required
+to use the server but TexLab cannot compile your documents without one.
+TexLab supports compiling using [Tectonic](https://tectonic-typesetting.github.io/).
+For an example configuration, please see [here](docs/tectonic.md).
+
+On Windows, you may need to install [Microsoft Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-US/download/details.aspx?id=48145).
+
+### Building from Source
You will need to install the following dependencies to compile the server:
-- [Rust (>= 1.39)](https://rustup.rs/)
+- A recent, stable version of [Rust](https://rustup.rs/)
Then run the following command in the project folder:
@@ -35,13 +49,22 @@ Then run the following command in the project folder:
cargo build --release
```
-Alternatively, Rust users can run the following command
-without having to clone this repository:
+Alternatively, you can run the following command
+without having to clone this repository and make TexLab available in your PATH:
```shell
-cargo install --git --locked https://github.com/latex-lsp/texlab.git
+cargo install --git https://github.com/latex-lsp/texlab.git --locked
```
+## Usage
+
+After installing an editor extension, you can simply start editing LaTeX files. All editing features work out-of-the-box over all files in the currently opened workspace.
+There is no need for magic comments like `%!TEX root`
+and TexLab should figure out the dependencies of a file on its own.
+Note that you may need to set the `texlab.rootDirectory` option for some multi-folder projects.
+
+TexLab features a variety of [options](docs/options.md) which can be used to configure features like building or [forward search](docs/previewing.md).
+
## Development
You can create a debug build by building the server without the `--release` flag.
@@ -56,6 +79,8 @@ cargo test
in the project folder.
+For a list of custom messages, please see [here](docs/custom_messages.md).
+
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
diff --git a/support/texlab/benches/bench_main.rs b/support/texlab/benches/bench_main.rs
deleted file mode 100644
index a73dbc1aa9..0000000000
--- a/support/texlab/benches/bench_main.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-mod benchmarks;
-
-use criterion::criterion_main;
-
-criterion_main! {
- benchmarks::completion::benches
-}
diff --git a/support/texlab/benches/benchmarks/completion.rs b/support/texlab/benches/benchmarks/completion.rs
deleted file mode 100644
index 4653102460..0000000000
--- a/support/texlab/benches/benchmarks/completion.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-use criterion::criterion_group;
-use criterion::{BenchmarkId, Criterion};
-use futures::executor::block_on;
-use indoc::indoc;
-use std::time::Duration;
-use texlab::{completion::CompletionProvider, feature::FeatureTester};
-
-fn criterion_benchmark(criterion: &mut Criterion) {
- criterion.bench_with_input(
- BenchmarkId::new("Completion", "LaTeX Word"),
- &LATEX_CODE,
- |b, code| {
- b.iter(|| {
- block_on(async {
- FeatureTester::new()
- .file("main.tex", *code)
- .main("main.tex")
- .position(0, 0)
- .test_completion(CompletionProvider::new())
- .await
- });
- });
- },
- );
-
- criterion.bench_with_input(
- BenchmarkId::new("Completion", "LaTeX Command (Filtered)"),
- &LATEX_CODE,
- |b, code| {
- b.iter(|| {
- block_on(async {
- FeatureTester::new()
- .file("main.tex", *code)
- .main("main.tex")
- .position(0, 1)
- .test_completion(CompletionProvider::new())
- .await
- });
- });
- },
- );
-
- criterion.bench_with_input(
- BenchmarkId::new("Completion", "LaTeX Command (Unfiltered)"),
- &LATEX_CODE,
- |b, code| {
- b.iter(|| {
- block_on(async {
- FeatureTester::new()
- .file("main.tex", *code)
- .main("main.tex")
- .position(30, 1)
- .test_completion(CompletionProvider::new())
- .await
- });
- });
- },
- );
-
- criterion.bench_with_input(
- BenchmarkId::new("Completion", "LaTeX Environment"),
- &LATEX_CODE,
- |b, code| {
- b.iter(|| {
- block_on(async {
- FeatureTester::new()
- .file("main.tex", *code)
- .main("main.tex")
- .position(9, 9)
- .test_completion(CompletionProvider::new())
- .await
- });
- })
- },
- );
-
- criterion.bench_with_input(
- BenchmarkId::new("Completion", "LaTeX Label"),
- &LATEX_CODE,
- |b, code| {
- b.iter(|| {
- block_on(async {
- FeatureTester::new()
- .file("main.tex", *code)
- .main("main.tex")
- .position(15, 7)
- .test_completion(CompletionProvider::new())
- .await
- });
- })
- },
- );
-}
-
-criterion_group! {
- name = benches;
- config = Criterion::default().measurement_time(Duration::from_secs(60));
- targets = criterion_benchmark
-}
-
-static LATEX_CODE: &str = indoc!(
- r#"
- \documentclass{article}
- \usepackage{amsmath}
- \usepackage{lipsum}
- \usepackage{geometry}
- \usepackage[utf8]{inputenc}
- \newcommand{\foo}{foo}
- \DeclareMathOperator{\bar}{bar}
- \include{child1}
- \input{child2.tex}
- \begin{document}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \begin{equation*}\label{eq:foo}
- e^{i \pi} + 1 = 0
- \end{equation*}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \ref{eq:foo}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \section{Foo}\label{sec:foo}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \subsection{Bar}\label{sec:bar}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \include{foo}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \input{bar.tex}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \cite{foo, bar, baz}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \nocite{*}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum lectus placerat, suscipit ligula quis.
- \end{document}
- \
- "#
-);
diff --git a/support/texlab/benches/benchmarks/mod.rs b/support/texlab/benches/benchmarks/mod.rs
deleted file mode 100644
index c893d109ab..0000000000
--- a/support/texlab/benches/benchmarks/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod completion;
diff --git a/support/texlab/build.rs b/support/texlab/build.rs
index 5283240997..e14ac6747e 100644
--- a/support/texlab/build.rs
+++ b/support/texlab/build.rs
@@ -1,5 +1,5 @@
fn main() {
- println!("cargo:rerun-if-changed=src/citeproc/name/parser.lalrpop");
+ println!("cargo:rerun-if-changed=src/citation/name/parser.lalrpop");
#[cfg(feature = "citation")]
lalrpop::process_root().unwrap();
diff --git a/support/texlab/crates/jsonrpc/Cargo.toml b/support/texlab/crates/jsonrpc/Cargo.toml
deleted file mode 100644
index c5cec72074..0000000000
--- a/support/texlab/crates/jsonrpc/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "jsonrpc"
-version = "0.1.0"
-authors = [
- "Eric Förster <eric.foerster@outlook.com>",
- "Patrick Förster <patrick.foerster@outlook.de>"]
-edition = "2018"
-
-[lib]
-doctest = false
-
-[dependencies]
-async-trait = "0.1"
-chashmap = "2.2"
-futures = "0.3"
-log = "0.4"
-serde = { version = "1.0", features = ["derive", "rc"] }
-serde_json = "1.0"
-serde_repr = "0.1"
-tokio = { version = "0.2", features = ["rt-core"] }
diff --git a/support/texlab/crates/jsonrpc/src/client.rs b/support/texlab/crates/jsonrpc/src/client.rs
deleted file mode 100644
index 7d714283c6..0000000000
--- a/support/texlab/crates/jsonrpc/src/client.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use super::types::*;
-use async_trait::async_trait;
-use chashmap::CHashMap;
-use futures::{
- channel::{mpsc, oneshot},
- prelude::*,
-};
-use serde::Serialize;
-use serde_json::json;
-use std::sync::atomic::{AtomicU64, Ordering};
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[async_trait]
-pub trait ResponseHandler {
- async fn handle(&self, response: Response);
-}
-
-#[derive(Debug)]
-pub struct Client {
- output: mpsc::Sender<String>,
- request_id: AtomicU64,
- senders_by_id: CHashMap<Id, oneshot::Sender<Result<serde_json::Value>>>,
-}
-
-impl Client {
- pub fn new(output: mpsc::Sender<String>) -> Self {
- Self {
- output,
- request_id: AtomicU64::new(0),
- senders_by_id: CHashMap::new(),
- }
- }
-
- pub async fn send_request<T: Serialize>(
- &self,
- method: String,
- params: T,
- ) -> Result<serde_json::Value> {
- let id = self.request_id.fetch_add(1, Ordering::SeqCst);
- let request = Request::new(method, json!(params), Id::Number(id));
-
- let (result_tx, result_rx) = oneshot::channel();
- self.senders_by_id.insert(request.id.clone(), result_tx);
- self.send(Message::Request(request)).await;
-
- result_rx.await.unwrap()
- }
-
- pub async fn send_notification<T: Serialize>(&self, method: String, params: T) {
- let notification = Notification::new(method, json!(params));
- self.send(Message::Notification(notification)).await;
- }
-
- async fn send(&self, message: Message) {
- let mut output = self.output.clone();
- let json = serde_json::to_string(&message).unwrap();
- output.send(json).await.unwrap();
- }
-}
-
-#[async_trait]
-impl ResponseHandler for Client {
- async fn handle(&self, response: Response) {
- let id = response.id.expect("Expected response with id");
- let result = match response.error {
- Some(why) => Err(why),
- None => Ok(response.result.unwrap_or(serde_json::Value::Null)),
- };
-
- let result_tx = self
- .senders_by_id
- .remove(&id)
- .expect("Unexpected response received");
- result_tx.send(result).unwrap();
- }
-}
diff --git a/support/texlab/crates/jsonrpc/src/lib.rs b/support/texlab/crates/jsonrpc/src/lib.rs
deleted file mode 100644
index 3a771e6ba5..0000000000
--- a/support/texlab/crates/jsonrpc/src/lib.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-pub mod client;
-pub mod server;
-mod types;
-
-pub use self::{
- client::{Client, ResponseHandler},
- server::{handle_notification, handle_request, Middleware, RequestHandler},
- types::*,
-};
-
-use futures::{channel::mpsc, prelude::*};
-use log::error;
-use std::sync::Arc;
-
-#[derive(Debug)]
-pub struct MessageHandler<S, C> {
- pub server: Arc<S>,
- pub client: Arc<C>,
- pub output: mpsc::Sender<String>,
-}
-
-impl<S, C> MessageHandler<S, C>
-where
- S: RequestHandler + Middleware + Send + Sync + 'static,
- C: ResponseHandler + Send + Sync + 'static,
-{
- pub async fn handle(&mut self, json: &str) {
- self.server.before_message().await;
-
- match serde_json::from_str(json).map_err(|_| Error::parse_error()) {
- Ok(Message::Request(request)) => {
- let server = Arc::clone(&self.server);
- let mut output = self.output.clone();
- tokio::spawn(async move {
- let response = server.handle_request(request).await;
- if let Some(error) = response.error.as_ref() {
- error!("{:?}", error);
- }
- let json = serde_json::to_string(&response).unwrap();
- output.send(json).await.unwrap();
- server.after_message().await;
- });
- }
- Ok(Message::Notification(notification)) => {
- self.server.handle_notification(notification).await;
- self.after_message();
- }
- Ok(Message::Response(response)) => {
- self.client.handle(response).await;
- self.after_message();
- }
- Err(why) => {
- let response = Response::error(why, None);
- let json = serde_json::to_string(&response).unwrap();
- self.output.send(json).await.unwrap();
- self.after_message();
- }
- };
- }
-
- fn after_message(&self) {
- let server = Arc::clone(&self.server);
- tokio::spawn(async move {
- server.after_message().await;
- });
- }
-}
diff --git a/support/texlab/crates/jsonrpc/src/server.rs b/support/texlab/crates/jsonrpc/src/server.rs
deleted file mode 100644
index ce34dc8b60..0000000000
--- a/support/texlab/crates/jsonrpc/src/server.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use super::types::*;
-use async_trait::async_trait;
-use futures::prelude::*;
-use serde::{de::DeserializeOwned, Serialize};
-use serde_json::json;
-
-pub type Result<T> = std::result::Result<T, String>;
-
-#[async_trait]
-pub trait RequestHandler {
- async fn handle_request(&self, request: Request) -> Response;
-
- async fn handle_notification(&self, notification: Notification);
-}
-
-#[async_trait]
-pub trait Middleware {
- async fn before_message(&self);
-
- async fn after_message(&self);
-}
-
-pub async fn handle_request<'a, H, F, I, O>(request: Request, handler: H) -> Response
-where
- H: Fn(I) -> F + Send + Sync + 'a,
- F: Future<Output = Result<O>> + Send,
- I: DeserializeOwned + Send,
- O: Serialize,
-{
- let handle = |json| async move {
- let params: I = serde_json::from_value(json).map_err(|_| Error::deserialize_error())?;
- let result = handler(params).await.map_err(Error::internal_error)?;
- Ok(result)
- };
-
- match handle(request.params).await {
- Ok(result) => Response::result(json!(result), request.id),
- Err(error) => Response::error(error, Some(request.id)),
- }
-}
-
-pub async fn handle_notification<'a, H, F, I>(notification: Notification, handler: H)
-where
- H: Fn(I) -> F + Send + Sync + 'a,
- F: Future<Output = ()> + Send,
- I: DeserializeOwned + Send,
-{
- let error = Error::deserialize_error().message;
- let params = serde_json::from_value(notification.params).expect(&error);
- handler(params).await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- const METHOD_NAME: &str = "foo";
-
- async fn increment(i: i32) -> Result<i32> {
- Ok(i + 1)
- }
-
- async fn panic(_params: ()) {
- panic!("success");
- }
-
- fn setup_request<T: Serialize>(value: T) -> Request {
- Request {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- params: json!(value),
- method: METHOD_NAME.to_owned(),
- id: Id::Number(0),
- }
- }
-
- fn setup_notification() -> Notification {
- Notification {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- method: METHOD_NAME.to_owned(),
- params: json!(()),
- }
- }
-
- #[tokio::test]
- async fn request_valid() {
- let value = 42;
- let request = setup_request(value);
-
- let response = handle_request(request.clone(), increment).await;
- let expected = Response {
- jsonrpc: request.jsonrpc,
- result: Some(json!(increment(value).await.unwrap())),
- error: None,
- id: Some(request.id),
- };
-
- assert_eq!(response, expected);
- }
-
- #[tokio::test]
- async fn request_invalid_params() {
- let request = setup_request((0, 0));
-
- let response = handle_request(request.clone(), increment).await;
- let expected = Response {
- jsonrpc: request.jsonrpc.clone(),
- result: None,
- error: Some(Error::deserialize_error()),
- id: Some(request.id),
- };
-
- assert_eq!(response, expected);
- }
-
- #[tokio::test]
- #[should_panic(expected = "success")]
- async fn notification_valid() {
- let notification = setup_notification();
- handle_notification(notification, panic).await;
- }
-
- #[tokio::test]
- #[should_panic]
- async fn notification_invalid_params() {
- let notification = Notification {
- params: json!(0),
- ..setup_notification()
- };
- handle_notification(notification, panic).await;
- }
-}
diff --git a/support/texlab/crates/jsonrpc/src/types.rs b/support/texlab/crates/jsonrpc/src/types.rs
deleted file mode 100644
index 30036d1c7f..0000000000
--- a/support/texlab/crates/jsonrpc/src/types.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-use serde::{Deserialize, Serialize};
-use serde_repr::*;
-
-pub const PROTOCOL_VERSION: &str = "2.0";
-
-#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]
-#[serde(untagged)]
-pub enum Id {
- Number(u64),
- String(String),
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize_repr, Serialize_repr)]
-#[repr(i32)]
-pub enum ErrorCode {
- ParseError = -32700,
- InvalidRequest = -32600,
- MethodNotFound = -32601,
- InvalidParams = -32602,
- InternalError = -32603,
- ServerNotInitialized = -32002,
- UnknownErrorCode = -32001,
- RequestCancelled = -32800,
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Error {
- pub code: ErrorCode,
- pub message: String,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub data: Option<serde_json::Value>,
-}
-
-impl Error {
- pub fn parse_error() -> Self {
- Self {
- code: ErrorCode::ParseError,
- message: "Could not parse the input".to_owned(),
- data: None,
- }
- }
-
- pub fn method_not_found_error() -> Self {
- Self {
- code: ErrorCode::MethodNotFound,
- message: "Method not found".to_owned(),
- data: None,
- }
- }
-
- pub fn deserialize_error() -> Self {
- Self {
- code: ErrorCode::InvalidParams,
- message: "Could not deserialize parameter object".to_owned(),
- data: None,
- }
- }
-
- pub fn internal_error(message: String) -> Self {
- Self {
- code: ErrorCode::InternalError,
- message,
- data: None,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Request {
- pub jsonrpc: String,
- pub method: String,
- pub params: serde_json::Value,
- pub id: Id,
-}
-
-impl Request {
- pub fn new(method: String, params: serde_json::Value, id: Id) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- method,
- params,
- id,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Response {
- pub jsonrpc: String,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub result: Option<serde_json::Value>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub error: Option<Error>,
-
- pub id: Option<Id>,
-}
-
-impl Response {
- pub fn result(result: serde_json::Value, id: Id) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- result: Some(result),
- error: None,
- id: Some(id),
- }
- }
-
- pub fn error(error: Error, id: Option<Id>) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- result: None,
- error: Some(error),
- id,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Notification {
- pub jsonrpc: String,
- pub method: String,
- pub params: serde_json::Value,
-}
-
-impl Notification {
- pub fn new(method: String, params: serde_json::Value) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- method,
- params,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-#[serde(untagged)]
-pub enum Message {
- Request(Request),
- Notification(Notification),
- Response(Response),
-}
diff --git a/support/texlab/crates/jsonrpc_derive/Cargo.toml b/support/texlab/crates/jsonrpc_derive/Cargo.toml
deleted file mode 100644
index fb99f16a26..0000000000
--- a/support/texlab/crates/jsonrpc_derive/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "jsonrpc-derive"
-version = "0.1.0"
-authors = [
- "Eric Förster <eric.foerster@outlook.com>",
- "Patrick Förster <patrick.foerster@outlook.de>"]
-edition = "2018"
-
-[lib]
-proc-macro = true
-doctest = false
-
-[dependencies]
-syn = "1.0"
-quote = "1.0"
diff --git a/support/texlab/crates/jsonrpc_derive/src/lib.rs b/support/texlab/crates/jsonrpc_derive/src/lib.rs
deleted file mode 100644
index 283be858db..0000000000
--- a/support/texlab/crates/jsonrpc_derive/src/lib.rs
+++ /dev/null
@@ -1,207 +0,0 @@
-#![recursion_limit = "128"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-use quote::quote;
-use syn::{export::TokenStream2, *};
-
-macro_rules! unwrap {
- ($input:expr, $arm:pat => $value:expr) => {{
- match $input {
- $arm => $value,
- _ => panic!(),
- }
- }};
-}
-
-enum MethodKind {
- Request,
- Notification,
-}
-
-struct MethodMeta {
- pub name: String,
- pub kind: MethodKind,
-}
-
-impl MethodMeta {
- pub fn parse(attr: &Attribute) -> Self {
- let meta = attr.parse_meta().unwrap();
- if meta.path().get_ident().unwrap() != "jsonrpc_method" {
- panic!("Expected jsonrpc_method attribute");
- }
-
- let nested = unwrap!(meta, Meta::List(x) => x.nested);
- let name = unwrap!(&nested[0], NestedMeta::Lit(Lit::Str(x)) => x.value());
- let kind = {
- let lit = unwrap!(&nested[1], NestedMeta::Meta(Meta::NameValue(x)) => &x.lit);
- let kind = unwrap!(lit, Lit::Str(x) => x.value());
- match kind.as_str() {
- "request" => MethodKind::Request,
- "notification" => MethodKind::Notification,
- _ => panic!(
- "Invalid method kind. Valid options are \"request\" and \"notification\""
- ),
- }
- };
-
- Self { name, kind }
- }
-}
-
-#[proc_macro_attribute]
-pub fn jsonrpc_method(_attr: TokenStream, item: TokenStream) -> TokenStream {
- item
-}
-
-#[proc_macro_attribute]
-pub fn jsonrpc_server(_attr: TokenStream, item: TokenStream) -> TokenStream {
- let impl_: ItemImpl = parse_macro_input!(item);
- let generics = &impl_.generics;
- let self_ty = &impl_.self_ty;
- let (requests, notifications) = generate_server_skeletons(&impl_.items);
-
- let tokens = quote! {
- #impl_
-
- #[async_trait::async_trait]
- impl #generics jsonrpc::RequestHandler for #self_ty {
- async fn handle_request(&self, request: jsonrpc::Request) -> jsonrpc::Response {
- use jsonrpc::*;
-
- match request.method.as_str() {
- #(#requests),*,
- _ => {
- Response::error(Error::method_not_found_error(), Some(request.id))
- }
- }
- }
-
- async fn handle_notification(&self, notification: jsonrpc::Notification) {
- match notification.method.as_str() {
- #(#notifications),*,
- _ => log::warn!("{}: {}", "Method not found", notification.method),
- }
- }
- }
- };
-
- tokens.into()
-}
-
-#[proc_macro_attribute]
-pub fn jsonrpc_client(attr: TokenStream, item: TokenStream) -> TokenStream {
- let trait_: ItemTrait = parse_macro_input!(item);
- let trait_ident = &trait_.ident;
- let stubs = generate_client_stubs(&trait_.items);
- let attr: AttributeArgs = parse_macro_input!(attr);
- let struct_ident = unwrap!(attr.first().unwrap(), NestedMeta::Meta(Meta::Path(x)) => x);
-
- let tokens = quote! {
- #[async_trait::async_trait]
- #trait_
-
- pub struct #struct_ident {
- client: jsonrpc::Client
- }
-
- impl #struct_ident
- {
- pub fn new(output: futures::channel::mpsc::Sender<String>) -> Self {
- Self {
- client: jsonrpc::Client::new(output),
- }
- }
- }
-
- #[async_trait::async_trait]
- impl #trait_ident for #struct_ident
- {
- #(#stubs)*
- }
-
- #[async_trait::async_trait]
- impl jsonrpc::ResponseHandler for #struct_ident
- {
- async fn handle(&self, response: jsonrpc::Response) -> () {
- self.client.handle(response).await
- }
- }
- };
-
- tokens.into()
-}
-
-fn generate_server_skeletons(items: &Vec<ImplItem>) -> (Vec<TokenStream2>, Vec<TokenStream2>) {
- let mut requests = Vec::new();
- let mut notifications = Vec::new();
- for item in items {
- let method = unwrap!(item, ImplItem::Method(x) => x);
- if method.attrs.is_empty() {
- continue;
- }
-
- let ident = &method.sig.ident;
- let param_ty = unwrap!(&method.sig.inputs[1], FnArg::Typed(x) => &x.ty);
- let meta = MethodMeta::parse(method.attrs.first().unwrap());
- let name = &meta.name.as_str();
-
- match meta.kind {
- MethodKind::Request => {
- requests.push(quote!(
- #name => {
- let handler = |param: #param_ty| async move {
- self.#ident(param).await
- };
-
- jsonrpc::handle_request(request, handler).await
- }
- ));
- }
- MethodKind::Notification => {
- notifications.push(quote!(
- #name => {
- let handler = |param: #param_ty| async move {
- self.#ident(param).await;
- };
-
- jsonrpc::handle_notification(notification, handler).await;
- }
- ));
- }
- }
- }
-
- (requests, notifications)
-}
-
-fn generate_client_stubs(items: &Vec<TraitItem>) -> Vec<TokenStream2> {
- let mut stubs = Vec::new();
- for item in items {
- let method = unwrap!(item, TraitItem::Method(x) => x);
- let attrs = &method.attrs;
- let sig = &method.sig;
- let param = unwrap!(&sig.inputs[1], FnArg::Typed(x) => &x.pat);
- let meta = MethodMeta::parse(attrs.first().unwrap());
- let name = &meta.name;
-
- let stub = match meta.kind {
- MethodKind::Request => quote!(
- #sig {
- let result = self.client.send_request(#name.to_owned(), #param).await?;
- serde_json::from_value(result).map_err(|_| jsonrpc::Error::deserialize_error())
- }
- ),
- MethodKind::Notification => quote!(
- #sig {
- self.client.send_notification(#name.to_owned(), #param).await
- }
- ),
- };
-
- stubs.push(stub);
- }
-
- stubs
-}
diff --git a/support/texlab/data/lang_data.json b/support/texlab/data/lang_data.json
index 6c156a2908..8cba6d297c 100644
--- a/support/texlab/data/lang_data.json
+++ b/support/texlab/data/lang_data.json
@@ -1,637 +1,4 @@
{
- "environmentCommands": [
- {
- "name": "\\begin",
- "index": 0
- },
- {
- "name": "\\end",
- "index": 0
- }
- ],
- "citationCommands": [
- {
- "name": "\\cite",
- "index": 0
- },
- {
- "name": "\\cite*",
- "index": 0
- },
- {
- "name": "\\Cite",
- "index": 0
- },
- {
- "name": "\\nocite",
- "index": 0
- },
- {
- "name": "\\citet",
- "index": 0
- },
- {
- "name": "\\citep",
- "index": 0
- },
- {
- "name": "\\citet*",
- "index": 0
- },
- {
- "name": "\\citep*",
- "index": 0
- },
- {
- "name": "\\citeauthor",
- "index": 0
- },
- {
- "name": "\\citeauthor*",
- "index": 0
- },
- {
- "name": "\\Citeauthor",
- "index": 0
- },
- {
- "name": "\\Citeauthor*",
- "index": 0
- },
- {
- "name": "\\citetitle",
- "index": 0
- },
- {
- "name": "\\citetitle*",
- "index": 0
- },
- {
- "name": "\\citeyear",
- "index": 0
- },
- {
- "name": "\\citeyear*",
- "index": 0
- },
- {
- "name": "\\citedate",
- "index": 0
- },
- {
- "name": "\\citedate*",
- "index": 0
- },
- {
- "name": "\\citeurl",
- "index": 0
- },
- {
- "name": "\\fullcite",
- "index": 0
- },
- {
- "name": "\\citeyearpar",
- "index": 0
- },
- {
- "name": "\\citealt",
- "index": 0
- },
- {
- "name": "\\citealp",
- "index": 0
- },
- {
- "name": "\\citetext",
- "index": 0
- },
- {
- "name": "\\parencite",
- "index": 0
- },
- {
- "name": "\\parencite*",
- "index": 0
- },
- {
- "name": "\\Parencite",
- "index": 0
- },
- {
- "name": "\\footcite",
- "index": 0
- },
- {
- "name": "\\footfullcite",
- "index": 0
- },
- {
- "name": "\\footcitetext",
- "index": 0
- },
- {
- "name": "\\textcite",
- "index": 0
- },
- {
- "name": "\\Textcite",
- "index": 0
- },
- {
- "name": "\\smartcite",
- "index": 0
- },
- {
- "name": "\\Smartcite",
- "index": 0
- },
- {
- "name": "\\supercite",
- "index": 0
- },
- {
- "name": "\\autocite",
- "index": 0
- },
- {
- "name": "\\Autocite",
- "index": 0
- },
- {
- "name": "\\autocite*",
- "index": 0
- },
- {
- "name": "\\Autocite*",
- "index": 0
- },
- {
- "name": "\\volcite",
- "index": 0
- },
- {
- "name": "\\Volcite",
- "index": 0
- },
- {
- "name": "\\pvolcite",
- "index": 0
- },
- {
- "name": "\\Pvolcite",
- "index": 0
- },
- {
- "name": "\\fvolcite",
- "index": 0
- },
- {
- "name": "\\ftvolcite",
- "index": 0
- },
- {
- "name": "\\svolcite",
- "index": 0
- },
- {
- "name": "\\Svolcite",
- "index": 0
- },
- {
- "name": "\\tvolcite",
- "index": 0
- },
- {
- "name": "\\Tvolcite",
- "index": 0
- },
- {
- "name": "\\avolcite",
- "index": 0
- },
- {
- "name": "\\Avolcite",
- "index": 0
- },
- {
- "name": "\\notecite",
- "index": 0
- },
- {
- "name": "\\notecite",
- "index": 0
- },
- {
- "name": "\\pnotecite",
- "index": 0
- },
- {
- "name": "\\Pnotecite",
- "index": 0
- },
- {
- "name": "\\fnotecite",
- "index": 0
- }
- ],
- "labelCommands": [
- {
- "name": "\\label",
- "index": 0,
- "kind": "definition"
- },
- {
- "name": "\\ref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\vref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Vref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\autoref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\pageref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\eqref",
- "index": 0,
- "kind": {
- "reference": "math"
- }
- },
- {
- "name": "\\cref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Cref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\crefrange",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\crefrange",
- "index": 1,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Crefrange",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Crefrange",
- "index": 1,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\cref*",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Cref*",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\crefrange*",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\crefrange*",
- "index": 1,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Crefrange*",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\Crefrange*",
- "index": 1,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\namecref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\nameCref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\lcnamecref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\namecrefs",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\nameCrefs",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\lcnamecrefs",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\labelcref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- },
- {
- "name": "\\labelcpageref",
- "index": 0,
- "kind": {
- "reference": "everything"
- }
- }
- ],
- "sectionCommands": [
- {
- "name": "\\part",
- "index": 0,
- "level": 0,
- "prefix": "Part"
- },
- {
- "name": "\\part*",
- "index": 0,
- "level": 0,
- "prefix": "Part"
- },
- {
- "name": "\\chapter",
- "index": 0,
- "level": 1,
- "prefix": "Chapter"
- },
- {
- "name": "\\chapter*",
- "index": 0,
- "level": 1,
- "prefix": "Chapter"
- },
- {
- "name": "\\section",
- "index": 0,
- "level": 2,
- "prefix": "Section"
- },
- {
- "name": "\\section*",
- "index": 0,
- "level": 2,
- "prefix": "Section"
- },
- {
- "name": "\\subsection",
- "index": 0,
- "level": 3,
- "prefix": "Subsection"
- },
- {
- "name": "\\subsection*",
- "index": 0,
- "level": 3,
- "prefix": "Subsection"
- },
- {
- "name": "\\subsubsection",
- "index": 0,
- "level": 4,
- "prefix": "Subsection"
- },
- {
- "name": "\\subsubsection*",
- "index": 0,
- "level": 4,
- "prefix": "Subsection"
- },
- {
- "name": "\\paragraph",
- "index": 0,
- "level": 5,
- "prefix": "Paragraph"
- },
- {
- "name": "\\paragraph*",
- "index": 0,
- "level": 5,
- "prefix": "Paragraph"
- },
- {
- "name": "\\subparagraph",
- "index": 0,
- "level": 6,
- "prefix": "Subparagraph"
- },
- {
- "name": "\\subparagraph*",
- "index": 0,
- "level": 6,
- "prefix": "Subparagraph"
- }
- ],
- "includeCommands": [
- {
- "name": "\\documentclass",
- "index": 0,
- "kind": "class",
- "includeExtension": false
- },
- {
- "name": "\\usepackage",
- "index": 0,
- "kind": "package",
- "includeExtension": false
- },
- {
- "name": "\\RequirePackage",
- "index": 0,
- "kind": "package",
- "includeExtension": false
- },
- {
- "name": "\\include",
- "index": 0,
- "kind": "latex",
- "includeExtension": false
- },
- {
- "name": "\\input",
- "index": 0,
- "kind": "latex",
- "includeExtension": true
- },
- {
- "name": "\\bibliography",
- "index": 0,
- "kind": "bibliography",
- "includeExtension": true
- },
- {
- "name": "\\addbibresource",
- "index": 0,
- "kind": "bibliography",
- "includeExtension": true
- },
- {
- "name": "\\includegraphics",
- "index": 0,
- "kind": "image",
- "includeExtension": true
- },
- {
- "name": "\\includesvg",
- "index": 0,
- "kind": "svg",
- "includeExtension": false
- },
- {
- "name": "\\includepdf",
- "index": 0,
- "kind": "pdf",
- "includeExtension": true
- },
- {
- "name": "\\verbatiminput",
- "index": 0,
- "kind": "everything",
- "includeExtension": true
- },
- {
- "name": "\\VerbatimInput",
- "index": 0,
- "kind": "everything",
- "includeExtension": true
- },
- {
- "name": "\\subfile",
- "index": 0,
- "kind": "latex",
- "includeExtension": false
- }
- ],
- "commandDefinitionCommands": [
- {
- "name": "\\newcommand",
- "definitionIndex": 0,
- "argCountIndex": 0,
- "implementationIndex": 1
- },
- {
- "name": "\\renewcommand",
- "definitionIndex": 0,
- "argCountIndex": 0,
- "implementationIndex": 1
- },
- {
- "name": "\\DeclareRobustCommand",
- "definitionIndex": 0,
- "argCountIndex": 0,
- "implementationIndex": 1
- }
- ],
- "mathOperatorCommands": [
- {
- "name": "\\DeclareMathOperator",
- "definitionIndex": 0,
- "implementationIndex": 1
- },
- {
- "name": "\\DeclareMathOperator*",
- "definitionIndex": 0,
- "implementationIndex": 1
- }
- ],
- "theoremDefinitionCommands": [
- {
- "name": "\\newtheorem",
- "index": 0
- },
- {
- "name": "\\declaretheorem",
- "index": 0
- }
- ],
"colors": [
"black",
"blue",
@@ -721,493 +88,6 @@
"Yellow",
"YellowOrange"
],
- "colorCommands": [
- {
- "name": "\\color",
- "index": 0
- },
- {
- "name": "\\colorbox",
- "index": 0
- },
- {
- "name": "\\textcolor",
- "index": 0
- },
- {
- "name": "\\pagecolor",
- "index": 0
- }
- ],
- "colorModelCommands": [
- {
- "name": "\\definecolor",
- "index": 1
- },
- {
- "name": "\\definecolorset",
- "index": 0
- }
- ],
- "glossaryEntryDefinitionCommands": [
- {
- "name": "\\newglossaryentry",
- "labelIndex": 0,
- "kind": "general"
- },
- {
- "name": "\\newacronym",
- "labelIndex": 0,
- "kind": "acronym"
- }
- ],
- "glossaryEntryReferenceCommands": [
- {
- "name": "\\gls",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Gls",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLS",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glspl",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glspl",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSpl",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsdisp",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glslink",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glstext",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glstext",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLStext",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsfirst",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsfirst",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSfirst",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsplural",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsplural",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSplural",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsfirstplural",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsfirstplural",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSfirstplural",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsname",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsname",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSname",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glssymbol",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glssymbol",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsdesc",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsdesc",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSdesc",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsuseri",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsuseri",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSuseri",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsuserii",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsuserii",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSuserii",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsuseriii",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsuseriii",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSuseriii",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsuseriv",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsuseriv",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSuseriv",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsuserv",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsuserv",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSuserv",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\glsuservi",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\Glsuservi",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\GLSuservi",
- "index": 0,
- "kind": "general"
- },
- {
- "name": "\\acrshort",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acrshort",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ACRshort",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acrshortpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acrshortpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ACRshortpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acrlong",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acrlong",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ACRlong",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acrlongpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acrlongpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ACRlongpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acrfull",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acrfull",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ACRfull",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acrfullpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acrfullpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ACRfullpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acs",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acs",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acsp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acsp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\aclp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Aclp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acf",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acf",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acfp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Acfp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\ac",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Ac",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\acp",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\glsentrylong",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Glsentrylong",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\glsentrylongpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Glsentrylongpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\glsentryshort",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Glsentryshort",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\glsentryshortpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Glsentryshortpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\glsentryfullpl",
- "index": 0,
- "kind": "acronym"
- },
- {
- "name": "\\Glsentryfullpl",
- "index": 0,
- "kind": "acronym"
- }
- ],
"entryTypes": [
{
"name": "preamble",
@@ -2198,6 +1078,8 @@
"eqnarray*",
"equation",
"equation*",
+ "subequations",
+ "subequations*",
"gather",
"gather*",
"gathered",
diff --git a/support/texlab/docs/custom_messages.md b/support/texlab/docs/custom_messages.md
new file mode 100644
index 0000000000..0142a76342
--- /dev/null
+++ b/support/texlab/docs/custom_messages.md
@@ -0,0 +1,102 @@
+# Custom Messages
+
+We extend the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/specification)
+with custom messages to provide better LaTeX integration.
+These messages are _optional_ and it is up to the client to support them.
+
+## Build Request
+
+The build request is sent from the client to the server to build a given LaTeX document.
+
+_Request_:
+
+- method: 'textDocument/build'
+- params: `BuildTextDocumentParams` defined as follows:
+
+```typescript
+interface BuildTextDocumentParams {
+ /**
+ * The text document to build.
+ */
+ textDocument: TextDocumentIdentifier;
+}
+```
+
+_Response_:
+
+- result: `BuildResult` defined as follows:
+
+```typescript
+interface BuildResult {
+ /**
+ * The status of the build process.
+ */
+ status: BuildStatus;
+}
+
+enum BuildStatus {
+ /**
+ * The build process terminated without any errors.
+ */
+ Success = 0,
+
+ /**
+ * The build process terminated with errors.
+ */
+ Error = 1,
+
+ /**
+ * The build process failed to start or crashed.
+ */
+ Failure = 2,
+
+ /**
+ * The build process was cancelled.
+ */
+ Cancelled = 3,
+}
+```
+
+## Forward Search Request
+
+The forward search request is sent from the client to the server when the user requests a forward search via SyncTeX.
+
+_Request_:
+
+- method: 'textDocument/forwardSearch'
+- params: [`TextDocumentPositionParams`](https://microsoft.github.io/language-server-protocol/specification#textdocumentpositionparams)
+
+_Response_:
+
+- result: `ForwardSearchResult` defined as follows:
+
+```typescript
+interface ForwardSearchResult {
+ /**
+ * The status of the previewer process.
+ */
+ status: ForwardSearchStatus;
+}
+
+enum ForwardSearchStatus {
+ /**
+ * The previewer process executed the command without any errors.
+ */
+ Success = 0,
+
+ /**
+ * The previewer process executed the command with errors.
+ */
+ Error = 1,
+
+ /**
+ * The previewer process failed to start or crashed.
+ */
+ Failure = 2,
+
+ /**
+ * The previewer command is not configured.
+ */
+ Unconfigured = 3,
+}
+```
diff --git a/support/texlab/docs/demo.gif b/support/texlab/docs/demo.gif
new file mode 100644
index 0000000000..6bb0817a59
--- /dev/null
+++ b/support/texlab/docs/demo.gif
Binary files differ
diff --git a/support/texlab/docs/lsp_kinds.md b/support/texlab/docs/lsp_kinds.md
new file mode 100644
index 0000000000..8d6ad6efc7
--- /dev/null
+++ b/support/texlab/docs/lsp_kinds.md
@@ -0,0 +1,31 @@
+The following table describes the mapping of LaTeX and BibTeX structures
+to their `CompletionItemKind` and `SymbolKind`.
+
+| LaTeX / BibTeX structure | CompletionItemKind | SymbolKind |
+| ------------------------- | -------------------- | -------------------- |
+| Command | `Function` (3) | `Function` (12) |
+| Command Argument | `Value` (12) | `Number` (16) |
+| Snippet | `Snippet` (15) | |
+| Environment | `Enum` (13) | `Enum` (10) |
+| Section | `Module` (9) | `Module` (2) |
+| Float | `Method` (2) | `Method` (6) |
+| Theorem | `Variable` (6) | `Variable` (13) |
+| Equation | `Constant` (21) | `Constant` (14) |
+| Enumeration Item | `EnumMember` (20) | `EnumMember` (22) |
+| Label | `Constructor` (4) | `Constructor` (9) |
+| Folder | `Folder` (19) | `Namespace` (3) |
+| File | `File` (17) | `File` (1) |
+| PGF Library | `Property` (10) | `Property` (7) |
+| TikZ Library | `Property` (10) | `Property` (7) |
+| Color | `Color` (16) | |
+| Color Model | `Color` (16) | |
+| Package | `Class` (7) | `Class` (5) |
+| Class | `Class` (7) | `Class` (5) |
+| BibTeX Entry (Misc) | `Interface` (8) | `Interface` (11) |
+| BibTeX Entry (Article) | `Event` (23) | `Event` (24) |
+| BibTeX Entry (Book) | `Struct` (22) | `Struct` (23) |
+| BibTeX Entry (Collection) | `TypeParameter` (25) | `TypeParameter` (26) |
+| BibTeX Entry (Part) | `Operator` (24) | `Operator` (25) |
+| BibTeX Entry (Thesis) | `Unit` (11) | `Object` (19) |
+| BibTeX String | `Text` (1) | `String` (15) |
+| BibTeX Field | `Field` (5) | `Field` (8) |
diff --git a/support/texlab/docs/options.md b/support/texlab/docs/options.md
new file mode 100644
index 0000000000..9cabd31062
--- /dev/null
+++ b/support/texlab/docs/options.md
@@ -0,0 +1,145 @@
+# Configuration
+
+This document describes the configuration settings
+that the server will query from the LSP client / extension.
+
+---
+
+## texlab.rootDirectory
+
+Defines the directory from which the source files get compiled.
+You may need to set this property for multi-folder projects
+where TexLab fails to detect the root document.
+
+**Type:** `string | null`
+
+**Default value**: `null`
+
+---
+
+## texlab.build.executable
+
+Defines the executable of the LaTeX build tool.
+
+**Type:** `string`
+
+**Default value:** `latexmk`
+
+---
+
+## texlab.build.args
+
+Defines additional arguments that are passed to the configured LaTeX build tool.
+Note that flags and their arguments need to be separate
+elements in this array.
+To pass the arguments `-foo bar` to a build tool,
+`latex.build.args` needs to be `["-foo", "bar"]`.
+The placeholder `%f` will be replaced by the server.
+
+**Placeholders:**
+
+- `%f`: The path of the TeX file to compile.
+
+**Type:** `string[]`
+
+**Default value:** `["-pdf", "-interaction=nonstopmode", "-synctex=1", "%f"]`
+
+---
+
+## texlab.build.isContinuous
+
+Set this property to true if the build arguments imply a continous build (like `latexmk -pvc`).
+
+**Type:** `boolean`
+
+**Default value:** `false`
+
+---
+
+## texlab.auxDirectory
+
+Defines the directory containing the build artifacts.
+Note that you need to set the output directory in `latex.build.args` too,
+if you want to change the build directory.
+In this case, use the `-outdir` flag for `latexmk`.
+
+**Type:** `string`
+
+**Default value:** `.` (the same directory as the TeX file)
+
+## texlab.forwardSearch.executable
+
+Defines the executable of the PDF previewer.
+The previewer needs to support [SyncTeX](http://www.tug.org/TUGboat/tb29-3/tb93laurens.pdf).
+
+**Type:** `string | null`
+
+**Default value:** `null`
+
+---
+
+## texlab.forwardSearch.args
+
+Defines additional arguments that are passed to the configured previewer to perform the forward search.
+The placeholders `%f, %p, %l` will be replaced by the server.
+
+**Placeholders:**
+
+- `%f`: The path of the current TeX file.
+- `%p`: The path of the current PDF file.
+- `%l`: The current line number.
+
+**Type:** `string[] | null`
+
+**Default value:** `null`
+
+---
+
+## texlab.chktex.onOpenAndSave
+
+Lint using [chktex](https://www.nongnu.org/chktex/) after opening and saving a file.
+
+**Type:** `boolean`
+
+**Default value:** `false`
+
+---
+
+## texlab.chktex.onEdit
+
+Lint using [chktex](https://www.nongnu.org/chktex/) after editing a file.
+
+**Type:** `boolean`
+
+**Default value:** `false`
+
+---
+
+## texlab.diagnosticsDelay
+
+Delay in milliseconds before reporting diagnostics.
+
+**Type:** `integer`
+
+**Default value:** `300`
+
+---
+
+## texlab.formatterLineLength
+
+Defines the maximum amount of characters per line (0 = disable) when formatting BibTeX files.
+
+**Type:** `integer`
+
+**Default value:** `80`
+
+---
+
+## texlab.bibtexFormatter
+
+Defines the formatter to use for BibTeX formatting.
+Possible values are either `texlab` or `latexindent`.
+
+**Type:** `string`
+
+**Default value:** `texlab`
diff --git a/support/texlab/docs/previewing.md b/support/texlab/docs/previewing.md
new file mode 100644
index 0000000000..16a047190b
--- /dev/null
+++ b/support/texlab/docs/previewing.md
@@ -0,0 +1,217 @@
+# Previewing
+
+We believe that previewing should be a concern of the build system.
+With [`latexmk`](https://ctan.org/pkg/latexmk?lang=en), you can enable the preview feature by adding the `-pv` flag
+to the [`texlab.build.args`](/docs/reference/configuration/#latexbuildargs) setting.
+After that, the configured previewer will start on each rebuild of the document.
+Alternatively, use the `-pvc` flag to tell the previewer to continuously check for updates,
+instead of opening a new window each time a build completes.
+
+If you want to use [SyncTeX](http://www.tug.org/TUGboat/tb29-3/tb93laurens.pdf),
+you need to configure the settings in the [`texlab.forwardSearch`](/docs/reference/configuration#latexforwardsearchexecutable) section
+and configure your previewer to call your editor correctly.
+A forward search can then be executed by invoking the [`texlab.forwardSearch`](/docs/reference/commands#latexforwardsearch) command.
+
+In the following sections, we will give configurations for popular viewers with `latexmk` and Visual Studio Code.
+For other build systems and editors, please refer to their respective manuals.
+
+---
+
+## SumatraPDF
+
+We highly recommend [SumatraPDF](https://www.sumatrapdfreader.org) on Windows
+because Adobe Reader locks the opened PDF file and will therefore prevent further builds.
+To use [SumatraPDF](https://www.sumatrapdfreader.org) as previewer, add the following line to your `%USERPROFILE%/.latexmkrc` file:
+
+```perl
+$pdf_previewer = 'start "C:\Program Files\SumatraPDF\SumatraPDF.exe" %O %S';
+```
+
+### Forward Search
+
+Add the following lines to your editor config:
+
+```json
+{
+ "texlab.forwardSearch.executable": "C:/Program Files/SumatraPDF/SumatraPDF.exe",
+ "texlab.forwardSearch.args": [
+ "-reuse-instance",
+ "%p",
+ "-forward-search",
+ "%f",
+ "%l"
+ ]
+}
+```
+
+### Inverse Search
+
+Add the following line to your SumatraPDF settings file (Menu -> Settings -> Advanced Options):
+
+```ini
+InverseSearchCmdLine = "C:\Users\{User}\AppData\Local\Programs\Microsoft VS Code\Code.exe" -g "%f":%l
+```
+
+> **Note**: Please make sure to replace `{User}` with your Windows username.
+
+You can execute the search by pressing `Alt+DoubleClick` in the PDF document.
+
+---
+
+## Evince
+
+The SyncTeX feature of [Evince](https://wiki.gnome.org/Apps/Evince) requires communication via D-Bus.
+In order to use it from the command line, install the [evince-synctex](https://github.com/latex-lsp/evince-synctex) script.
+Then add the following line to your `~/.latexmkrc` file:
+
+```perl
+$pdf_previewer = 'start evince-synctex %S "code -g %f:%l"';
+```
+
+### Forward Search
+
+Add the following lines to your editor config:
+
+```json
+{
+ "texlab.forwardSearch.executable": "evince-synctex",
+ "texlab.forwardSearch.args": ["-f", "%l", "%p", "\"code -g %f:%l\""]
+}
+```
+
+### Inverse Search
+
+The inverse search feature is already configured if you use `evince-synctex`.
+You can execute the search by pressing `Ctrl+Click` in the PDF document.
+
+---
+
+## Okular
+
+To use [Okular](https://okular.kde.org/) as previewer, add the following line to your `~/.latexmkrc` file:
+
+```perl
+$pdf_previewer = 'start okular';
+```
+
+### Forward Search
+
+Add the following lines to your editor config:
+
+```json
+{
+ "texlab.forwardSearch.executable": "okular",
+ "texlab.forwardSearch.args": ["--unique", "file:%p#src:%l%f"]
+}
+```
+
+### Inverse Search
+
+Change the editor of Okular (Settings -> Configure Okular... -> Editor) to "Custom Text Editor" and set the following command:
+
+```bash
+code -g "%f":%l
+```
+
+You can execute the search by pressing `Shift+Click` in the PDF document.
+
+---
+
+## Zathura
+
+To use [Zathura](https://pwmt.org/projects/zathura/) as previewer, add the following line to your `~/.latexmkrc` file:
+
+```perl
+$pdf_previewer = 'start zathura';
+```
+
+### Forward Search
+
+Add the following lines to your editor config:
+
+```json
+{
+ "texlab.forwardSearch.executable": "zathura",
+ "texlab.forwardSearch.args": ["--synctex-forward", "%l:1:%f", "%p"]
+}
+```
+
+### Inverse Search
+
+Add the following lines to your `~/.config/zathura/zathurarc` file:
+
+```bash
+set synctex true
+set synctex-editor-command "code -g %{input}:%{line}"
+```
+
+You can execute the search by pressing `Alt+Click` in the PDF document.
+
+---
+
+## qpdfview
+
+To use [qpdfview](https://launchpad.net/qpdfview) as previewer, add the following line to your `~/.latexmkrc` file:
+
+```perl
+$pdf_previewer = 'start qpdfview --unique %S';
+```
+
+### Forward Search
+
+Add the following lines to your editor config:
+
+```json
+{
+ "texlab.forwardSearch.executable": "qpdfview",
+ "texlab.forwardSearch.args": ["--unique", "%p#src:%f:%l:1"]
+}
+```
+
+### Inverse Search
+
+Change the source editor setting (Edit -> Settings... -> Behavior -> Source editor) to:
+
+```bash
+code -g "%1":%2
+```
+
+and select a mouse button modifier (Edit -> Settings... -> Behavior -> Modifiers -> Mouse button modifiers -> Open in Source Editor)
+of choice.
+You can execute the search by pressing `Modifier+Click` in the PDF document.
+
+---
+
+## Skim
+
+We recommend [Skim](https://skim-app.sourceforge.io/) on macOS since it is the only native viewer that supports SyncTeX.
+To use [Skim](https://skim-app.sourceforge.io/) as previewer, add the following line to your `~/.latexmkrc` file:
+
+```perl
+$pdf_previewer = 'open -a Skim';
+```
+
+If you want Skim to stay in the background after building,
+you can add the `-g` option to the `open` arguments.
+
+Additionally, enable the "Reload automatically" setting in the Skim preferences (Skim -> Preferences -> Sync -> Check for file changes).
+
+### Forward Search
+
+Add the following lines to your editor config:
+
+```json
+{
+ "texlab.forwardSearch.executable": "/Applications/Skim.app/Contents/SharedSupport/displayline",
+ "texlab.forwardSearch.args": ["%l", "%p", "%f"]
+}
+```
+
+If you want Skim to stay in the background after
+executing the forward search, you can add the `-g` option
+to `latex.forwardSearch.args`.
+
+### Inverse Search
+
+Select the Visual Studio Code preset in the Skim preferences (Skim -> Preferences -> Sync -> PDF-TeX Sync support).
+You can execute the search by pressing `Shift+⌘+Click` in the PDF document.
diff --git a/support/texlab/docs/tectonic.md b/support/texlab/docs/tectonic.md
new file mode 100644
index 0000000000..1e75c2d126
--- /dev/null
+++ b/support/texlab/docs/tectonic.md
@@ -0,0 +1,26 @@
+### Example: Using `tectonic`
+
+[`tectonic`](https://tectonic-typesetting.github.io/) is an alternative to `latexmk`, built in Rust.
+You can quickly get started by changing `.vscode/settings.json` in your workspace to include the following:
+
+```jsonc
+{
+ // See `tectonic --help` for the format
+ "texlab.build.executable": "tectonic",
+ "texlab.build.args": [
+ // Input
+ "%f",
+ // Flags
+ "--synctex",
+ "--keep-logs",
+ "--keep-intermediates"
+ // Options
+ // OPTIONAL: If you want a custom out directory,
+ // uncomment the following line.
+ //"--outdir out",
+ ]
+ // OPTIONAL: The extension needs to be configured
+ // to read the logs from the out directory as well.
+ // "latex.build.outputDirectory": "out",
+}
+```
diff --git a/support/texlab/src/build.rs b/support/texlab/src/build.rs
deleted file mode 100644
index fe4597c0d7..0000000000
--- a/support/texlab/src/build.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- BuildParams, BuildResult, BuildStatus, ClientCapabilitiesExt, LatexOptions,
- LogMessageParams, LspClient, MessageType, ProgressParams, ProgressParamsValue,
- ProgressToken, Uri, WorkDoneProgress, WorkDoneProgressBegin, WorkDoneProgressCreateParams,
- WorkDoneProgressEnd,
- },
-};
-use async_trait::async_trait;
-use chashmap::CHashMap;
-use futures::{
- future::{AbortHandle, Abortable, Aborted},
- lock::Mutex,
- prelude::*,
- stream,
-};
-use log::error;
-use std::{collections::HashMap, io, path::Path, process::Stdio, sync::Arc};
-use tokio::{
- io::{AsyncBufReadExt, BufReader},
- process::Command,
-};
-use uuid::Uuid;
-
-pub struct BuildProvider<C> {
- client: Arc<C>,
- handles_by_token: Mutex<HashMap<ProgressToken, AbortHandle>>,
- current_docs: CHashMap<Uri, ()>,
-}
-
-impl<C> BuildProvider<C> {
- pub fn new(client: Arc<C>) -> Self {
- Self {
- client,
- handles_by_token: Mutex::new(HashMap::new()),
- current_docs: CHashMap::new(),
- }
- }
-
- pub fn is_building(&self) -> bool {
- self.current_docs.len() > 0
- }
-
- pub async fn cancel(&self, token: ProgressToken) {
- let handles_by_token = self.handles_by_token.lock().await;
- if let Some(handle) = handles_by_token.get(&token) {
- handle.abort();
- } else if let ProgressToken::String(id) = token {
- if id == "texlab-build-*" {
- handles_by_token.values().for_each(|handle| handle.abort());
- }
- }
- }
-}
-
-#[async_trait]
-impl<C> FeatureProvider for BuildProvider<C>
-where
- C: LspClient + Send + Sync + 'static,
-{
- type Params = BuildParams;
- type Output = BuildResult;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<BuildParams>) -> BuildResult {
- let token = ProgressToken::String(format!("texlab-build-{}", Uuid::new_v4()));
- let (handle, reg) = AbortHandle::new_pair();
- {
- let mut handles_by_token = self.handles_by_token.lock().await;
- handles_by_token.insert(token.clone(), handle);
- }
-
- let doc = req
- .snapshot()
- .parent(&req.current().uri, &req.options, &req.current_dir)
- .unwrap_or_else(|| Arc::clone(&req.view.current));
-
- if !doc.is_file() {
- error!("Unable to build the document {}: wrong URI scheme", doc.uri);
- return BuildResult {
- status: BuildStatus::Failure,
- };
- }
-
- if self.current_docs.get(&doc.uri).is_some() {
- return BuildResult {
- status: BuildStatus::Success,
- };
- }
- self.current_docs.insert(doc.uri.clone(), ());
-
- let status = match doc.uri.to_file_path() {
- Ok(path) => {
- if req.client_capabilities.has_work_done_progress_support() {
- let params = WorkDoneProgressCreateParams {
- token: token.clone(),
- };
- self.client.work_done_progress_create(params).await.unwrap();
-
- let title = path.file_name().unwrap().to_string_lossy().into_owned();
- let params = ProgressParams {
- token: token.clone(),
- value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(
- WorkDoneProgressBegin {
- title,
- cancellable: Some(true),
- message: Some("Building".into()),
- percentage: None,
- },
- )),
- };
- self.client.progress(params).await;
- }
-
- let latex_options = req.options.latex.clone().unwrap_or_default();
- let client = Arc::clone(&self.client);
- match Abortable::new(build(&path, &latex_options, client), reg).await {
- Ok(Ok(true)) => BuildStatus::Success,
- Ok(Ok(false)) => BuildStatus::Error,
- Ok(Err(why)) => {
- error!("Unable to build the document {}: {}", doc.uri, why);
- BuildStatus::Failure
- }
- Err(Aborted) => BuildStatus::Cancelled,
- }
- }
- Err(()) => {
- error!("Unable to build the document {}: invalid URI", doc.uri);
- BuildStatus::Failure
- }
- };
-
- if req.client_capabilities.has_work_done_progress_support() {
- let params = ProgressParams {
- token: token.clone(),
- value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
- message: None,
- })),
- };
- self.client.progress(params).await;
- }
- {
- let mut handles_by_token = self.handles_by_token.lock().await;
- handles_by_token.remove(&token);
- }
-
- self.current_docs.remove(&doc.uri);
- BuildResult { status }
- }
-}
-
-async fn build<C>(path: &Path, options: &LatexOptions, client: Arc<C>) -> io::Result<bool>
-where
- C: LspClient + Send + Sync + 'static,
-{
- let build_options = options.build.as_ref().cloned().unwrap_or_default();
- let build_dir = options
- .root_directory
- .as_ref()
- .map(AsRef::as_ref)
- .or_else(|| path.parent())
- .unwrap();
-
- let args: Vec<_> = build_options
- .args()
- .into_iter()
- .map(|arg| replace_placeholder(arg, path))
- .collect();
-
- let mut process = Command::new(build_options.executable())
- .args(args)
- .stdin(Stdio::null())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped())
- .current_dir(build_dir)
- .kill_on_drop(true)
- .spawn()?;
-
- let stdout = BufReader::new(process.stdout.take().unwrap()).lines();
- let stderr = BufReader::new(process.stderr.take().unwrap()).lines();
- let mut output = stream::select(stdout, stderr);
-
- tokio::spawn(async move {
- while let Some(Ok(line)) = output.next().await {
- let params = LogMessageParams {
- typ: MessageType::Log,
- message: line,
- };
-
- client.log_message(params).await;
- }
- });
-
- Ok(process.await?.success())
-}
-
-fn replace_placeholder(arg: String, file: &Path) -> String {
- if arg.starts_with('"') || arg.ends_with('"') {
- arg
- } else {
- arg.replace("%f", &file.to_string_lossy())
- }
-}
diff --git a/support/texlab/src/protocol/capabilities.rs b/support/texlab/src/capabilities.rs
index c83b205aa8..e20a66b1ba 100644
--- a/support/texlab/src/protocol/capabilities.rs
+++ b/support/texlab/src/capabilities.rs
@@ -60,10 +60,13 @@ impl ClientCapabilitiesExt for ClientCapabilities {
#[cfg(test)]
mod tests {
use super::*;
- use lsp_types::*;
+ use lsp_types::{
+ DocumentSymbolClientCapabilities, GotoCapability, HoverClientCapabilities,
+ TextDocumentClientCapabilities, WindowClientCapabilities,
+ };
#[test]
- fn has_definition_link_support_true() {
+ fn test_has_definition_link_support_true() {
let capabilities = ClientCapabilities {
text_document: Some(TextDocumentClientCapabilities {
definition: Some(GotoCapability {
@@ -78,18 +81,18 @@ mod tests {
}
#[test]
- fn has_definition_link_support_false() {
+ fn test_has_definition_link_support_false() {
let capabilities = ClientCapabilities::default();
assert!(!capabilities.has_definition_link_support());
}
#[test]
- fn has_hierarchical_document_symbol_support_true() {
+ fn test_has_hierarchical_document_symbol_support_true() {
let capabilities = ClientCapabilities {
text_document: Some(TextDocumentClientCapabilities {
- document_symbol: Some(DocumentSymbolCapability {
+ document_symbol: Some(DocumentSymbolClientCapabilities {
hierarchical_document_symbol_support: Some(true),
- ..DocumentSymbolCapability::default()
+ ..DocumentSymbolClientCapabilities::default()
}),
..TextDocumentClientCapabilities::default()
}),
@@ -99,13 +102,13 @@ mod tests {
}
#[test]
- fn has_hierarchical_document_symbol_support_false() {
+ fn test_has_hierarchical_document_symbol_support_false() {
let capabilities = ClientCapabilities::default();
assert!(!capabilities.has_hierarchical_document_symbol_support());
}
#[test]
- fn has_work_done_progress_support_true() {
+ fn test_has_work_done_progress_support_true() {
let capabilities = ClientCapabilities {
window: Some(WindowClientCapabilities {
work_done_progress: Some(true),
@@ -117,18 +120,18 @@ mod tests {
}
#[test]
- fn has_work_done_progress_support_false() {
+ fn test_has_work_done_progress_support_false() {
let capabilities = ClientCapabilities::default();
assert!(!capabilities.has_work_done_progress_support());
}
#[test]
- fn has_hover_markdown_support_true() {
+ fn test_has_hover_markdown_support_true() {
let capabilities = ClientCapabilities {
text_document: Some(TextDocumentClientCapabilities {
- hover: Some(HoverCapability {
+ hover: Some(HoverClientCapabilities {
content_format: Some(vec![MarkupKind::PlainText, MarkupKind::Markdown]),
- ..HoverCapability::default()
+ ..HoverClientCapabilities::default()
}),
..TextDocumentClientCapabilities::default()
}),
@@ -138,7 +141,7 @@ mod tests {
}
#[test]
- fn has_hover_markdown_support_false() {
+ fn test_has_hover_markdown_support_false() {
let capabilities = ClientCapabilities::default();
assert!(!capabilities.has_hover_markdown_support());
}
diff --git a/support/texlab/src/citeproc/mod.rs b/support/texlab/src/citation.rs
index 6def2ed8a4..e185c14b55 100644
--- a/support/texlab/src/citeproc/mod.rs
+++ b/support/texlab/src/citation.rs
@@ -2,28 +2,30 @@ mod bibutils;
mod name;
mod ris;
-use self::{
- bibutils::{InputFormat, OutputFormat},
- ris::{RisLibrary, RisReference},
-};
-use crate::{
- protocol::{BibtexFormattingOptions, MarkupContent, MarkupKind},
- syntax::bibtex,
-};
-use citeproc::prelude::*;
+use std::sync::Arc;
+
+use citeproc::{prelude::SupportedFormat, ClusterPosition, Processor};
use citeproc_db::PredefinedLocales;
+use citeproc_io::{Cite, Cluster, Reference};
+use lsp_types::{MarkupContent, MarkupKind};
use once_cell::sync::Lazy;
use regex::Regex;
-use std::sync::Arc;
-static APA_STYLE: &str = include_str!("apa.csl");
+use crate::syntax::{bibtex, CstNode};
+
+use self::{
+ bibutils::*,
+ ris::{RisLibrary, RisReference},
+};
+
+static APA_STYLE: &str = include_str!("citation/apa.csl");
static DOI_URL_PATTERN: &str = r#"https://doi.org/\[.*\]\(.*\)"#;
static DOI_URL_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(DOI_URL_PATTERN).unwrap());
-pub fn render_citation(tree: &bibtex::Tree, key: &str) -> Option<MarkupContent> {
- let ris_reference = convert_to_ris(tree, key)?;
+pub fn render_citation(root: &bibtex::SyntaxNode, key: &str) -> Option<MarkupContent> {
+ let ris_reference = convert_to_ris(root, key)?;
let doi_url = get_doi_url_markdown(&ris_reference);
let csl_reference: Reference = ris_reference.into();
let html = generate_bibliography(csl_reference)?;
@@ -52,34 +54,22 @@ pub fn render_citation(tree: &bibtex::Tree, key: &str) -> Option<MarkupContent>
Some(content)
}
-fn convert_to_ris(tree: &bibtex::Tree, key: &str) -> Option<RisReference> {
- let options = BibtexFormattingOptions {
- line_length: None,
- formatter: None,
- };
- let params = bibtex::FormattingParams {
- insert_spaces: true,
- tab_size: 4,
- options: &options,
- };
-
+fn convert_to_ris(root: &bibtex::SyntaxNode, key: &str) -> Option<RisReference> {
let mut bib_code = String::new();
- tree.children(tree.root)
- .filter(|node| tree.as_string(*node).is_some())
- .map(|node| bibtex::format(tree, node, params))
- .for_each(|string| {
- bib_code.push_str(&string);
- bib_code.push('\n');
- });
-
- let entry = tree.entry_by_key(key)?;
- if let Some(crossref) = tree.crossref(entry) {
- bib_code.push_str(&bibtex::format(tree, crossref, params));
- bib_code.push('\n');
+ for string in root
+ .children()
+ .filter_map(bibtex::String::cast)
+ .filter(|string| string.name().is_some())
+ {
+ bib_code.push_str(&string.syntax().to_string());
}
- bib_code.push_str(&bibtex::format(tree, entry, params));
- bib_code.push('\n');
+ let entry = root
+ .children()
+ .filter_map(bibtex::Entry::cast)
+ .find(|entry| entry.key().map(|key| key.text()) == Some(key))?;
+ bib_code.push_str(&entry.syntax().to_string());
+
bib_code = bib_code.replace("\\hypen", "-");
let ris_code = bibutils::convert(&bib_code, InputFormat::Biblatex, OutputFormat::Ris)?;
@@ -119,21 +109,20 @@ fn generate_bibliography(reference: Reference) -> Option<String> {
#[cfg(test)]
mod tests {
use super::*;
- use indoc::indoc;
#[test]
- fn simple() {
- let tree = bibtex::open(indoc!(
+ fn test_simple() {
+ let document = bibtex::parse(
r#"
- @article{foo,
- author = {Foo Bar},
+ @article{foo,
+ author = {Foo Bar},
title = {Baz Qux},
year = {2020}
}
- "#
- ));
+ "#,
+ );
- let actual_md = render_citation(&tree, "foo").unwrap();
+ let actual_md = render_citation(&document.root, "foo").unwrap();
let expected_md = MarkupContent {
kind: MarkupKind::Markdown,
@@ -144,55 +133,18 @@ mod tests {
}
#[test]
- fn crossref() {
- let tree = bibtex::open(indoc!(
- r#"
- https://tex.stackexchange.com/questions/401138/what-is-the-bibtex-crossref-field-used-for
-
- @inproceedings{duck2015,
- author = {Duck, D.},
- title = {Duck tales},
- crossref = {ICRC2015},
- }
-
- @inproceedings{mouse2015,
- author = {Mouse, M.},
- title = {Mouse stories},
- crossref = {ICRC2015},
- }
-
- @proceedings{ICRC2015,
- title = "{Proceedings of the 34\textsuperscript{th} International Cosmic Ray Conference}",
- year = "2015",
- month = aug,
- }
- "#
- ));
-
- let actual_md = render_citation(&tree, "mouse2015").unwrap();
-
- let expected_md = MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Mouse, M. (2015). Mouse stories. In *Proceedings of the 34th International Cosmic Ray Conference*.".into(),
- };
-
- assert_eq!(actual_md, expected_md);
- }
-
- #[test]
- fn string() {
- let tree = bibtex::open(indoc!(
+ fn test_string() {
+ let document = bibtex::parse(
r#"
@string{author = "Foo Bar"}
- @article{foo,
- author = author,
+ @article{foo,
+ author = author,
title = {Baz Qux},
year = {2020}
}
- "#
- ));
-
- let actual_md = render_citation(&tree, "foo").unwrap();
+ "#,
+ );
+ let actual_md = render_citation(&document.root, "foo").unwrap();
let expected_md = MarkupContent {
kind: MarkupKind::Markdown,
@@ -203,10 +155,10 @@ mod tests {
}
#[test]
- fn unknown_key() {
- let tree = bibtex::open("");
+ fn test_unknown_key() {
+ let document = bibtex::parse("");
- let actual_md = render_citation(&tree, "foo");
+ let actual_md = render_citation(&document.root, "foo");
assert_eq!(actual_md, None);
}
diff --git a/support/texlab/src/citeproc/apa.csl b/support/texlab/src/citation/apa.csl
index 8454246a98..8454246a98 100644
--- a/support/texlab/src/citeproc/apa.csl
+++ b/support/texlab/src/citation/apa.csl
diff --git a/support/texlab/src/citeproc/bibutils.rs b/support/texlab/src/citation/bibutils.rs
index b69ed66ed1..9931ba3f9f 100644
--- a/support/texlab/src/citeproc/bibutils.rs
+++ b/support/texlab/src/citation/bibutils.rs
@@ -1,3 +1,5 @@
+use std::{ffi::CString, fs, mem::MaybeUninit, path::Path};
+
use bibutils_sys::{
bibl, bibl_free, bibl_freeparams, bibl_init, bibl_initparams, bibl_read, bibl_write, fclose,
fopen, param, BIBL_ADSABSOUT, BIBL_BIBLATEXIN, BIBL_BIBTEXIN, BIBL_BIBTEXOUT, BIBL_COPACIN,
@@ -5,10 +7,10 @@ use bibutils_sys::{
BIBL_MODSIN, BIBL_MODSOUT, BIBL_NBIBIN, BIBL_NBIBOUT, BIBL_OK, BIBL_RISIN, BIBL_RISOUT,
BIBL_WORD2007OUT, BIBL_WORDIN, FILE,
};
-use std::{ffi::CString, fs, mem::MaybeUninit, path::Path};
use tempfile::tempdir;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[allow(unused)]
pub enum InputFormat {
Bibtex,
Biblatex,
@@ -42,6 +44,7 @@ impl InputFormat {
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[allow(unused)]
pub enum OutputFormat {
Adsabs,
Bibtex,
@@ -183,6 +186,10 @@ pub fn convert(input: &str, from: InputFormat, to: OutputFormat) -> Option<Strin
// Remove BOM
let data = fs::read(&output_path).ok()?;
+ if data.is_empty() {
+ return None;
+ }
+
let text = String::from_utf8_lossy(&data[3..]).into_owned();
Some(text)
}
diff --git a/support/texlab/src/citeproc/name/mod.rs b/support/texlab/src/citation/name.rs
index ef97d30130..9e22383a7d 100644
--- a/support/texlab/src/citeproc/name/mod.rs
+++ b/support/texlab/src/citation/name.rs
@@ -1,14 +1,15 @@
// Ported from: https://github.com/michel-kraemer/citeproc-java/blob/master/citeproc-java/grammars/InternalName.g4
// Michel Kraemer
// Apache License 2.0
+use citeproc_io::Name;
+
+use parser::NamesParser;
+
mod parser {
#![allow(warnings)]
- include!(concat!(env!("OUT_DIR"), "/citeproc/name/parser.rs"));
+ include!(concat!(env!("OUT_DIR"), "/citation/name/parser.rs"));
}
-use self::parser::NamesParser;
-use citeproc_io::Name;
-
pub fn parse(input: &str) -> Vec<Name> {
let parser = NamesParser::new();
parser.parse(input).unwrap_or_else(|_| {
@@ -24,7 +25,7 @@ mod tests {
use citeproc_io::PersonName;
#[test]
- fn family_only() {
+ fn test_family_only() {
let name = Name::Person(PersonName {
family: Some("Thompson".into()),
given: None,
@@ -36,7 +37,7 @@ mod tests {
}
#[test]
- fn simple() {
+ fn test_simple() {
let name = Name::Person(PersonName {
family: Some("Thompson".into()),
given: Some("Ken".into()),
@@ -48,7 +49,7 @@ mod tests {
}
#[test]
- fn middle_name() {
+ fn test_middle_name() {
let name = Name::Person(PersonName {
family: Some("Ritchie".into()),
given: Some("Dennis M.".into()),
@@ -60,7 +61,7 @@ mod tests {
}
#[test]
- fn initials() {
+ fn test_initials() {
let name = Name::Person(PersonName {
family: Some("Johnson".into()),
given: Some("S. C.".into()),
@@ -72,7 +73,7 @@ mod tests {
}
#[test]
- fn non_dropping_particle() {
+ fn test_non_dropping_particle() {
let name = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: Some("Michael".into()),
@@ -84,7 +85,7 @@ mod tests {
}
#[test]
- fn non_dropping_particle_family_only() {
+ fn test_non_dropping_particle_family_only() {
let name = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: None,
@@ -96,7 +97,7 @@ mod tests {
}
#[test]
- fn comma() {
+ fn test_comma() {
let name = Name::Person(PersonName {
family: Some("Thompson".into()),
given: Some("Ken".into()),
@@ -108,7 +109,7 @@ mod tests {
}
#[test]
- fn comma_junior() {
+ fn test_comma_junior() {
let name = Name::Person(PersonName {
family: Some("Friedman".into()),
given: Some("George".into()),
@@ -120,7 +121,7 @@ mod tests {
}
#[test]
- fn comma_no_junior() {
+ fn test_comma_no_junior() {
let name = Name::Person(PersonName {
family: Some("Familya Familyb".into()),
given: Some("Given".into()),
@@ -132,7 +133,7 @@ mod tests {
}
#[test]
- fn comma_initials() {
+ fn test_comma_initials() {
let name = Name::Person(PersonName {
family: Some("Ritchie".into()),
given: Some("Dennis M.".into()),
@@ -144,7 +145,7 @@ mod tests {
}
#[test]
- fn comma_non_dropping_particle() {
+ fn test_comma_non_dropping_particle() {
let name = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: Some("Michael".into()),
@@ -156,7 +157,7 @@ mod tests {
}
#[test]
- fn comma_non_dropping_particles() {
+ fn test_comma_non_dropping_particles() {
let name = Name::Person(PersonName {
family: Some("Voort".into()),
given: Some("Vincent".into()),
@@ -168,7 +169,7 @@ mod tests {
}
#[test]
- fn and() {
+ fn test_and() {
let name1 = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: Some("Michael".into()),
@@ -190,7 +191,7 @@ mod tests {
}
#[test]
- fn and_comma1() {
+ fn test_and_comma1() {
let name1 = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: Some("Michael".into()),
@@ -212,7 +213,7 @@ mod tests {
}
#[test]
- fn and_comma2() {
+ fn test_and_comma2() {
let name1 = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: Some("Michael".into()),
@@ -234,7 +235,7 @@ mod tests {
}
#[test]
- fn and_comma_mix() {
+ fn test_and_comma_mix() {
let name1 = Name::Person(PersonName {
family: Some("Gerwen".into()),
given: Some("Michael".into()),
@@ -256,7 +257,7 @@ mod tests {
}
#[test]
- fn junior() {
+ fn test_junior() {
let name = Name::Person(PersonName {
family: Some("Friedman".into()),
given: Some("George".into()),
@@ -268,7 +269,7 @@ mod tests {
}
#[test]
- fn non_parseable() {
+ fn test_non_parseable() {
let literal = "Jerry Peek and Tim O'Reilly and Mike Loukides and other authors of the Nutshell handbooks";
let name = Name::Literal {
literal: literal.into(),
diff --git a/support/texlab/src/citeproc/name/parser.lalrpop b/support/texlab/src/citation/name/parser.lalrpop
index e7bce8a302..e7bce8a302 100644
--- a/support/texlab/src/citeproc/name/parser.lalrpop
+++ b/support/texlab/src/citation/name/parser.lalrpop
diff --git a/support/texlab/src/citeproc/ris.rs b/support/texlab/src/citation/ris.rs
index 1cb5754aec..5b666160a3 100644
--- a/support/texlab/src/citeproc/ris.rs
+++ b/support/texlab/src/citation/ris.rs
@@ -1,12 +1,13 @@
// Ported from: https://github.com/michel-kraemer/citeproc-java/tree/master/citeproc-java/templates
// Michel Kraemer
// Apache License 2.0
-use super::name;
use citeproc_io::{Date, DateOrRange, Name, NumericValue, Reference};
use csl::*;
use fnv::FnvHashMap;
use serde::{Deserialize, Serialize};
+use super::name;
+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum RisType {
diff --git a/support/texlab/src/client.rs b/support/texlab/src/client.rs
new file mode 100644
index 0000000000..72f2ac9eba
--- /dev/null
+++ b/support/texlab/src/client.rs
@@ -0,0 +1,53 @@
+use std::sync::Mutex;
+
+use anyhow::{anyhow, Result};
+use crossbeam_channel::{Receiver, Sender};
+use lsp_server::{Message, ResponseError};
+use serde::{de::DeserializeOwned, Serialize};
+
+use crate::req_queue::{OutgoingData, ReqQueue};
+
+pub fn send_notification<N>(lsp_sender: &Sender<Message>, params: N::Params) -> Result<()>
+where
+ N: lsp_types::notification::Notification,
+ N::Params: Serialize,
+{
+ lsp_sender.send(lsp_server::Notification::new(N::METHOD.to_string(), params).into())?;
+ Ok(())
+}
+
+pub fn send_request<R>(
+ req_queue: &Mutex<ReqQueue>,
+ lsp_sender: &Sender<Message>,
+ params: R::Params,
+) -> Result<R::Result>
+where
+ R: lsp_types::request::Request,
+ R::Params: Serialize,
+ R::Result: DeserializeOwned,
+{
+ let receiver = register_outgoing_request::<R>(req_queue, lsp_sender, params)?;
+ let params = receiver.recv()?.map_err(|err| anyhow!(err.message))?;
+ let result = serde_json::from_value(params)?;
+ Ok(result)
+}
+
+fn register_outgoing_request<R>(
+ req_queue: &Mutex<ReqQueue>,
+ lsp_sender: &Sender<Message>,
+ params: R::Params,
+) -> Result<Receiver<Result<serde_json::Value, ResponseError>>>
+where
+ R: lsp_types::request::Request,
+ R::Params: Serialize,
+ R::Result: DeserializeOwned,
+{
+ let mut req_queue = req_queue.lock().unwrap();
+ let (sender, receiver) = crossbeam_channel::bounded(1);
+ let method = R::METHOD.to_string();
+ let data = OutgoingData { sender };
+ let req = req_queue.outgoing.register(method, params, data);
+ drop(req_queue);
+ lsp_sender.send(req.into())?;
+ Ok(receiver)
+}
diff --git a/support/texlab/src/completion/bibtex/cmd.rs b/support/texlab/src/completion/bibtex/cmd.rs
deleted file mode 100644
index eab905386a..0000000000
--- a/support/texlab/src/completion/bibtex/cmd.rs
+++ /dev/null
@@ -1,177 +0,0 @@
-use crate::{
- completion::types::{Item, ItemData},
- components::COMPONENT_DATABASE,
- feature::FeatureRequest,
- protocol::{CompletionParams, RangeExt},
- syntax::SyntaxNode,
- workspace::DocumentContent,
-};
-
-pub async fn complete_bibtex_commands<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- let pos = req.params.text_document_position.position;
- if let Some(cmd) = tree
- .find(pos)
- .into_iter()
- .last()
- .and_then(|node| tree.as_command(node))
- {
- if cmd.token.range().contains(pos) && cmd.token.start().character != pos.character {
- let mut range = cmd.range();
- range.start.character += 1;
- for cmd in &COMPONENT_DATABASE.kernel().commands {
- let item = Item::new(
- range,
- ItemData::ComponentCommand {
- name: &cmd.name,
- image: cmd.image.as_deref(),
- glyph: cmd.glyph.as_deref(),
- file_names: &[],
- },
- );
- items.push(item);
- }
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_comment() {
- let req = FeatureTester::new()
- .file("main.bib", r#"\"#)
- .main("main.bib")
- .position(0, 1)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_command() {
- let req = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo, bar=
- \}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 1)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(1, 1, 1, 2));
- }
-
- #[tokio::test]
- async fn start_of_command() {
- let req = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo, bar=
- \}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_text() {
- let req = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo, bar=
- }
- "#
- ),
- )
- .main("main.bib")
- .position(1, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_latex_command() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\"#)
- .main("main.tex")
- .position(0, 1)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/bibtex/entry_type.rs b/support/texlab/src/completion/bibtex/entry_type.rs
deleted file mode 100644
index e3b12ef00d..0000000000
--- a/support/texlab/src/completion/bibtex/entry_type.rs
+++ /dev/null
@@ -1,164 +0,0 @@
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::{CompletionParams, Position, Range, RangeExt},
- syntax::{bibtex, SyntaxNode, LANGUAGE_DATA},
- workspace::DocumentContent,
-};
-
-pub async fn complete_bibtex_entry_types<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- let pos = req.params.text_document_position.position;
- for decl in tree.children(tree.root) {
- match &tree.graph[decl] {
- bibtex::Node::Preamble(preamble) => {
- if contains(&preamble.ty, pos) {
- make_items(items, preamble.ty.range());
- return;
- }
- }
- bibtex::Node::String(string) => {
- if contains(&string.ty, pos) {
- make_items(items, string.ty.range());
- return;
- }
- }
- bibtex::Node::Entry(entry) => {
- if contains(&entry.ty, pos) {
- make_items(items, entry.ty.range());
- return;
- }
- }
- _ => {}
- }
- }
- }
-}
-
-fn contains(ty: &bibtex::Token, pos: Position) -> bool {
- ty.range().contains(pos) && ty.start().character != pos.character
-}
-
-fn make_items(items: &mut Vec<Item>, mut range: Range) {
- range.start.character += 1;
- for ty in &LANGUAGE_DATA.entry_types {
- let item = Item::new(range, ItemData::EntryType { ty });
- items.push(item);
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn before_at_sign() {
- let req = FeatureTester::new()
- .file("main.bib", "@")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn after_at_sign() {
- let req = FeatureTester::new()
- .file("main.bib", "@")
- .main("main.bib")
- .position(0, 1)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 1, 0, 1));
- }
-
- #[tokio::test]
- async fn inside_entry_type() {
- let req = FeatureTester::new()
- .file("main.bib", "@foo")
- .main("main.bib")
- .position(0, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 1, 0, 4));
- }
-
- #[tokio::test]
- async fn inside_entry_key() {
- let req = FeatureTester::new()
- .file("main.bib", "@article{foo,}")
- .main("main.bib")
- .position(0, 11)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_comments() {
- let req = FeatureTester::new()
- .file("main.bib", "foo")
- .main("main.bib")
- .position(0, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_entry_types(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/bibtex/field_name.rs b/support/texlab/src/completion/bibtex/field_name.rs
deleted file mode 100644
index 039cc5d6b3..0000000000
--- a/support/texlab/src/completion/bibtex/field_name.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::{CompletionParams, Range, RangeExt},
- syntax::{bibtex, SyntaxNode, LANGUAGE_DATA},
- workspace::DocumentContent,
-};
-
-pub async fn complete_bibtex_fields<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- let pos = req.params.text_document_position.position;
- match tree
- .find(pos)
- .into_iter()
- .last()
- .map(|node| &tree.graph[node])
- {
- Some(bibtex::Node::Field(field)) => {
- if field.name.range().contains(pos) {
- make_items(items, field.name.range());
- return;
- }
- }
- Some(bibtex::Node::Entry(entry)) => {
- if !entry.is_comment() && !entry.ty.range().contains(pos) {
- let range = Range::new(pos, pos);
- if let Some(key) = &entry.key {
- if !key.range().contains(pos) {
- make_items(items, range);
- return;
- }
- } else {
- make_items(items, range);
- return;
- }
- }
- }
- _ => (),
- }
- }
-}
-
-fn make_items(items: &mut Vec<Item>, range: Range) {
- for field in &LANGUAGE_DATA.fields {
- let item = Item::new(range, ItemData::Field { field });
- items.push(item);
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_first_field() {
- let req = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo,
- bar}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 1)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(1, 0, 1, 3));
- }
-
- #[tokio::test]
- async fn inside_second_field() {
- let req = FeatureTester::new()
- .file("main.bib", "@article{foo, bar = {baz}, qux}")
- .main("main.bib")
- .position(0, 27)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 27, 0, 30));
- }
-
- #[tokio::test]
- async fn inside_entry() {
- let req = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo,
- }
- "#
- ),
- )
- .main("main.bib")
- .position(1, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(1, 0, 1, 0));
- }
-
- #[tokio::test]
- async fn inside_content() {
- let req = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo,
- bar = {baz}}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 7)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_entry_type() {
- let req = FeatureTester::new()
- .file("main.bib", "@article{foo,}")
- .main("main.bib")
- .position(0, 3)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_bibtex_fields(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/bibtex/mod.rs b/support/texlab/src/completion/bibtex/mod.rs
deleted file mode 100644
index 96f3a94932..0000000000
--- a/support/texlab/src/completion/bibtex/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub mod cmd;
-pub mod entry_type;
-pub mod field_name;
diff --git a/support/texlab/src/completion/latex/argument.rs b/support/texlab/src/completion/latex/argument.rs
deleted file mode 100644
index 5736099ca6..0000000000
--- a/support/texlab/src/completion/latex/argument.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
-};
-use std::iter;
-
-pub async fn complete_latex_arguments<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- for comp in req.view.components() {
- for cmd in &comp.commands {
- for (i, param) in cmd.parameters.iter().enumerate() {
- complete_internal(req, items, &cmd.name, i, param).await;
- }
- }
- }
-}
-
-async fn complete_internal<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
- name: &'a str,
- index: usize,
- param: &'a crate::components::Parameter,
-) {
- combinators::argument(
- req,
- iter::once(Parameter { name, index }),
- |ctx| async move {
- for arg in &param.0 {
- let item = Item::new(
- ctx.range,
- ItemData::Argument {
- name: &arg.name,
- image: arg.image.as_deref(),
- },
- );
- items.push(item);
- }
- },
- )
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_arguments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_arguments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_mathbb_empty() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \usepackage{amsfonts}
- \mathbb{}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 8)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_arguments(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(1, 8, 1, 8));
- }
-
- #[tokio::test]
- async fn inside_mathbb_non_empty() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \usepackage{amsfonts}
- \mathbb{foo}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 8)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_arguments(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(1, 8, 1, 11));
- }
-
- #[tokio::test]
- async fn outside_mathbb_empty() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \usepackage{amsfonts}
- \mathbb{}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 9)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_arguments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
-
-/*
-use super::combinators::{self, Parameter};
-use crate::{
- completion::factory,
- feature::{FeatureProvider, FeatureRequest},
- protocol::{CompletionItem, CompletionParams, TextEdit},
-};
-use async_trait::async_trait;
-use std::iter;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexArgumentCompletionProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexArgumentCompletionProvider {
- type Params = CompletionParams;
- type Output = Vec<CompletionItem>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut all_items = Vec::new();
- for comp in req.view.components() {
- for cmd in &comp.commands {
- let name = format!("\\{}", cmd.name);
- for (i, param) in cmd.parameters.iter().enumerate() {
- let mut items = combinators::argument(
- req,
- iter::once(Parameter {
- name: &name,
- index: i,
- }),
- |ctx| async move {
- let mut items = Vec::new();
- for arg in &param.0 {
- let text_edit = TextEdit::new(ctx.range, (&arg.name).into());
- let item = factory::argument(
- req,
- &arg.name,
- text_edit,
- arg.image.as_ref().map(AsRef::as_ref),
- );
- items.push(item);
- }
- items
- },
- )
- .await;
- all_items.append(&mut items);
- }
- }
- }
- all_items
- }
-}
-
-
-
-*/
diff --git a/support/texlab/src/completion/latex/begin_cmd.rs b/support/texlab/src/completion/latex/begin_cmd.rs
deleted file mode 100644
index 44e7a4f60d..0000000000
--- a/support/texlab/src/completion/latex/begin_cmd.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use super::combinators;
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
-};
-
-pub async fn complete_latex_begin_command<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- combinators::command(req, |cmd_node| async move {
- let table = req.current().content.as_latex().unwrap();
- let cmd = table.as_command(cmd_node).unwrap();
- let range = cmd.short_name_range();
- items.push(Item::new(range, ItemData::BeginCommand));
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_begin_command(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_begin_command(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn after_backslash() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\"#)
- .main("main.tex")
- .position(0, 1)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_begin_command(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- }
-}
diff --git a/support/texlab/src/completion/latex/citation.rs b/support/texlab/src/completion/latex/citation.rs
deleted file mode 100644
index 3e7b1851d1..0000000000
--- a/support/texlab/src/completion/latex/citation.rs
+++ /dev/null
@@ -1,261 +0,0 @@
-use super::combinators::{self, ArgumentContext, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::{BibtexFormattingOptions, CompletionParams},
- syntax::{bibtex, BibtexEntryTypeCategory, Structure, LANGUAGE_DATA},
- workspace::{Document, DocumentContent},
-};
-use once_cell::sync::Lazy;
-use petgraph::graph::NodeIndex;
-use regex::Regex;
-
-pub async fn complete_latex_citations<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let parameters = LANGUAGE_DATA.citation_commands.iter().map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument(req, parameters, |ctx| async move {
- for doc in req.related() {
- if let DocumentContent::Bibtex(tree) = &doc.content {
- for entry_node in tree.children(tree.root) {
- if let Some(item) = make_item(ctx, doc, tree, entry_node) {
- items.push(item);
- }
- }
- }
- }
- })
- .await;
-}
-
-fn make_item<'a>(
- ctx: ArgumentContext,
- doc: &'a Document,
- tree: &'a bibtex::Tree,
- entry_node: NodeIndex,
-) -> Option<Item<'a>> {
- let entry = tree.as_entry(entry_node)?;
- if entry.is_comment() {
- return None;
- }
-
- let key = entry.key.as_ref()?.text();
- let options = BibtexFormattingOptions::default();
- let params = bibtex::FormattingParams {
- insert_spaces: true,
- tab_size: 4,
- options: &options,
- };
- let entry_code = bibtex::format(tree, entry_node, params);
- let text = format!(
- "{} {}",
- &key,
- WHITESPACE_REGEX
- .replace_all(
- &entry_code
- .replace('{', "")
- .replace('}', "")
- .replace(',', " ")
- .replace('=', " "),
- " ",
- )
- .trim()
- );
-
- let ty = LANGUAGE_DATA
- .find_entry_type(&entry.ty.text()[1..])
- .map(|ty| Structure::Entry(ty.category))
- .unwrap_or_else(|| Structure::Entry(BibtexEntryTypeCategory::Misc));
-
- let item = Item::new(
- ctx.range,
- ItemData::Citation {
- uri: &doc.uri,
- key,
- text,
- ty,
- },
- );
- Some(item)
-}
-
-static WHITESPACE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("\\s+").unwrap());
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn incomplete() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{
- \begin{foo}
- \end{bar}
- "#
- ),
- )
- .file("main.bib", "@article{foo,}")
- .main("main.tex")
- .position(1, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- assert_eq!(actual_items[0].data.label(), "foo");
- assert_eq!(actual_items[0].range, Range::new_simple(1, 6, 1, 6));
- }
-
- #[tokio::test]
- async fn empty_key() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \addbibresource{bar.bib}
- \cite{}
- "#
- ),
- )
- .file("bar.bib", "@article{foo,}")
- .file("baz.bib", "@article{bar,}")
- .main("foo.tex")
- .position(1, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- assert_eq!(actual_items[0].data.label(), "foo");
- assert_eq!(actual_items[0].range, Range::new_simple(1, 6, 1, 6));
- }
-
- #[tokio::test]
- async fn single_key() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \addbibresource{bar.bib}
- \cite{foo}
- "#
- ),
- )
- .file("bar.bib", "@article{foo,}")
- .file("baz.bib", "@article{bar,}")
- .main("foo.tex")
- .position(1, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- assert_eq!(actual_items[0].data.label(), "foo");
- assert_eq!(actual_items[0].range, Range::new_simple(1, 6, 1, 9));
- }
-
- #[tokio::test]
- async fn second_key() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \addbibresource{bar.bib}
- \cite{foo,}
- "#
- ),
- )
- .file("bar.bib", "@article{foo,}")
- .file("baz.bib", "@article{bar,}")
- .main("foo.tex")
- .position(1, 10)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- assert_eq!(actual_items[0].data.label(), "foo");
- assert_eq!(actual_items[0].range, Range::new_simple(1, 10, 1, 10));
- }
-
- #[tokio::test]
- async fn outside_cite() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \addbibresource{bar.bib}
- \cite{}
- "#
- ),
- )
- .file("bar.bib", "@article{foo,}")
- .file("baz.bib", "@article{bar,}")
- .main("foo.tex")
- .position(1, 7)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_citations(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/latex/color.rs b/support/texlab/src/completion/latex/color.rs
deleted file mode 100644
index 93b06b178e..0000000000
--- a/support/texlab/src/completion/latex/color.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
- syntax::LANGUAGE_DATA,
-};
-
-pub async fn complete_latex_colors<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let parameters = LANGUAGE_DATA.color_commands.iter().map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument(req, parameters, |ctx| async move {
- for name in &LANGUAGE_DATA.colors {
- let item = Item::new(ctx.range, ItemData::Color { name });
- items.push(item);
- }
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_colors(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_colors(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_color() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\color{}"#)
- .main("main.tex")
- .position(0, 7)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_colors(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 7, 0, 7));
- }
-
- #[tokio::test]
- async fn inside_define_color_set() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\color{}"#)
- .main("main.tex")
- .position(0, 8)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_colors(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/latex/color_model.rs b/support/texlab/src/completion/latex/color_model.rs
deleted file mode 100644
index e0151da2f0..0000000000
--- a/support/texlab/src/completion/latex/color_model.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
- syntax::LANGUAGE_DATA,
-};
-
-const MODEL_NAMES: &[&str] = &["gray", "rgb", "RGB", "HTML", "cmyk"];
-
-pub async fn complete_latex_color_models<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let parameters = LANGUAGE_DATA
- .color_model_commands
- .iter()
- .map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument(req, parameters, |ctx| async move {
- for name in MODEL_NAMES {
- let item = Item::new(ctx.range, ItemData::ColorModel { name });
- items.push(item);
- }
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_color_models(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_color_models(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_define_color() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\definecolor{name}{}"#)
- .main("main.tex")
- .position(0, 19)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_color_models(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 19, 0, 19));
- }
-
- #[tokio::test]
- async fn inside_define_color_set() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\definecolorset{}"#)
- .main("main.tex")
- .position(0, 16)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_color_models(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 16, 0, 16));
- }
-}
diff --git a/support/texlab/src/completion/latex/combinators.rs b/support/texlab/src/completion/latex/combinators.rs
deleted file mode 100644
index d8ef336421..0000000000
--- a/support/texlab/src/completion/latex/combinators.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-use crate::{
- feature::FeatureRequest,
- protocol::{CompletionParams, Position, Range, RangeExt},
- syntax::{latex, AstNodeIndex, SyntaxNode, LANGUAGE_DATA},
- workspace::DocumentContent,
-};
-use std::future::Future;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct Parameter<'a> {
- pub name: &'a str,
- pub index: usize,
-}
-
-pub async fn command<E, F>(req: &FeatureRequest<CompletionParams>, execute: E)
-where
- E: FnOnce(AstNodeIndex) -> F,
- F: Future<Output = ()>,
-{
- if let DocumentContent::Latex(table) = &req.current().content {
- let pos = req.params.text_document_position.position;
- if let Some(cmd) = table.find_command_by_short_name_range(pos) {
- execute(cmd).await;
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct ArgumentContext<'a> {
- pub parameter: Parameter<'a>,
- pub node: AstNodeIndex,
- pub range: Range,
-}
-
-pub async fn argument<'a, I, E, F>(
- req: &'a FeatureRequest<CompletionParams>,
- mut parameters: I,
- execute: E,
-) where
- I: Iterator<Item = Parameter<'a>>,
- E: FnOnce(ArgumentContext<'a>) -> F,
- F: Future<Output = ()>,
-{
- if let DocumentContent::Latex(table) = &req.current().content {
- let pos = req.params.text_document_position.position;
- if let Some(node) = find_command(&table, pos) {
- let cmd = table.as_command(node).unwrap();
- for parameter in parameters
- .by_ref()
- .filter(|param| param.name == &cmd.name.text()[1..])
- {
- if let Some(args_node) =
- table.extract_group(node, latex::GroupKind::Group, parameter.index)
- {
- let args = table.as_group(args_node).unwrap();
- if args.right.is_some() && !args.range().contains_exclusive(pos) {
- continue;
- }
-
- let range = table
- .children(args_node)
- .filter_map(|child| table.as_text(child))
- .flat_map(|text| text.words.iter())
- .map(|word| word.range())
- .find(|range| range.contains(pos))
- .unwrap_or_else(|| Range::new(pos, pos));
-
- let context = ArgumentContext {
- parameter,
- node,
- range,
- };
- execute(context).await;
- return;
- }
- }
- }
- }
-}
-
-pub async fn argument_word<'a, I, E, F>(
- req: &'a FeatureRequest<CompletionParams>,
- mut parameters: I,
- execute: E,
-) where
- I: Iterator<Item = Parameter<'a>>,
- E: FnOnce(AstNodeIndex, usize) -> F,
- F: Future<Output = ()>,
-{
- if let DocumentContent::Latex(table) = &req.current().content {
- let pos = req.params.text_document_position.position;
- if let Some(node) = find_command(&table, pos) {
- let cmd = table.as_command(node).unwrap();
- for parameter in parameters
- .by_ref()
- .filter(|param| param.name == &cmd.name.text()[1..])
- {
- if let Some(args_node) =
- table.extract_group(node, latex::GroupKind::Group, parameter.index)
- {
- let args = table.as_group(args_node).unwrap();
- if args.right.is_some() && !args.range().contains_exclusive(pos) {
- continue;
- }
-
- if table.children(args_node).next().is_some()
- && table
- .extract_word(node, latex::GroupKind::Group, parameter.index)
- .is_none()
- {
- continue;
- }
-
- execute(node, parameter.index).await;
- return;
- }
- }
- }
- }
-}
-
-pub async fn environment<'a, E, F>(req: &'a FeatureRequest<CompletionParams>, execute: E)
-where
- E: FnOnce(ArgumentContext<'a>) -> F,
- F: Future<Output = ()>,
-{
- let parameters = LANGUAGE_DATA
- .environment_commands
- .iter()
- .map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
- argument(req, parameters, execute).await;
-}
-
-fn find_command(table: &latex::SymbolTable, pos: Position) -> Option<AstNodeIndex> {
- table
- .find(pos)
- .into_iter()
- .rev()
- .find(|node| table.as_command(*node).is_some())
-}
diff --git a/support/texlab/src/completion/latex/component.rs b/support/texlab/src/completion/latex/component.rs
deleted file mode 100644
index 8cf9f494a4..0000000000
--- a/support/texlab/src/completion/latex/component.rs
+++ /dev/null
@@ -1,351 +0,0 @@
-use super::combinators;
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
-};
-
-pub async fn complete_latex_component_commands<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- combinators::command(req, |cmd_node| async move {
- let table = req.current().content.as_latex().unwrap();
- let cmd = table.as_command(cmd_node).unwrap();
- let range = cmd.short_name_range();
-
- for comp in req.view.components() {
- for cmd in &comp.commands {
- items.push(Item::new(
- range,
- ItemData::ComponentCommand {
- name: &cmd.name,
- image: cmd.image.as_deref(),
- glyph: cmd.glyph.as_deref(),
- file_names: &comp.file_names,
- },
- ));
- }
- }
- })
- .await;
-}
-
-pub async fn complete_latex_component_environments<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- combinators::environment(req, |ctx| async move {
- for comp in req.view.components() {
- for env in &comp.environments {
- items.push(Item::new(
- ctx.range,
- ItemData::ComponentEnvironment {
- name: env,
- file_names: &comp.file_names,
- },
- ));
- }
- }
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document_command() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_command() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_latex_document_environment() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_environment() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn command_start() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\use"#)
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn command_end() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\use"#)
- .main("main.tex")
- .position(0, 4)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 1, 0, 4));
- }
-
- #[tokio::test]
- async fn command_word() {
- let req = FeatureTester::new()
- .file("main.tex", r#"use"#)
- .main("main.tex")
- .position(0, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn command_package() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \usepackage{lipsum}
- \lips
- "#
- ),
- )
- .main("main.tex")
- .position(1, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items
- .iter()
- .any(|item| item.data.label() == "lipsum"));
- }
-
- #[tokio::test]
- async fn command_package_comma_separated() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \usepackage{geometry, lipsum}
- \lips
- "#
- ),
- )
- .main("main.tex")
- .position(1, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items
- .iter()
- .any(|item| item.data.label() == "lipsum"));
- }
-
- #[tokio::test]
- async fn command_class() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \chap
- "#
- ),
- )
- .main("main.tex")
- .position(1, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_commands(&req, &mut actual_items).await;
-
- assert!(actual_items
- .iter()
- .any(|item| item.data.label() == "chapter"));
- }
-
- #[tokio::test]
- async fn environment_inside_of_empty_begin() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\begin{}"#)
- .main("main.tex")
- .position(0, 7)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 7, 0, 7));
- }
-
- #[tokio::test]
- async fn environment_inside_of_non_empty_end() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\end{foo}"#)
- .main("main.tex")
- .position(0, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 5, 0, 8));
- }
-
- #[tokio::test]
- async fn environment_outside_of_empty_begin() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\begin{}"#)
- .main("main.tex")
- .position(0, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn environment_outside_of_empty_end() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\end{}"#)
- .main("main.tex")
- .position(0, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn environment_inside_of_other_command() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\foo{bar}"#)
- .main("main.tex")
- .position(0, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn environment_inside_second_argument() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\begin{foo}{bar}"#)
- .main("main.tex")
- .position(0, 14)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn environment_unterminated() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\begin{foo"#)
- .main("main.tex")
- .position(0, 7)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_component_environments(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- assert_eq!(actual_items[0].range, Range::new_simple(0, 7, 0, 10));
- }
-}
diff --git a/support/texlab/src/completion/latex/glossary.rs b/support/texlab/src/completion/latex/glossary.rs
deleted file mode 100644
index 417152dd21..0000000000
--- a/support/texlab/src/completion/latex/glossary.rs
+++ /dev/null
@@ -1,114 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
- syntax::{
- LatexGlossaryEntryKind::{Acronym, General},
- LANGUAGE_DATA,
- },
- workspace::DocumentContent,
-};
-
-pub async fn complete_latex_glossary_entries<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let parameters = LANGUAGE_DATA
- .glossary_entry_reference_commands
- .iter()
- .map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument(req, parameters, |ctx| async move {
- let cmd_kind = LANGUAGE_DATA
- .glossary_entry_reference_commands
- .iter()
- .find(|cmd| &cmd.name[1..] == ctx.parameter.name)
- .unwrap()
- .kind;
-
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- for entry in &table.glossary_entries {
- match (cmd_kind, entry.kind) {
- (Acronym, Acronym) | (General, General) | (General, Acronym) => {
- let name = entry.label(&table).text();
- let item = Item::new(ctx.range, ItemData::GlossaryEntry { name });
- items.push(item);
- }
- (Acronym, General) => {}
- }
- }
- }
- }
- })
- .await
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_glossary_entries(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_glossary_entries(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn acronym() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \newacronym{lvm}{LVM}{Logical Volume Manager}
- \acrfull{foo}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 9)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_glossary_entries(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- assert_eq!(actual_items[0].data.label(), "lvm");
- assert_eq!(actual_items[0].range, Range::new_simple(1, 9, 1, 12));
- }
-}
diff --git a/support/texlab/src/completion/latex/import.rs b/support/texlab/src/completion/latex/import.rs
deleted file mode 100644
index 06c28e189b..0000000000
--- a/support/texlab/src/completion/latex/import.rs
+++ /dev/null
@@ -1,188 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- components::COMPONENT_DATABASE,
- feature::FeatureRequest,
- protocol::CompletionParams,
- syntax::{LatexIncludeKind, LANGUAGE_DATA},
-};
-use std::{borrow::Cow, collections::HashSet};
-
-pub async fn complete_latex_classes<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- complete_latex_imports(req, items, LatexIncludeKind::Class, |name| {
- ItemData::Class { name }
- })
- .await;
-}
-
-pub async fn complete_latex_packages<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- complete_latex_imports(req, items, LatexIncludeKind::Package, |name| {
- ItemData::Package { name }
- })
- .await;
-}
-
-async fn complete_latex_imports<'a, F>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
- kind: LatexIncludeKind,
- mut factory: F,
-) where
- F: FnMut(Cow<'a, str>) -> ItemData<'a>,
-{
- let extension = if kind == LatexIncludeKind::Package {
- "sty"
- } else {
- "cls"
- };
-
- let parameters = LANGUAGE_DATA
- .include_commands
- .iter()
- .filter(|cmd| cmd.kind == kind)
- .map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument(req, parameters, |ctx| async move {
- let resolver = req.distro.resolver().await;
- let mut file_names = HashSet::new();
- COMPONENT_DATABASE
- .components
- .iter()
- .flat_map(|comp| comp.file_names.iter())
- .filter(|file_name| file_name.ends_with(extension))
- .for_each(|file_name| {
- file_names.insert(file_name);
- let stem = &file_name[0..file_name.len() - 4];
- let data = factory(stem.into());
- let item = Item::new(ctx.range, data);
- items.push(item);
- });
-
- resolver
- .files_by_name
- .keys()
- .filter(|file_name| file_name.ends_with(extension) && !file_names.contains(file_name))
- .for_each(|file_name| {
- let stem = &file_name[0..file_name.len() - 4];
- let data = factory(stem.to_owned().into());
- let item = Item::new(ctx.range, data);
- items.push(item);
- });
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
-
- #[tokio::test]
- async fn empty_latex_document_class() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_classes(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_class() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_classes(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_latex_document_package() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_packages(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_package() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_packages(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn class() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\documentclass{}"#)
- .main("main.tex")
- .position(0, 15)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_classes(&req, &mut actual_items).await;
-
- assert!(actual_items
- .iter()
- .any(|item| item.data.label() == "beamer"));
- assert!(actual_items
- .iter()
- .all(|item| item.data.label() != "amsmath"));
- }
-
- #[tokio::test]
- async fn package() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\usepackage{}"#)
- .main("main.tex")
- .position(0, 12)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_packages(&req, &mut actual_items).await;
-
- assert!(actual_items
- .iter()
- .all(|item| item.data.label() != "beamer"));
- assert!(actual_items
- .iter()
- .any(|item| item.data.label() == "amsmath"));
- }
-}
diff --git a/support/texlab/src/completion/latex/include.rs b/support/texlab/src/completion/latex/include.rs
deleted file mode 100644
index 1a8555d07c..0000000000
--- a/support/texlab/src/completion/latex/include.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::{CompletionParams, Range, RangeExt},
- syntax::{latex, AstNodeIndex, SyntaxNode, LANGUAGE_DATA},
-};
-use std::path::{Path, PathBuf};
-use tokio::fs;
-
-pub async fn complete_latex_includes<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let parameters = LANGUAGE_DATA.include_commands.iter().map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument_word(req, parameters, |cmd_node, index| async move {
- if !req.current().is_file() {
- return;
- }
-
- make_items(req, items, cmd_node, index).await;
- })
- .await;
-}
-
-async fn make_items<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
- cmd_node: AstNodeIndex,
- index: usize,
-) -> Option<()> {
- let table = req.current().content.as_latex()?;
- let pos = req.params.text_document_position.position;
- let path_word = table.extract_word(cmd_node, latex::GroupKind::Group, index);
- let name_range = match path_word {
- Some(path_word) => Range::new_simple(
- path_word.start().line,
- path_word.end().character - path_word.text().split('/').last()?.chars().count() as u64,
- path_word.end().line,
- path_word.end().character,
- ),
- None => Range::new(pos, pos),
- };
-
- let cmd = table.as_command(cmd_node)?;
- let current_dir = current_dir(req, table, cmd_node)?;
- let mut entries = fs::read_dir(current_dir).await.ok()?;
- while let Some(entry) = entries.next_entry().await.ok()? {
- let mut path = entry.path();
-
- let file_type = entry.file_type().await.ok()?;
- if file_type.is_file() && is_included(&cmd, &path) {
- let include_extension = LANGUAGE_DATA
- .include_commands
- .iter()
- .find(|c| cmd.name.text() == c.name)?
- .include_extension;
-
- if !include_extension {
- remove_extension(&mut path);
- }
- let name = path.file_name().unwrap().to_string_lossy().into_owned();
- let item = Item::new(name_range, ItemData::File { name });
- items.push(item);
- } else if file_type.is_dir() {
- let name = path.file_name().unwrap().to_string_lossy().into_owned();
- let item = Item::new(name_range, ItemData::Directory { name });
- items.push(item);
- }
- }
- Some(())
-}
-
-fn current_dir(
- req: &FeatureRequest<CompletionParams>,
- table: &latex::SymbolTable,
- cmd_node: AstNodeIndex,
-) -> Option<PathBuf> {
- let mut path = req
- .options
- .latex
- .as_ref()
- .and_then(|latex| latex.root_directory.as_ref())
- .map_or_else(
- || {
- let mut path = req.current().uri.to_file_path().unwrap();
- path.pop();
- path
- },
- Clone::clone,
- );
-
- path = PathBuf::from(path.to_str()?.replace('\\', "/"));
- if let Some(include) = table.extract_word(cmd_node, latex::GroupKind::Group, 0) {
- path.push(include.text());
- if !include.text().ends_with('/') {
- path.pop();
- }
- }
- Some(path)
-}
-
-fn is_included(cmd: &latex::Command, file: &Path) -> bool {
- if let Some(allowed_extensions) = LANGUAGE_DATA
- .include_commands
- .iter()
- .find(|c| c.name == cmd.name.text())
- .and_then(|c| c.kind.extensions())
- {
- file.extension()
- .and_then(|ext| ext.to_str())
- .map(|ext| ext.to_lowercase())
- .map(|ext| allowed_extensions.contains(&ext.as_str()))
- .unwrap_or_default()
- } else {
- true
- }
-}
-
-fn remove_extension(path: &mut PathBuf) {
- if let Some(stem) = path
- .file_stem()
- .and_then(|stem| stem.to_str())
- .map(ToOwned::to_owned)
- {
- path.pop();
- path.push(stem);
- }
-}
diff --git a/support/texlab/src/completion/latex/label.rs b/support/texlab/src/completion/latex/label.rs
deleted file mode 100644
index 91aa80e532..0000000000
--- a/support/texlab/src/completion/latex/label.rs
+++ /dev/null
@@ -1,230 +0,0 @@
-use super::combinators::{self, ArgumentContext, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::{DocumentView, FeatureRequest},
- outline::{Outline, OutlineContext, OutlineContextItem},
- protocol::{CompletionParams, RangeExt},
- syntax::{
- latex, LatexLabelKind, LatexLabelReferenceSource, Structure, SyntaxNode, LANGUAGE_DATA,
- },
- workspace::DocumentContent,
-};
-use std::sync::Arc;
-
-pub async fn complete_latex_labels<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let parameters = LANGUAGE_DATA
- .label_commands
- .iter()
- .filter(|cmd| cmd.kind.is_reference())
- .map(|cmd| Parameter {
- name: &cmd.name[1..],
- index: cmd.index,
- });
-
- combinators::argument(req, parameters, |ctx| async move {
- let source = find_source(ctx);
- for doc in req.related() {
- let snapshot = Arc::clone(&req.view.snapshot);
- let view =
- DocumentView::analyze(snapshot, Arc::clone(&doc), &req.options, &req.current_dir);
- let outline = Outline::analyze(&view, &req.options, &req.current_dir);
-
- if let DocumentContent::Latex(table) = &doc.content {
- for label in table
- .labels
- .iter()
- .filter(|label| label.kind == LatexLabelKind::Definition)
- .filter(|label| is_included(&table, label, source))
- {
- let outline_ctx = OutlineContext::parse(&view, &outline, *label);
-
- let kind = match outline_ctx.as_ref().map(|ctx| &ctx.item) {
- Some(OutlineContextItem::Section { .. }) => Structure::Section,
- Some(OutlineContextItem::Caption { .. }) => Structure::Float,
- Some(OutlineContextItem::Theorem { .. }) => Structure::Theorem,
- Some(OutlineContextItem::Equation) => Structure::Equation,
- Some(OutlineContextItem::Item) => Structure::Item,
- None => Structure::Label,
- };
-
- for name in label.names(&table) {
- let header = outline_ctx.as_ref().and_then(|ctx| ctx.detail());
- let footer = outline_ctx.as_ref().and_then(|ctx| match &ctx.item {
- OutlineContextItem::Caption { text, .. } => Some(text.clone()),
- _ => None,
- });
-
- let text = outline_ctx
- .as_ref()
- .map(|ctx| format!("{} {}", name.text(), ctx.reference()))
- .unwrap_or_else(|| name.text().into());
-
- let item = Item::new(
- ctx.range,
- ItemData::Label {
- name: name.text(),
- kind,
- header,
- footer,
- text,
- },
- );
- items.push(item);
- }
- }
- }
- }
- })
- .await;
-}
-
-fn find_source(ctx: ArgumentContext) -> LatexLabelReferenceSource {
- match LANGUAGE_DATA
- .label_commands
- .iter()
- .find(|cmd| &cmd.name[1..] == ctx.parameter.name && cmd.index == ctx.parameter.index)
- .map(|cmd| cmd.kind)
- .unwrap()
- {
- LatexLabelKind::Definition => unreachable!(),
- LatexLabelKind::Reference(source) => source,
- }
-}
-
-fn is_included(
- table: &latex::SymbolTable,
- label: &latex::Label,
- source: LatexLabelReferenceSource,
-) -> bool {
- let label_range = table[label.parent].range();
- match source {
- LatexLabelReferenceSource::Everything => true,
- LatexLabelReferenceSource::Math => table
- .environments
- .iter()
- .filter(|env| env.left.is_math(&table))
- .any(|env| env.range(&table).contains_exclusive(label_range.start)),
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_labels(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_labels(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_of_ref() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \addbibresource{bar.bib}
- \include{baz}
- \ref{}
- "#
- ),
- )
- .file("bar.bib", "")
- .file("baz.tex", r#"\label{foo}\label{bar}\ref{baz}"#)
- .main("foo.tex")
- .position(2, 5)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_labels(&req, &mut actual_items).await;
-
- let actual_labels: Vec<_> = actual_items
- .into_iter()
- .map(|item| item.data.label().to_owned())
- .collect();
- assert_eq!(actual_labels, vec!["foo", "bar"]);
- }
-
- #[tokio::test]
- async fn outside_of_ref() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \include{bar}
- \ref{}
- "#
- ),
- )
- .file("bar.tex", r#"\label{foo}\label{bar}"#)
- .main("foo.tex")
- .position(1, 6)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_labels(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn eqref() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{align}\label{foo}\end{align}\label{bar}
- \eqref{}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 7)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_labels(&req, &mut actual_items).await;
-
- let actual_labels: Vec<_> = actual_items
- .into_iter()
- .map(|item| item.data.label().to_owned())
- .collect();
-
- assert_eq!(actual_labels, vec!["foo"]);
- }
-}
diff --git a/support/texlab/src/completion/latex/mod.rs b/support/texlab/src/completion/latex/mod.rs
deleted file mode 100644
index 519d00e5f7..0000000000
--- a/support/texlab/src/completion/latex/mod.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-pub mod argument;
-pub mod begin_cmd;
-pub mod citation;
-pub mod color;
-pub mod color_model;
-mod combinators;
-pub mod component;
-pub mod glossary;
-pub mod import;
-pub mod include;
-pub mod label;
-pub mod theorem;
-pub mod tikz_lib;
-pub mod user;
diff --git a/support/texlab/src/completion/latex/theorem.rs b/support/texlab/src/completion/latex/theorem.rs
deleted file mode 100644
index a8706bed0b..0000000000
--- a/support/texlab/src/completion/latex/theorem.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use super::combinators;
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
-};
-
-pub async fn complete_latex_theorem_environments<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- combinators::environment(req, |ctx| async move {
- for table in req
- .related()
- .into_iter()
- .filter_map(|doc| doc.content.as_latex())
- {
- for theorem in &table.theorem_definitions {
- let name = theorem.name(&table).text();
- let data = ItemData::UserEnvironment { name };
- let item = Item::new(ctx.range, data);
- items.push(item);
- }
- }
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_theorem_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_theorem_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn inside_begin() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \newtheorem{theorem}{Theorem}
- \begin{th}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 8)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_theorem_environments(&req, &mut actual_items).await;
-
- assert_eq!(actual_items.len(), 1);
- assert_eq!(actual_items[0].data.label(), "theorem");
- assert_eq!(actual_items[0].range, Range::new_simple(1, 7, 1, 9));
- }
-
- #[tokio::test]
- async fn outside_begin() {
- let req = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \newtheorem{theorem}{Theorem}
- \begin{th}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 10)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_theorem_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/latex/tikz_lib.rs b/support/texlab/src/completion/latex/tikz_lib.rs
deleted file mode 100644
index fb51fd7229..0000000000
--- a/support/texlab/src/completion/latex/tikz_lib.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-use super::combinators::{self, Parameter};
-use crate::{
- completion::types::{Item, ItemData},
- feature::FeatureRequest,
- protocol::CompletionParams,
- syntax::LANGUAGE_DATA,
-};
-use std::iter;
-
-pub async fn complete_latex_pgf_libraries<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let param = Parameter {
- name: "usepgflibrary",
- index: 0,
- };
- combinators::argument(req, iter::once(param), |ctx| async move {
- for name in &LANGUAGE_DATA.pgf_libraries {
- let item = Item::new(ctx.range, ItemData::PgfLibrary { name });
- items.push(item);
- }
- })
- .await;
-}
-
-pub async fn complete_latex_tikz_libraries<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- let param = Parameter {
- name: "usetikzlibrary",
- index: 0,
- };
- combinators::argument(req, iter::once(param), |ctx| async move {
- for name in &LANGUAGE_DATA.tikz_libraries {
- let item = Item::new(ctx.range, ItemData::TikzLibrary { name });
- items.push(item);
- }
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
-
- #[tokio::test]
- async fn empty_latex_document_pgf() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_pgf_libraries(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_pgf() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_pgf_libraries(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_latex_document_tikz() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_tikz_libraries(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_tikz() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_tikz_libraries(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn pgf_library() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\usepgflibrary{}"#)
- .main("main.tex")
- .position(0, 15)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_pgf_libraries(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn tikz_library() {
- let req = FeatureTester::new()
- .file("main.tex", r#"\usetikzlibrary{}"#)
- .main("main.tex")
- .position(0, 16)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_tikz_libraries(&req, &mut actual_items).await;
-
- assert!(!actual_items.is_empty());
- }
-}
diff --git a/support/texlab/src/completion/latex/user.rs b/support/texlab/src/completion/latex/user.rs
deleted file mode 100644
index 0a5706958a..0000000000
--- a/support/texlab/src/completion/latex/user.rs
+++ /dev/null
@@ -1,204 +0,0 @@
-use super::combinators;
-use crate::{
- completion::{Item, ItemData},
- feature::FeatureRequest,
- protocol::{CompletionParams, Range},
- syntax::latex,
- workspace::DocumentContent,
-};
-
-pub async fn complete_latex_user_commands<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- combinators::command(req, |current_cmd_node| async move {
- let current_cmd = req
- .current()
- .content
- .as_latex()
- .unwrap()
- .as_command(current_cmd_node)
- .unwrap();
-
- for table in req
- .related()
- .into_iter()
- .flat_map(|doc| doc.content.as_latex())
- {
- table
- .commands
- .iter()
- .filter(|cmd_node| **cmd_node != current_cmd_node)
- .map(|cmd_node| {
- let name = &table.as_command(*cmd_node).unwrap().name.text()[1..];
- Item::new(
- current_cmd.short_name_range(),
- ItemData::UserCommand { name },
- )
- })
- .for_each(|item| items.push(item));
- }
- })
- .await;
-}
-
-pub async fn complete_latex_user_environments<'a>(
- req: &'a FeatureRequest<CompletionParams>,
- items: &mut Vec<Item<'a>>,
-) {
- fn make_item(
- table: &latex::SymbolTable,
- delim: latex::EnvironmentDelimiter,
- name_range: Range,
- ) -> Option<Item> {
- delim
- .name(&table)
- .map(|name| Item::new(name_range, ItemData::UserEnvironment { name: &name.text() }))
- }
-
- combinators::environment(req, |ctx| async move {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- for env in &table.environments {
- if (env.left.parent == ctx.node || env.right.parent == ctx.node)
- && doc.uri == req.current().uri
- {
- continue;
- }
-
- if let Some(item) = make_item(&table, env.left, ctx.range) {
- items.push(item);
- }
-
- if let Some(item) = make_item(&table, env.right, ctx.range) {
- items.push(item);
- }
- }
- }
- }
- })
- .await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
- use itertools::Itertools;
-
- #[tokio::test]
- async fn empty_latex_document_command() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_user_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_command() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_user_commands(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_latex_document_environment() {
- let req = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_user_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_environment() {
- let req = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
- complete_latex_user_environments(&req, &mut actual_items).await;
-
- assert!(actual_items.is_empty());
- }
-
- #[tokio::test]
- async fn command() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \include{bar}
- \foo
- "#
- ),
- )
- .file("bar.tex", r#"\bar"#)
- .file("baz.tex", r#"\baz"#)
- .main("foo.tex")
- .position(1, 2)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_user_commands(&req, &mut actual_items).await;
-
- let actual_labels: Vec<_> = actual_items
- .into_iter()
- .map(|item| item.data.label().to_owned())
- .collect();
- assert_eq!(actual_labels, vec!["include", "bar"]);
- }
-
- #[tokio::test]
- async fn environment() {
- let req = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \include{bar}
- \begin{foo}
- "#
- ),
- )
- .file("bar.tex", r#"\begin{bar}\end{bar}"#)
- .file("baz.tex", r#"\begin{baz}\end{baz}"#)
- .main("foo.tex")
- .position(1, 9)
- .test_completion_request()
- .await;
- let mut actual_items = Vec::new();
-
- complete_latex_user_environments(&req, &mut actual_items).await;
-
- let actual_labels: Vec<_> = actual_items
- .into_iter()
- .map(|item| item.data.label().to_owned())
- .unique()
- .collect();
- assert_eq!(actual_labels, vec!["bar"]);
- }
-}
diff --git a/support/texlab/src/completion/mod.rs b/support/texlab/src/completion/mod.rs
deleted file mode 100644
index d354ed1d98..0000000000
--- a/support/texlab/src/completion/mod.rs
+++ /dev/null
@@ -1,419 +0,0 @@
-mod bibtex;
-mod latex;
-mod types;
-mod util;
-
-pub use self::types::{CompletionItemData, Item, ItemData};
-
-use self::{
- bibtex::{
- cmd::complete_bibtex_commands, entry_type::complete_bibtex_entry_types,
- field_name::complete_bibtex_fields,
- },
- latex::{
- argument::complete_latex_arguments,
- begin_cmd::complete_latex_begin_command,
- citation::complete_latex_citations,
- color::complete_latex_colors,
- color_model::complete_latex_color_models,
- component::{complete_latex_component_commands, complete_latex_component_environments},
- glossary::complete_latex_glossary_entries,
- import::{complete_latex_classes, complete_latex_packages},
- include::complete_latex_includes,
- label::complete_latex_labels,
- theorem::complete_latex_theorem_environments,
- tikz_lib::{complete_latex_pgf_libraries, complete_latex_tikz_libraries},
- user::{complete_latex_user_commands, complete_latex_user_environments},
- },
- util::{adjust_kind, component_detail, current_word, image_documentation},
-};
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- CompletionItem, CompletionParams, CompletionTextEdit, Documentation, InsertTextFormat,
- MarkupContent, MarkupKind, RangeExt, TextEdit,
- },
- syntax::{self, Structure, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use fuzzy_matcher::FuzzyMatcher;
-use fuzzy_matcher::skim::SkimMatcherV2;
-use std::collections::HashSet;
-
-pub const COMPLETION_LIMIT: usize = 50;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct CompletionProvider;
-
-impl CompletionProvider {
- pub fn new() -> Self {
- Self
- }
-}
-
-#[async_trait]
-impl FeatureProvider for CompletionProvider {
- type Params = CompletionParams;
- type Output = Vec<CompletionItem>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let items = complete_all(req).await;
- let mut items = dedup(items);
- preselect(req, &mut items);
- score(req, &mut items);
-
- items.sort_by_key(|item| (!item.preselect, -item.score.unwrap_or(std::i64::MIN + 1)));
- items
- .into_iter()
- .take(COMPLETION_LIMIT)
- .filter(|item| item.score.is_some())
- .map(|item| convert(req, item))
- .enumerate()
- .map(|(i, item)| append_sort_text(item, i))
- .collect()
- }
-}
-
-async fn complete_all<'a>(req: &'a FeatureRequest<CompletionParams>) -> Vec<Item<'a>> {
- let mut items = Vec::new();
- complete_bibtex_commands(req, &mut items).await;
- complete_bibtex_entry_types(req, &mut items).await;
- complete_bibtex_fields(req, &mut items).await;
- complete_latex_arguments(req, &mut items).await;
- complete_latex_begin_command(req, &mut items).await;
- complete_latex_colors(req, &mut items).await;
- complete_latex_color_models(req, &mut items).await;
- complete_latex_glossary_entries(req, &mut items).await;
- complete_latex_citations(req, &mut items).await;
- complete_latex_classes(req, &mut items).await;
- complete_latex_packages(req, &mut items).await;
- complete_latex_includes(req, &mut items).await;
- complete_latex_labels(req, &mut items).await;
- complete_latex_pgf_libraries(req, &mut items).await;
- complete_latex_tikz_libraries(req, &mut items).await;
- complete_latex_component_environments(req, &mut items).await;
- complete_latex_theorem_environments(req, &mut items).await;
- complete_latex_user_environments(req, &mut items).await;
- complete_latex_component_commands(req, &mut items).await;
- complete_latex_user_commands(req, &mut items).await;
- items
-}
-
-fn dedup<'a>(items: Vec<Item<'a>>) -> Vec<Item<'a>> {
- let mut labels = HashSet::new();
- let mut insert = vec![false; items.len()];
- for (i, item) in items.iter().enumerate() {
- insert[i] = labels.insert(item.data.label());
- }
- items
- .into_iter()
- .enumerate()
- .filter(|(i, _)| insert[*i])
- .map(|(_, item)| item)
- .collect()
-}
-
-fn preselect(req: &FeatureRequest<CompletionParams>, items: &mut [Item]) {
- let pos = req.params.text_document_position.position;
- if let DocumentContent::Latex(table) = &req.current().content {
- for env in &table.environments {
- if let Some(name) = env.left.name(&table) {
- let right_args = table
- .extract_group(env.right.parent, syntax::latex::GroupKind::Group, 0)
- .unwrap();
- let right_args_range = table[right_args].range();
- let cond1 = right_args_range.contains_exclusive(pos);
- let cond2 = table
- .as_group(right_args)
- .and_then(|group| group.right.as_ref())
- .is_none()
- && right_args_range.contains(pos);
-
- if cond1 || cond2 {
- for symbol in items.iter_mut() {
- if symbol.data.label() == name.text() {
- symbol.preselect = true;
- break;
- }
- }
- }
- }
- }
- }
-}
-
-fn score(req: &FeatureRequest<CompletionParams>, items: &mut Vec<Item>) {
- let current_word = current_word(req);
- let pattern = current_word.as_deref().unwrap_or_default();
- let matcher = SkimMatcherV2::default();
- for item in items {
- item.score = match &item.data {
- ItemData::ComponentCommand { name, .. } => matcher.fuzzy_match(name, pattern),
- ItemData::ComponentEnvironment { name, .. } => matcher.fuzzy_match(name, pattern),
- ItemData::UserCommand { name } => matcher.fuzzy_match(name, pattern),
- ItemData::UserEnvironment { name } => matcher.fuzzy_match(name, pattern),
- ItemData::Label { text, .. } => matcher.fuzzy_match(&text, pattern),
- ItemData::Class { name } => matcher.fuzzy_match(&name, pattern),
- ItemData::Package { name } => matcher.fuzzy_match(&name, pattern),
- ItemData::PgfLibrary { name } => matcher.fuzzy_match(name, pattern),
- ItemData::TikzLibrary { name } => matcher.fuzzy_match(name, pattern),
- ItemData::File { name } => matcher.fuzzy_match(name, pattern),
- ItemData::Directory { name } => matcher.fuzzy_match(name, pattern),
- ItemData::Citation { text, .. } => matcher.fuzzy_match(&text, pattern),
- ItemData::Argument { name, .. } => matcher.fuzzy_match(&name, pattern),
- ItemData::BeginCommand => matcher.fuzzy_match("begin", pattern),
- ItemData::Color { name } => matcher.fuzzy_match(name, pattern),
- ItemData::ColorModel { name } => matcher.fuzzy_match(name, pattern),
- ItemData::GlossaryEntry { name } => matcher.fuzzy_match(name, pattern),
- ItemData::EntryType { ty } => matcher.fuzzy_match(&ty.name, pattern),
- ItemData::Field { field } => matcher.fuzzy_match(&field.name, pattern),
- };
- }
-}
-
-fn convert(req: &FeatureRequest<CompletionParams>, item: Item) -> CompletionItem {
- let mut new_item = match item.data {
- ItemData::ComponentCommand {
- name,
- image,
- glyph,
- file_names,
- } => {
- let detail = glyph.map_or_else(
- || component_detail(file_names),
- |glyph| format!("{}, {}", glyph, component_detail(file_names)),
- );
- let documentation = image.and_then(|img| image_documentation(&req, &name, img));
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- kind: Some(adjust_kind(req, Structure::Command.completion_kind())),
- data: Some(CompletionItemData::Command.into()),
- documentation,
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::new_simple(name.into(), detail)
- }
- }
- ItemData::ComponentEnvironment { name, file_names } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- kind: Some(adjust_kind(req, Structure::Environment.completion_kind())),
- data: Some(CompletionItemData::Environment.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::new_simple(name.into(), component_detail(file_names))
- }
- }
- ItemData::UserCommand { name } => {
- let detail = "user-defined".into();
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- kind: Some(adjust_kind(req, Structure::Command.completion_kind())),
- data: Some(CompletionItemData::Command.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::new_simple(name.into(), detail)
- }
- }
- ItemData::UserEnvironment { name } => {
- let detail = "user-defined".into();
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- kind: Some(adjust_kind(req, Structure::Environment.completion_kind())),
- data: Some(CompletionItemData::Environment.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::new_simple(name.into(), detail)
- }
- }
- ItemData::Label {
- name,
- kind,
- header,
- footer,
- text,
- } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, kind.completion_kind())),
- data: Some(CompletionItemData::Label.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- filter_text: Some(text.clone()),
- sort_text: Some(text),
- detail: header,
- documentation: footer.map(Documentation::String),
- ..CompletionItem::default()
- }
- }
- ItemData::Class { name } => {
- let text_edit = TextEdit::new(item.range, name.as_ref().into());
- CompletionItem {
- label: name.into_owned(),
- kind: Some(adjust_kind(req, Structure::Class.completion_kind())),
- data: Some(CompletionItemData::Class.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::Package { name } => {
- let text_edit = TextEdit::new(item.range, name.as_ref().into());
- CompletionItem {
- label: name.into_owned(),
- kind: Some(adjust_kind(req, Structure::Package.completion_kind())),
- data: Some(CompletionItemData::Package.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::PgfLibrary { name } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, Structure::PgfLibrary.completion_kind())),
- data: Some(CompletionItemData::PgfLibrary.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::TikzLibrary { name } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, Structure::TikzLibrary.completion_kind())),
- data: Some(CompletionItemData::TikzLibrary.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::File { name } => {
- let text_edit = TextEdit::new(item.range, name.clone());
- CompletionItem {
- label: name,
- kind: Some(adjust_kind(req, Structure::File.completion_kind())),
- data: Some(CompletionItemData::File.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::Directory { name } => {
- let text_edit = TextEdit::new(item.range, name.clone());
- CompletionItem {
- label: name,
- kind: Some(adjust_kind(req, Structure::Folder.completion_kind())),
- data: Some(CompletionItemData::Folder.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::Citation { uri, key, text, ty } => {
- let text_edit = TextEdit::new(item.range, key.into());
- CompletionItem {
- label: key.into(),
- kind: Some(adjust_kind(req, ty.completion_kind())),
- filter_text: Some(text.clone()),
- sort_text: Some(text),
- data: Some(
- CompletionItemData::Citation {
- uri: uri.clone(),
- key: key.into(),
- }
- .into(),
- ),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::Argument { name, image } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, Structure::Argument.completion_kind())),
- data: Some(CompletionItemData::Argument.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- documentation: image.and_then(|image| image_documentation(&req, &name, image)),
- ..CompletionItem::default()
- }
- }
- ItemData::BeginCommand => CompletionItem {
- kind: Some(adjust_kind(req, Structure::Snippet.completion_kind())),
- data: Some(CompletionItemData::CommandSnippet.into()),
- insert_text: Some("begin{$1}\n\t$0\n\\end{$1}".into()),
- insert_text_format: Some(InsertTextFormat::Snippet),
- ..CompletionItem::new_simple("begin".into(), component_detail(&[]))
- },
- ItemData::Color { name } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, Structure::Color.completion_kind())),
- data: Some(CompletionItemData::Color.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::ColorModel { name } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, Structure::ColorModel.completion_kind())),
- data: Some(CompletionItemData::ColorModel.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::GlossaryEntry { name } => {
- let text_edit = TextEdit::new(item.range, name.into());
- CompletionItem {
- label: name.into(),
- kind: Some(adjust_kind(req, Structure::GlossaryEntry.completion_kind())),
- data: Some(CompletionItemData::GlossaryEntry.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- ..CompletionItem::default()
- }
- }
- ItemData::EntryType { ty } => {
- let text_edit = TextEdit::new(item.range, (&ty.name).into());
- let kind = Structure::Entry(ty.category).completion_kind();
- CompletionItem {
- label: (&ty.name).into(),
- kind: Some(adjust_kind(req, kind)),
- data: Some(CompletionItemData::EntryType.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- documentation: ty.documentation.as_ref().map(|doc| {
- Documentation::MarkupContent(MarkupContent {
- kind: MarkupKind::Markdown,
- value: doc.into(),
- })
- }),
- ..CompletionItem::default()
- }
- }
- ItemData::Field { field } => {
- let text_edit = TextEdit::new(item.range, (&field.name).into());
- CompletionItem {
- label: (&field.name).into(),
- kind: Some(adjust_kind(req, Structure::Field.completion_kind())),
- data: Some(CompletionItemData::FieldName.into()),
- text_edit: Some(CompletionTextEdit::Edit(text_edit)),
- documentation: Some(Documentation::MarkupContent(MarkupContent {
- kind: MarkupKind::Markdown,
- value: (&field.documentation).into(),
- })),
- ..CompletionItem::default()
- }
- }
- };
- new_item.preselect = Some(item.preselect);
- new_item
-}
-
-fn append_sort_text(mut item: CompletionItem, index: usize) -> CompletionItem {
- let sort_prefix = format!("{:0>2}", index);
- match &item.sort_text {
- Some(sort_text) => {
- item.sort_text = Some(format!("{} {}", sort_prefix, sort_text));
- }
- None => {
- item.sort_text = Some(sort_prefix);
- }
- };
- item
-}
diff --git a/support/texlab/src/completion/util.rs b/support/texlab/src/completion/util.rs
deleted file mode 100644
index ec3c8eb406..0000000000
--- a/support/texlab/src/completion/util.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-use crate::{
- feature::FeatureRequest,
- protocol::{
- CompletionItemKind, CompletionParams, Documentation, MarkupContent, MarkupKind, Position,
- RangeExt,
- },
- syntax::{bibtex, latex, SyntaxNode},
- workspace::DocumentContent,
-};
-use std::borrow::Cow;
-
-pub fn current_word(req: &FeatureRequest<CompletionParams>) -> Option<Cow<str>> {
- let pos = req.params.text_document_position.position;
- match &req.current().content {
- DocumentContent::Latex(table) => {
- if let Some(node) = table.find_command_by_short_name_range(pos) {
- return Some(command_word(table.as_command(node).unwrap()));
- }
-
- match &table[table.find(pos).into_iter().last()?] {
- latex::Node::Root(_) | latex::Node::Group(_) => Some("".into()),
- latex::Node::Command(cmd) => Some(command_word(cmd)),
- latex::Node::Text(text) => text
- .words
- .iter()
- .find(|word| word.range().contains(pos))
- .map(|word| word.text().split('/').last().unwrap().to_owned().into()),
- latex::Node::Comma(_) => Some(",".into()),
- latex::Node::Math(math) => Some(math.token.text().to_owned().into()),
- }
- }
- DocumentContent::Bibtex(tree) => {
- fn type_query(ty: &bibtex::Token, pos: Position) -> Option<Cow<str>> {
- if ty.range().contains(pos) {
- Some((&ty.text()[1..]).into())
- } else {
- Some("".into())
- }
- }
-
- match &tree.graph[tree.find(pos).pop()?] {
- bibtex::Node::Root(_) => Some("".into()),
- bibtex::Node::Preamble(preamble) => type_query(&preamble.ty, pos),
- bibtex::Node::String(string) => type_query(&string.ty, pos),
- bibtex::Node::Entry(entry) => type_query(&entry.ty, pos),
- bibtex::Node::Comment(comment) => Some(comment.token.text().into()),
- bibtex::Node::Field(field) => {
- if field.name.range().contains(pos) {
- Some(field.name.text().into())
- } else {
- Some("".into())
- }
- }
- bibtex::Node::Word(word) => Some(word.token.text().into()),
- bibtex::Node::Command(cmd) => Some((&cmd.token.text()[1..]).into()),
- bibtex::Node::QuotedContent(_)
- | bibtex::Node::BracedContent(_)
- | bibtex::Node::Concat(_) => Some("".into()),
- }
- }
- }
-}
-
-fn command_word(cmd: &latex::Command) -> Cow<str> {
- cmd.name.text()[1..].into()
-}
-
-pub fn component_detail(file_names: &[String]) -> String {
- if file_names.is_empty() {
- "built-in".to_owned()
- } else {
- file_names.join(", ")
- }
-}
-
-pub fn image_documentation(
- req: &FeatureRequest<CompletionParams>,
- name: &str,
- image: &str,
-) -> Option<Documentation> {
- if supports_images(req) {
- Some(Documentation::MarkupContent(MarkupContent {
- kind: MarkupKind::Markdown,
- value: format!(
- "![{}](data:image/png;base64,{}|width=48,height=48)",
- name, image
- ),
- }))
- } else {
- None
- }
-}
-
-fn supports_images(req: &FeatureRequest<CompletionParams>) -> bool {
- req.client_capabilities
- .text_document
- .as_ref()
- .and_then(|cap| cap.completion.as_ref())
- .and_then(|cap| cap.completion_item.as_ref())
- .and_then(|cap| cap.documentation_format.as_ref())
- .map_or(true, |formats| formats.contains(&MarkupKind::Markdown))
-}
-
-pub fn adjust_kind(
- req: &FeatureRequest<CompletionParams>,
- kind: CompletionItemKind,
-) -> CompletionItemKind {
- if let Some(value_set) = req
- .client_capabilities
- .text_document
- .as_ref()
- .and_then(|cap| cap.completion.as_ref())
- .and_then(|cap| cap.completion_item_kind.as_ref())
- .and_then(|cap| cap.value_set.as_ref())
- {
- if value_set.contains(&kind) {
- return kind;
- }
- }
- CompletionItemKind::Text
-}
diff --git a/support/texlab/src/components.rs b/support/texlab/src/component_db.rs
index 76890c8b15..a0c728a7ae 100644
--- a/support/texlab/src/components.rs
+++ b/support/texlab/src/component_db.rs
@@ -1,15 +1,19 @@
-use crate::protocol::{MarkupContent, MarkupKind};
+use itertools::Itertools;
+use lsp_types::{MarkupContent, MarkupKind};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
+use smol_str::SmolStr;
+
+use crate::WorkspaceSubset;
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct Database {
+pub struct ComponentDatabase {
pub components: Vec<Component>,
- pub metadata: Vec<Metadata>,
+ pub metadata: Vec<ComponentMetadata>,
}
-impl Database {
+impl ComponentDatabase {
pub fn find(&self, name: &str) -> Option<&Component> {
self.components.iter().find(|component| {
component
@@ -19,6 +23,44 @@ impl Database {
})
}
+ pub fn find_no_ext(&self, name: &str) -> Option<&Component> {
+ self.components.iter().find(|component| {
+ component
+ .file_names
+ .iter()
+ .any(|file_name| &file_name[0..file_name.len() - 4] == name)
+ })
+ }
+
+ pub fn linked_components<'a>(&self, subset: &WorkspaceSubset) -> Vec<&Component> {
+ let mut start_components = vec![self.kernel()];
+ for document in &subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ data.extras
+ .explicit_links
+ .iter()
+ .filter_map(|link| link.as_component_name())
+ .filter_map(|name| self.find(&name))
+ .for_each(|component| start_components.push(component));
+ }
+ }
+
+ let mut all_components = Vec::new();
+ for component in start_components {
+ all_components.push(component);
+ component
+ .references
+ .iter()
+ .flat_map(|file| self.find(&file))
+ .for_each(|component| all_components.push(component))
+ }
+
+ all_components
+ .into_iter()
+ .unique_by(|component| &component.file_names)
+ .collect()
+ }
+
pub fn contains(&self, short_name: &str) -> bool {
let sty = format!("{}.sty", short_name);
let cls = format!("{}.cls", short_name);
@@ -55,35 +97,35 @@ impl Database {
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Component {
- pub file_names: Vec<String>,
- pub references: Vec<String>,
- pub commands: Vec<Command>,
- pub environments: Vec<String>,
+ pub file_names: Vec<SmolStr>,
+ pub references: Vec<SmolStr>,
+ pub commands: Vec<ComponentCommand>,
+ pub environments: Vec<SmolStr>,
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct Command {
- pub name: String,
+pub struct ComponentCommand {
+ pub name: SmolStr,
pub image: Option<String>,
- pub glyph: Option<String>,
- pub parameters: Vec<Parameter>,
+ pub glyph: Option<SmolStr>,
+ pub parameters: Vec<ComponentParameter>,
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct Parameter(pub Vec<Argument>);
+pub struct ComponentParameter(pub Vec<ComponentArgument>);
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct Argument {
- pub name: String,
+pub struct ComponentArgument {
+ pub name: SmolStr,
pub image: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct Metadata {
+pub struct ComponentMetadata {
pub name: String,
pub caption: Option<String>,
pub description: Option<String>,
@@ -91,4 +133,5 @@ pub struct Metadata {
const JSON: &str = include_str!("../data/components.json");
-pub static COMPONENT_DATABASE: Lazy<Database> = Lazy::new(|| serde_json::from_str(JSON).unwrap());
+pub static COMPONENT_DATABASE: Lazy<ComponentDatabase> =
+ Lazy::new(|| serde_json::from_str(JSON).unwrap());
diff --git a/support/texlab/src/config.rs b/support/texlab/src/config.rs
index 84de2268fa..5690bee091 100644
--- a/support/texlab/src/config.rs
+++ b/support/texlab/src/config.rs
@@ -1,103 +1,90 @@
-use crate::protocol::*;
-use futures::lock::Mutex;
-use log::{error, warn};
-use serde::de::DeserializeOwned;
-use std::sync::Arc;
+use std::sync::{Mutex, RwLock};
-#[derive(Debug)]
-pub struct ConfigManager<C> {
- client: Arc<C>,
- client_capabilities: Arc<ClientCapabilities>,
- options: Mutex<Options>,
-}
+use crossbeam_channel::Sender;
+use log::{error, warn};
+use lsp_server::Message;
+use lsp_types::{
+ notification::{DidChangeConfiguration, Notification},
+ request::{RegisterCapability, WorkspaceConfiguration},
+ ClientCapabilities, ConfigurationItem, ConfigurationParams, Registration, RegistrationParams,
+};
-impl<C: LspClient + Send + Sync + 'static> ConfigManager<C> {
- pub fn new(client: Arc<C>, client_capabilities: Arc<ClientCapabilities>) -> Self {
- Self {
- client,
- client_capabilities,
- options: Mutex::default(),
- }
- }
+use crate::{client::send_request, req_queue::ReqQueue, ClientCapabilitiesExt, Options};
- pub async fn get(&self) -> Options {
- self.options.lock().await.clone()
- }
+pub fn register_config_capability(
+ req_queue: &Mutex<ReqQueue>,
+ sender: &Sender<Message>,
+ client_capabilities: &Mutex<ClientCapabilities>,
+) {
+ let client_capabilities = client_capabilities.lock().unwrap();
+ if !client_capabilities.has_pull_configuration_support()
+ && client_capabilities.has_push_configuration_support()
+ {
+ drop(client_capabilities);
+ let reg = Registration {
+ id: "pull-config".to_string(),
+ method: DidChangeConfiguration::METHOD.to_string(),
+ register_options: None,
+ };
- pub async fn register(&self) {
- if !self.client_capabilities.has_pull_configuration_support()
- && self.client_capabilities.has_push_configuration_support()
- {
- let registration = Registration {
- id: "pull-config".into(),
- method: "workspace/didChangeConfiguration".into(),
- register_options: None,
- };
- let params = RegistrationParams {
- registrations: vec![registration],
- };
+ let params = RegistrationParams {
+ registrations: vec![reg],
+ };
- if let Err(why) = self.client.register_capability(params).await {
- error!(
- "Failed to register \"workspace/didChangeConfiguration\": {}",
- why.message
- );
- }
+ if let Err(why) = send_request::<RegisterCapability>(&req_queue, &sender, params) {
+ error!(
+ "Failed to register \"{}\" notification: {}",
+ DidChangeConfiguration::METHOD,
+ why
+ );
}
}
+}
- pub async fn push(&self, options: serde_json::Value) {
- match serde_json::from_value(options) {
- Ok(options) => {
- *self.options.lock().await = options;
- }
- Err(why) => {
- error!("Invalid configuration: {}", why);
- }
- }
+pub fn pull_config(
+ req_queue: &Mutex<ReqQueue>,
+ sender: &Sender<Message>,
+ options: &RwLock<Options>,
+ client_capabilities: &ClientCapabilities,
+) {
+ if !client_capabilities.has_pull_configuration_support() {
+ return;
}
- pub async fn pull(&self) -> bool {
- if self.client_capabilities.has_pull_configuration_support() {
- let latex = self.pull_section("latex").await;
- let bibtex = self.pull_section("bibtex").await;
+ let params = ConfigurationParams {
+ items: vec![ConfigurationItem {
+ section: Some("texlab".to_string()),
+ scope_uri: None,
+ }],
+ };
- let new_options = Options {
- latex: Some(latex),
- bibtex: Some(bibtex),
+ match send_request::<WorkspaceConfiguration>(req_queue, sender, params) {
+ Ok(mut json) => {
+ let value = json.pop().expect("invalid configuration request");
+ let new_options = match serde_json::from_value(value) {
+ Ok(new_options) => new_options,
+ Err(why) => {
+ warn!("Invalid configuration section \"texlab\": {}", why);
+ Options::default()
+ }
};
- let mut old_options = self.options.lock().await;
- let has_changed = *old_options != new_options;
- *old_options = new_options;
- has_changed
- } else {
- false
- }
- }
- async fn pull_section<T: DeserializeOwned + Default>(&self, section: &str) -> T {
- let params = ConfigurationParams {
- items: vec![ConfigurationItem {
- section: Some(section.into()),
- scope_uri: None,
- }],
- };
+ let mut options = options.write().unwrap();
+ *options = new_options;
+ }
+ Err(why) => {
+ error!("Retrieving configuration failed: {}", why);
+ }
+ };
+}
- match self.client.configuration(params).await {
- Ok(json) => match serde_json::from_value::<Vec<T>>(json) {
- Ok(config) => config.into_iter().next().unwrap(),
- Err(_) => {
- warn!("Invalid configuration: {}", section);
- T::default()
- }
- },
- Err(why) => {
- error!(
- "Retrieving configuration for {} failed: {}",
- section, why.message
- );
- T::default()
- }
+pub fn push_config(options: &RwLock<Options>, config: serde_json::Value) {
+ match serde_json::from_value(config) {
+ Ok(new_options) => {
+ *options.write().unwrap() = new_options;
}
- }
+ Err(why) => {
+ error!("Invalid configuration: {}", why);
+ }
+ };
}
diff --git a/support/texlab/src/context.rs b/support/texlab/src/context.rs
new file mode 100644
index 0000000000..a9d6f530a6
--- /dev/null
+++ b/support/texlab/src/context.rs
@@ -0,0 +1,34 @@
+use std::{
+ path::PathBuf,
+ sync::{Mutex, RwLock},
+};
+
+use lsp_types::{ClientCapabilities, ClientInfo};
+
+use crate::{
+ distro::{DistributionKind, Resolver},
+ Options,
+};
+
+#[derive(Debug)]
+pub struct ServerContext {
+ pub current_directory: PathBuf,
+ pub distro_kind: Mutex<DistributionKind>,
+ pub resolver: Mutex<Resolver>,
+ pub client_capabilities: Mutex<ClientCapabilities>,
+ pub client_info: Mutex<Option<ClientInfo>>,
+ pub options: RwLock<Options>,
+}
+
+impl ServerContext {
+ pub fn new(current_dir: PathBuf) -> Self {
+ Self {
+ current_directory: current_dir,
+ distro_kind: Mutex::new(DistributionKind::Unknown),
+ resolver: Mutex::new(Resolver::default()),
+ client_capabilities: Mutex::default(),
+ client_info: Mutex::default(),
+ options: RwLock::default(),
+ }
+ }
+}
diff --git a/support/texlab/src/definition/bibtex_string.rs b/support/texlab/src/definition/bibtex_string.rs
deleted file mode 100644
index a1fe5132c0..0000000000
--- a/support/texlab/src/definition/bibtex_string.rs
+++ /dev/null
@@ -1,171 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{LocationLink, Position, TextDocumentPositionParams, Uri},
- syntax::{bibtex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexStringDefinitionProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexStringDefinitionProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<LocationLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- if let Some(reference) = Self::find_reference(tree, req.params.position) {
- return Self::find_definitions(&req.current().uri, tree, reference);
- }
- }
- Vec::new()
- }
-}
-
-impl BibtexStringDefinitionProvider {
- fn find_reference(tree: &bibtex::Tree, pos: Position) -> Option<&bibtex::Token> {
- let mut nodes = tree.find(pos);
- nodes.reverse();
- match (
- &tree.graph[nodes[0]],
- nodes.get(1).map(|node| &tree.graph[*node]),
- ) {
- (bibtex::Node::Word(word), Some(bibtex::Node::Field(_)))
- | (bibtex::Node::Word(word), Some(bibtex::Node::Concat(_))) => Some(&word.token),
- _ => None,
- }
- }
-
- fn find_definitions(
- uri: &Uri,
- tree: &bibtex::Tree,
- reference: &bibtex::Token,
- ) -> Vec<LocationLink> {
- let mut links = Vec::new();
- for node in tree.children(tree.root) {
- if let Some(string) = tree.as_string(node) {
- if let Some(name) = &string.name {
- if name.text() == reference.text() {
- links.push(LocationLink {
- origin_selection_range: Some(reference.range()),
- target_uri: uri.clone().into(),
- target_range: string.range(),
- target_selection_range: name.range(),
- });
- }
- }
- }
- }
- links
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_links = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(BibtexStringDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_links = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(BibtexStringDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn simple() {
- let actual_links = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {bar}}
- @article{bar, author = foo}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 24)
- .test_position(BibtexStringDefinitionProvider)
- .await;
-
- let expected_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(1, 23, 1, 26)),
- target_uri: FeatureTester::uri("main.bib").into(),
- target_range: Range::new_simple(0, 0, 0, 20),
- target_selection_range: Range::new_simple(0, 8, 0, 11),
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-
- #[tokio::test]
- async fn concat() {
- let actual_links = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {bar}}
- @article{bar, author = foo # "bar"}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 24)
- .test_position(BibtexStringDefinitionProvider)
- .await;
-
- let expected_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(1, 23, 1, 26)),
- target_uri: FeatureTester::uri("main.bib").into(),
- target_range: Range::new_simple(0, 0, 0, 20),
- target_selection_range: Range::new_simple(0, 8, 0, 11),
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-
- #[tokio::test]
- async fn field() {
- let actual_links = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {bar}}
- @article{bar, author = foo}
- "#
- ),
- )
- .main("main.bib")
- .position(1, 18)
- .test_position(BibtexStringDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-}
diff --git a/support/texlab/src/definition/latex_citation.rs b/support/texlab/src/definition/latex_citation.rs
deleted file mode 100644
index aa93e25fc0..0000000000
--- a/support/texlab/src/definition/latex_citation.rs
+++ /dev/null
@@ -1,118 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{LocationLink, RangeExt, TextDocumentPositionParams},
- syntax::{latex, SyntaxNode},
- workspace::{Document, DocumentContent},
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct LatexCitationDefinitionProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexCitationDefinitionProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<LocationLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut links = Vec::new();
- if let Some(reference) = Self::find_reference(req) {
- for doc in req.related() {
- Self::find_definitions(&doc, &reference, &mut links);
- }
- }
- links
- }
-}
-
-impl LatexCitationDefinitionProvider {
- fn find_reference(req: &FeatureRequest<TextDocumentPositionParams>) -> Option<&latex::Token> {
- req.current().content.as_latex().and_then(|table| {
- table
- .citations
- .iter()
- .flat_map(|citation| citation.keys(&table))
- .find(|key| key.range().contains(req.params.position))
- })
- }
-
- fn find_definitions(doc: &Document, reference: &latex::Token, links: &mut Vec<LocationLink>) {
- if let DocumentContent::Bibtex(tree) = &doc.content {
- for entry in tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- {
- if let Some(key) = &entry.key {
- if key.text() == reference.text() {
- links.push(LocationLink {
- origin_selection_range: Some(reference.range()),
- target_uri: doc.uri.clone().into(),
- target_range: entry.range(),
- target_selection_range: key.range(),
- });
- }
- }
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_links = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(LatexCitationDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_links = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(LatexCitationDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn has_definition() {
- let actual_links = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \addbibresource{baz.bib}
- \cite{foo}
- "#
- ),
- )
- .file("bar.bib", r#"@article{foo, bar = {baz}}"#)
- .file("baz.bib", r#"@article{foo, bar = {baz}}"#)
- .main("foo.tex")
- .position(1, 6)
- .test_position(LatexCitationDefinitionProvider)
- .await;
-
- let exepcted_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(1, 6, 1, 9)),
- target_uri: FeatureTester::uri("baz.bib").into(),
- target_range: Range::new_simple(0, 0, 0, 26),
- target_selection_range: Range::new_simple(0, 9, 0, 12),
- }];
-
- assert_eq!(actual_links, exepcted_links);
- }
-}
diff --git a/support/texlab/src/definition/latex_cmd.rs b/support/texlab/src/definition/latex_cmd.rs
deleted file mode 100644
index 35fc42be4f..0000000000
--- a/support/texlab/src/definition/latex_cmd.rs
+++ /dev/null
@@ -1,154 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{LocationLink, TextDocumentPositionParams},
- syntax::SyntaxNode,
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexCommandDefinitionProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexCommandDefinitionProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<LocationLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut links = Vec::new();
- if let DocumentContent::Latex(table) = &req.current().content {
- if let Some(cmd) = table
- .find(req.params.position)
- .last()
- .and_then(|node| table.as_command(*node))
- {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .command_definitions
- .iter()
- .filter(|def| def.definition_name(&table) == cmd.name.text())
- .map(|def| {
- let def_range = table[def.parent].range();
- LocationLink {
- origin_selection_range: Some(cmd.range()),
- target_uri: doc.uri.clone().into(),
- target_range: def_range,
- target_selection_range: def_range,
- }
- })
- .for_each(|link| links.push(link));
-
- table
- .math_operators
- .iter()
- .filter(|op| op.definition_name(&table) == cmd.name.text())
- .map(|op| {
- let def_range = table[op.parent].range();
- LocationLink {
- origin_selection_range: Some(cmd.range()),
- target_uri: doc.uri.clone().into(),
- target_range: def_range,
- target_selection_range: def_range,
- }
- })
- .for_each(|link| links.push(link));
- }
- }
- }
- }
- links
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_links = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(LatexCommandDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_links = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(LatexCommandDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn command_definition() {
- let actual_links = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \include{bar}
- \foo
- "#
- ),
- )
- .file("bar.tex", r#"\newcommand{\foo}{bar}"#)
- .file("baz.tex", r#"\newcommand{\foo}{baz}"#)
- .main("foo.tex")
- .position(1, 3)
- .test_position(LatexCommandDefinitionProvider)
- .await;
-
- let expected_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(1, 0, 1, 4)),
- target_uri: FeatureTester::uri("bar.tex").into(),
- target_range: Range::new_simple(0, 0, 0, 22),
- target_selection_range: Range::new_simple(0, 0, 0, 22),
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-
- #[tokio::test]
- async fn math_operator() {
- let actual_links = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \include{bar}
- \foo
- "#
- ),
- )
- .file("bar.tex", r#"\DeclareMathOperator{\foo}{bar}"#)
- .file("baz.tex", r#"\DeclareMathOperator{\foo}{baz}"#)
- .main("foo.tex")
- .position(1, 3)
- .test_position(LatexCommandDefinitionProvider)
- .await;
-
- let expected_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(1, 0, 1, 4)),
- target_uri: FeatureTester::uri("bar.tex").into(),
- target_range: Range::new_simple(0, 0, 0, 31),
- target_selection_range: Range::new_simple(0, 0, 0, 31),
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-}
diff --git a/support/texlab/src/definition/latex_label.rs b/support/texlab/src/definition/latex_label.rs
deleted file mode 100644
index 5318982ccd..0000000000
--- a/support/texlab/src/definition/latex_label.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use crate::{
- feature::{DocumentView, FeatureProvider, FeatureRequest},
- outline::{Outline, OutlineContext, OutlineContextItem},
- protocol::{LocationLink, Options, RangeExt, TextDocumentPositionParams},
- symbol::build_section_tree,
- syntax::{latex, LatexLabelKind, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use std::{path::Path, sync::Arc};
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexLabelDefinitionProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexLabelDefinitionProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<LocationLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut links = Vec::new();
- if let Some(reference) = Self::find_reference(req) {
- for doc in req.related() {
- let snapshot = Arc::clone(&req.view.snapshot);
- let view = DocumentView::analyze(
- snapshot,
- Arc::clone(&doc),
- &req.options,
- &req.current_dir,
- );
- Self::find_definitions(
- &view,
- &req.options,
- &req.current_dir,
- &reference,
- &mut links,
- );
- }
- }
- links
- }
-}
-
-impl LatexLabelDefinitionProvider {
- fn find_reference(req: &FeatureRequest<TextDocumentPositionParams>) -> Option<&latex::Token> {
- if let DocumentContent::Latex(table) = &req.current().content {
- table
- .labels
- .iter()
- .flat_map(|label| label.names(&table))
- .find(|label| label.range().contains(req.params.position))
- } else {
- None
- }
- }
-
- fn find_definitions(
- view: &DocumentView,
- options: &Options,
- current_dir: &Path,
- reference: &latex::Token,
- links: &mut Vec<LocationLink>,
- ) {
- if let DocumentContent::Latex(table) = &view.current.content {
- let outline = Outline::analyze(view, options, current_dir);
- let section_tree = build_section_tree(view, table, options, current_dir);
- for label in &table.labels {
- if label.kind == LatexLabelKind::Definition {
- let context = OutlineContext::parse(view, &outline, *label);
- for name in label.names(&table) {
- if name.text() == reference.text() {
- let target_range = if let Some(OutlineContextItem::Section { .. }) =
- context.as_ref().map(|ctx| &ctx.item)
- {
- section_tree
- .find(reference.text())
- .map(|sec| sec.full_range)
- } else {
- context.as_ref().map(|ctx| ctx.range)
- };
-
- links.push(LocationLink {
- origin_selection_range: Some(reference.range()),
- target_uri: view.current.uri.clone().into(),
- target_range: target_range
- .unwrap_or_else(|| table[label.parent].range()),
- target_selection_range: table[label.parent].range(),
- });
- }
- }
- }
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_links = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(LatexLabelDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_links = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(LatexLabelDefinitionProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn unknown_context() {
- let actual_links = FeatureTester::new()
- .file("foo.tex", r#"\label{foo}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \begin{a}\begin{b}\label{foo}\end{b}\end{a}
- \input{baz.tex}
- "#
- ),
- )
- .file("baz.tex", r#"\ref{foo}"#)
- .main("baz.tex")
- .position(0, 5)
- .test_position(LatexLabelDefinitionProvider)
- .await;
-
- let expected_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(0, 5, 0, 8)),
- target_uri: FeatureTester::uri("bar.tex").into(),
- target_range: Range::new_simple(0, 18, 0, 29),
- target_selection_range: Range::new_simple(0, 18, 0, 29),
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-}
diff --git a/support/texlab/src/definition/mod.rs b/support/texlab/src/definition/mod.rs
deleted file mode 100644
index 08901454fe..0000000000
--- a/support/texlab/src/definition/mod.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-mod bibtex_string;
-mod latex_citation;
-mod latex_cmd;
-mod latex_label;
-
-use self::{
- bibtex_string::BibtexStringDefinitionProvider, latex_citation::LatexCitationDefinitionProvider,
- latex_cmd::LatexCommandDefinitionProvider, latex_label::LatexLabelDefinitionProvider,
-};
-use crate::{
- feature::{ConcatProvider, FeatureProvider, FeatureRequest},
- protocol::{LocationLink, TextDocumentPositionParams},
-};
-use async_trait::async_trait;
-
-pub struct DefinitionProvider {
- provider: ConcatProvider<TextDocumentPositionParams, LocationLink>,
-}
-
-impl DefinitionProvider {
- pub fn new() -> Self {
- Self {
- provider: ConcatProvider::new(vec![
- Box::new(BibtexStringDefinitionProvider),
- Box::new(LatexCitationDefinitionProvider),
- Box::new(LatexCommandDefinitionProvider),
- Box::new(LatexLabelDefinitionProvider),
- ]),
- }
- }
-}
-
-impl Default for DefinitionProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for DefinitionProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<LocationLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
diff --git a/support/texlab/src/diagnostics.rs b/support/texlab/src/diagnostics.rs
new file mode 100644
index 0000000000..a4adbafd7d
--- /dev/null
+++ b/support/texlab/src/diagnostics.rs
@@ -0,0 +1,55 @@
+mod bibtex;
+mod build_log;
+mod chktex;
+mod debouncer;
+mod latex;
+
+use std::sync::Arc;
+
+use lsp_types::Diagnostic;
+use multimap::MultiMap;
+use rustc_hash::FxHashMap;
+
+use crate::{Options, Uri, Workspace};
+
+pub use self::debouncer::{DiagnosticsDebouncer, DiagnosticsMessage};
+
+use self::{
+ bibtex::analyze_bibtex_static, build_log::analyze_build_log_static,
+ chktex::analyze_latex_chktex, latex::analyze_latex_static,
+};
+
+#[derive(Default)]
+pub struct DiagnosticsManager {
+ static_diagnostics: FxHashMap<Arc<Uri>, MultiMap<Arc<Uri>, Diagnostic>>,
+ chktex_diagnostics: MultiMap<Arc<Uri>, Diagnostic>,
+}
+
+impl DiagnosticsManager {
+ pub fn update_static(&mut self, workspace: &dyn Workspace, uri: Arc<Uri>) {
+ let mut diagnostics_by_uri = MultiMap::new();
+ analyze_build_log_static(workspace, &mut diagnostics_by_uri, &uri);
+ analyze_bibtex_static(workspace, &mut diagnostics_by_uri, &uri);
+ analyze_latex_static(workspace, &mut diagnostics_by_uri, &uri);
+ self.static_diagnostics.insert(uri, diagnostics_by_uri);
+ }
+
+ pub fn update_chktex(&mut self, workspace: &dyn Workspace, uri: Arc<Uri>, options: &Options) {
+ analyze_latex_chktex(workspace, &mut self.chktex_diagnostics, &uri, options);
+ }
+
+ pub fn publish(&self, uri: Arc<Uri>) -> Vec<Diagnostic> {
+ let mut all_diagnostics = Vec::new();
+ for diagnostics_by_uri in self.static_diagnostics.values() {
+ if let Some(diagnostics) = diagnostics_by_uri.get_vec(&uri) {
+ all_diagnostics.append(&mut diagnostics.clone());
+ }
+ }
+
+ if let Some(diagnostics) = self.chktex_diagnostics.get_vec(&uri) {
+ all_diagnostics.append(&mut diagnostics.clone());
+ }
+
+ all_diagnostics
+ }
+}
diff --git a/support/texlab/src/diagnostics/bibtex.rs b/support/texlab/src/diagnostics/bibtex.rs
index 80cca80319..efea141db0 100644
--- a/support/texlab/src/diagnostics/bibtex.rs
+++ b/support/texlab/src/diagnostics/bibtex.rs
@@ -1,341 +1,147 @@
-use crate::{
- protocol::{Diagnostic, DiagnosticSeverity, Position, Range},
- syntax::{bibtex, SyntaxNode},
- workspace::{Document, DocumentContent},
-};
-use petgraph::graph::NodeIndex;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum BibtexErrorCode {
- MissingBeginBrace,
- MissingEntryKey,
- MissingComma,
- MissingEndBrace,
- MissingAssign,
- MissingContent,
- MissingQuote,
-}
-
-impl BibtexErrorCode {
- pub fn message(self) -> &'static str {
- match self {
- BibtexErrorCode::MissingBeginBrace => "Expecting a curly bracket: \"{\"",
- BibtexErrorCode::MissingEntryKey => "Expecting an entry key",
- BibtexErrorCode::MissingComma => "Expecting a comma: \",\"",
- BibtexErrorCode::MissingEndBrace => "Expecting a curly bracket: \"}\"",
- BibtexErrorCode::MissingAssign => "Expecting an equals sign: \"=\"",
- BibtexErrorCode::MissingContent => "Expecting content",
- BibtexErrorCode::MissingQuote => "Expecting a quote: '\"'",
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct BibtexError {
- code: BibtexErrorCode,
- position: Position,
-}
-
-impl BibtexError {
- pub fn new(code: BibtexErrorCode, position: Position) -> Self {
- Self { code, position }
- }
-
- pub fn analyze(tree: &bibtex::Tree) -> Vec<Self> {
- let mut errors = Vec::new();
- for entry_node in tree.children(tree.root) {
- if let Some(entry) = tree.as_entry(entry_node) {
- if entry.is_comment() {
- continue;
- }
-
- if entry.left.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingBeginBrace,
- entry.ty.end(),
- ));
- continue;
- }
+use std::sync::Arc;
- if entry.key.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingEntryKey,
- entry.left.as_ref().unwrap().end(),
- ));
- continue;
- }
+use cstree::TextRange;
+use lsp_types::{Diagnostic, DiagnosticSeverity};
+use multimap::MultiMap;
- if entry.comma.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingComma,
- entry.key.as_ref().unwrap().end(),
- ));
- continue;
- }
-
- let field_count = tree.children(entry_node).count();
- for (i, field_node) in tree.children(entry_node).enumerate() {
- let field = tree.as_field(field_node).unwrap();
- if field.assign.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingAssign,
- field.name.end(),
- ));
- continue;
- }
-
- let content = tree.children(field_node).next();
-
- if content.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingContent,
- field.assign.as_ref().unwrap().end(),
- ));
- continue;
- }
-
- Self::analyze_content(&mut errors, tree, content.unwrap());
-
- if i != field_count - 1 && field.comma.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingComma,
- tree.graph[content.unwrap()].end(),
- ));
- continue;
- }
- }
-
- if entry.right.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingEndBrace,
- entry.end(),
- ));
- continue;
- }
- }
- }
- errors
- }
-
- fn analyze_content(
- mut errors: &mut Vec<BibtexError>,
- tree: &bibtex::Tree,
- content_node: NodeIndex,
- ) {
- match &tree.graph[content_node] {
- bibtex::Node::QuotedContent(content) => {
- for child in tree.children(content_node) {
- Self::analyze_content(&mut errors, tree, child);
- }
-
- if content.right.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingQuote,
- content.end(),
- ));
- }
- }
- bibtex::Node::BracedContent(content) => {
- for child in tree.children(content_node) {
- Self::analyze_content(&mut errors, tree, child);
- }
+use crate::{
+ syntax::{
+ bibtex::{self, HasDelimiters, HasType},
+ CstNode,
+ },
+ Document, LineIndexExt, Uri, Workspace,
+};
- if content.right.is_none() {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingEndBrace,
- content.end(),
- ));
- }
- }
- bibtex::Node::Concat(concat) => {
- let mut children = tree.children(content_node);
- Self::analyze_content(&mut errors, tree, children.next().unwrap());
- match children.next() {
- Some(right) => {
- Self::analyze_content(&mut errors, tree, right);
- }
- None => {
- errors.push(BibtexError::new(
- BibtexErrorCode::MissingContent,
- concat.end(),
- ));
- }
- }
- }
- bibtex::Node::Root(_)
- | bibtex::Node::Comment(_)
- | bibtex::Node::Preamble(_)
- | bibtex::Node::String(_)
- | bibtex::Node::Entry(_)
- | bibtex::Node::Field(_)
- | bibtex::Node::Word(_)
- | bibtex::Node::Command(_) => {}
- }
- }
-}
+pub fn analyze_bibtex_static(
+ workspace: &dyn Workspace,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ uri: &Uri,
+) -> Option<()> {
+ let document = workspace.get(uri)?;
+ let data = document.data.as_bibtex()?;
-impl Into<Diagnostic> for BibtexError {
- fn into(self) -> Diagnostic {
- Diagnostic {
- source: Some("bibtex".into()),
- range: Range::new(self.position, self.position),
- message: self.code.message().into(),
- severity: Some(DiagnosticSeverity::Error),
- code: None,
- related_information: None,
- tags: None,
- }
+ for node in data.root.descendants() {
+ analyze_entry(&document, diagnostics_by_uri, node)
+ .or_else(|| analyze_field(&document, diagnostics_by_uri, node));
}
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexDiagnosticsProvider;
-impl BibtexDiagnosticsProvider {
- pub fn get(self, doc: &Document) -> Vec<Diagnostic> {
- if let DocumentContent::Bibtex(tree) = &doc.content {
- BibtexError::analyze(&tree)
- .into_iter()
- .map(Into::into)
- .collect()
- } else {
- Vec::new()
- }
- }
+ Some(())
}
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn begin_brace() {
- let errors = BibtexError::analyze(&bibtex::open("@article"));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingBeginBrace,
- Position::new(0, 8),
- )]
- );
- }
-
- #[test]
- fn entry_key() {
- let errors = BibtexError::analyze(&bibtex::open("@article{"));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingEntryKey,
- Position::new(0, 9),
- )]
- );
- }
-
- #[test]
- fn entry_comma() {
- let errors = BibtexError::analyze(&bibtex::open("@article{foo"));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingComma,
- Position::new(0, 12),
- )]
- );
- }
-
- #[test]
- fn entry_end_brace() {
- let errors = BibtexError::analyze(&bibtex::open("@article{foo,"));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingEndBrace,
- Position::new(0, 13),
- )]
+fn analyze_entry(
+ document: &Document,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ node: &bibtex::SyntaxNode,
+) -> Option<()> {
+ let entry = bibtex::Entry::cast(node)?;
+ if entry.left_delimiter().is_none() {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document
+ .line_index
+ .line_col_lsp_range(entry.ty()?.text_range()),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Expecting a curly bracket: \"{\"".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
+ },
);
- }
-
- #[test]
- fn field_equals() {
- let errors = BibtexError::analyze(&bibtex::open("@article{foo, bar}"));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingAssign,
- Position::new(0, 17),
- )]
+ return Some(());
+ }
+
+ if entry.key().is_none() {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document
+ .line_index
+ .line_col_lsp_range(entry.left_delimiter()?.text_range()),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Expecting a key".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
+ },
);
- }
-
- #[test]
- fn field_content() {
- let errors = BibtexError::analyze(&bibtex::open("@article{foo,\nbar = }"));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingContent,
- Position::new(1, 5),
- )]
- );
- }
-
- #[test]
- fn field_comma() {
- let text = "@article{foo,\nfoo = bar\nbaz = qux}";
- let errors = BibtexError::analyze(&bibtex::open(text));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingComma,
- Position::new(1, 9),
- )]
+ return Some(());
+ }
+
+ if entry.key().is_none() {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document
+ .line_index
+ .line_col_lsp_range(entry.right_delimiter()?.text_range()),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Expecting a curly bracket: \"}\"".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
+ },
);
+ return Some(());
}
- #[test]
- fn content_quote() {
- let text = "@article{foo, bar =\n\"}";
- let errors = BibtexError::analyze(&bibtex::open(text));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingQuote,
- Position::new(1, 1),
- )]
- );
- }
+ Some(())
+}
- #[test]
- fn content_brace() {
- let text = "@article{foo, bar =\n{";
- let errors = BibtexError::analyze(&bibtex::open(text));
- assert_eq!(
- errors,
- vec![
- BibtexError::new(BibtexErrorCode::MissingEndBrace, Position::new(1, 1)),
- BibtexError::new(BibtexErrorCode::MissingEndBrace, Position::new(1, 1)),
- ]
+fn analyze_field(
+ document: &Document,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ node: &bibtex::SyntaxNode,
+) -> Option<()> {
+ let field = bibtex::Field::cast(node)?;
+ if field.equality_sign().is_none() {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document
+ .line_index
+ .line_col_lsp_range(TextRange::empty(field.name()?.text_range().end())),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Expecting an equality sign: \"=\"".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
+ },
);
- }
-
- #[test]
- fn content_concat() {
- let text = "@article{foo, bar = baz \n# }";
- let errors = BibtexError::analyze(&bibtex::open(text));
- assert_eq!(
- errors,
- vec![BibtexError::new(
- BibtexErrorCode::MissingContent,
- Position::new(1, 1)
- )]
+ return Some(());
+ }
+
+ if field.value().is_none() {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document.line_index.line_col_lsp_range(TextRange::empty(
+ field.equality_sign()?.text_range().end(),
+ )),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Expecting a field value".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
+ },
);
+ return Some(());
}
- #[test]
- fn entry_valid() {
- let text = "@article{foo, bar = \"baz {qux}\" # quux}";
- let errors = BibtexError::analyze(&bibtex::open(text));
- assert_eq!(errors, Vec::new());
- }
+ Some(())
}
diff --git a/support/texlab/src/diagnostics/build_log.rs b/support/texlab/src/diagnostics/build_log.rs
new file mode 100644
index 0000000000..a2069ff762
--- /dev/null
+++ b/support/texlab/src/diagnostics/build_log.rs
@@ -0,0 +1,65 @@
+use std::{path::PathBuf, sync::Arc};
+
+use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
+use multimap::MultiMap;
+
+use crate::{syntax::build_log::BuildErrorLevel, Uri, Workspace};
+
+pub fn analyze_build_log_static(
+ workspace: &dyn Workspace,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ build_log_uri: &Uri,
+) -> Option<()> {
+ let build_log_document = workspace.get(build_log_uri)?;
+ let parse = build_log_document.data.as_build_log()?;
+
+ let root_document = workspace.documents().into_iter().find(|document| {
+ if let Some(data) = document.data.as_latex() {
+ data.extras
+ .implicit_links
+ .log
+ .iter()
+ .any(|u| u.as_ref() == build_log_uri)
+ } else {
+ false
+ }
+ })?;
+
+ let base_path = PathBuf::from(root_document.uri.path());
+
+ for error in &parse.errors {
+ let pos = Position::new(error.line.unwrap_or(0), 0);
+ let severity = match error.level {
+ BuildErrorLevel::Error => DiagnosticSeverity::Error,
+ BuildErrorLevel::Warning => DiagnosticSeverity::Warning,
+ };
+ let range = Range::new(pos, pos);
+ let diagnostic = Diagnostic {
+ range,
+ severity: Some(severity),
+ code: None,
+ code_description: None,
+ source: Some("latex".into()),
+ message: error.message.clone(),
+ related_information: None,
+ tags: None,
+ data: None,
+ };
+
+ let full_path = base_path.join(&error.relative_path);
+
+ let uri = if full_path.starts_with(&base_path) {
+ error
+ .relative_path
+ .to_str()
+ .and_then(|path| root_document.uri.join(path).map(Into::into).ok())
+ .map(Arc::new)
+ .unwrap_or_else(|| Arc::clone(&root_document.uri))
+ } else {
+ Arc::clone(&root_document.uri)
+ };
+
+ diagnostics_by_uri.insert(uri, diagnostic);
+ }
+ Some(())
+}
diff --git a/support/texlab/src/diagnostics/chktex.rs b/support/texlab/src/diagnostics/chktex.rs
new file mode 100644
index 0000000000..897887c473
--- /dev/null
+++ b/support/texlab/src/diagnostics/chktex.rs
@@ -0,0 +1,105 @@
+use std::{
+ fs, io,
+ path::Path,
+ process::{Command, Stdio},
+ sync::Arc,
+};
+
+use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString, Range};
+use multimap::MultiMap;
+use once_cell::sync::Lazy;
+use regex::Regex;
+use tempfile::tempdir;
+
+use crate::{Options, RangeExt, Uri, Workspace};
+
+pub fn analyze_latex_chktex(
+ workspace: &dyn Workspace,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ uri: &Uri,
+ options: &Options,
+) -> Option<()> {
+ let document = workspace.get(uri)?;
+ document.data.as_latex()?;
+
+ let current_dir = options
+ .root_directory
+ .as_ref()
+ .cloned()
+ .or_else(|| {
+ if document.uri.scheme() == "file" {
+ document
+ .uri
+ .to_file_path()
+ .unwrap()
+ .parent()
+ .map(ToOwned::to_owned)
+ } else {
+ None
+ }
+ })
+ .unwrap_or_else(|| ".".into());
+
+ diagnostics_by_uri.remove(uri);
+ diagnostics_by_uri.insert_many(
+ Arc::clone(&document.uri),
+ lint(&document.text, &current_dir).unwrap_or_default(),
+ );
+ Some(())
+}
+
+pub static LINE_REGEX: Lazy<Regex> =
+ Lazy::new(|| Regex::new("(\\d+):(\\d+):(\\d+):(\\w+):(\\w+):(.*)").unwrap());
+
+fn lint(text: &str, current_dir: &Path) -> io::Result<Vec<Diagnostic>> {
+ let directory = tempdir()?;
+ fs::write(directory.path().join("file.tex"), text)?;
+ let _ = fs::copy(
+ current_dir.join("chktexrc"),
+ directory.path().join("chktexrc"),
+ );
+
+ let output = Command::new("chktex")
+ .args(&["-I0", "-f%l:%c:%d:%k:%n:%m\n", "file.tex"])
+ .stdin(Stdio::null())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .current_dir(directory.path())
+ .output()?;
+
+ // let mut writer = BufWriter::new(process.stdin.take().unwrap());
+ // writer.write_all(text.as_bytes())?;
+ // // writer.flush()?;
+ // let output = process.wait_with_output()?;
+
+ let mut diagnostics = Vec::new();
+ for line in String::from_utf8_lossy(&output.stdout).lines() {
+ let captures = LINE_REGEX.captures(&line).unwrap();
+ let line = captures[1].parse::<u32>().unwrap() - 1;
+ let character = captures[2].parse::<u32>().unwrap() - 1;
+ let digit = captures[3].parse::<u32>().unwrap();
+ let kind = &captures[4];
+ let code = &captures[5];
+ let message = captures[6].into();
+ let range = Range::new_simple(line, character, line, character + digit);
+ let severity = match kind {
+ "Message" => DiagnosticSeverity::Information,
+ "Warning" => DiagnosticSeverity::Warning,
+ _ => DiagnosticSeverity::Error,
+ };
+
+ diagnostics.push(Diagnostic {
+ range,
+ severity: Some(severity),
+ code: Some(NumberOrString::String(code.into())),
+ code_description: None,
+ source: Some("chktex".into()),
+ message,
+ related_information: None,
+ tags: None,
+ data: None,
+ });
+ }
+
+ Ok(diagnostics)
+}
diff --git a/support/texlab/src/diagnostics/debouncer.rs b/support/texlab/src/diagnostics/debouncer.rs
new file mode 100644
index 0000000000..46bea80176
--- /dev/null
+++ b/support/texlab/src/diagnostics/debouncer.rs
@@ -0,0 +1,77 @@
+use std::{
+ sync::Arc,
+ thread::{self, JoinHandle},
+ time::{Duration, Instant},
+};
+
+use chashmap::CHashMap;
+use crossbeam_channel::Sender;
+
+use crate::{Document, ServerContext, Uri, Workspace};
+
+pub enum DiagnosticsMessage {
+ Analyze {
+ workspace: Arc<dyn Workspace>,
+ document: Arc<Document>,
+ },
+ Shutdown,
+}
+
+pub struct DiagnosticsDebouncer {
+ pub sender: Sender<DiagnosticsMessage>,
+ handle: Option<JoinHandle<()>>,
+}
+
+impl DiagnosticsDebouncer {
+ pub fn launch<A>(context: Arc<ServerContext>, action: A) -> Self
+ where
+ A: Fn(Arc<dyn Workspace>, Arc<Document>) + Send + Clone + 'static,
+ {
+ let (sender, receiver) = crossbeam_channel::unbounded();
+
+ let handle = thread::spawn(move || {
+ let pool = threadpool::Builder::new().build();
+ let last_task_time_by_uri: Arc<CHashMap<Arc<Uri>, Instant>> = Arc::default();
+ while let Ok(DiagnosticsMessage::Analyze {
+ workspace,
+ document,
+ }) = receiver.recv()
+ {
+ let delay = {
+ context
+ .options
+ .read()
+ .unwrap()
+ .diagnostics_delay
+ .unwrap_or(300)
+ };
+
+ if let Some(time) = last_task_time_by_uri.get(&document.uri) {
+ if time.elapsed().as_millis() < delay as u128 {
+ continue;
+ }
+ }
+
+ let last_task_time_by_uri = Arc::clone(&last_task_time_by_uri);
+ let action = action.clone();
+ pool.execute(move || {
+ thread::sleep(Duration::from_millis(delay));
+ last_task_time_by_uri.insert(Arc::clone(&document.uri), Instant::now());
+ action(workspace, document);
+ });
+ }
+ });
+
+ Self {
+ sender,
+ handle: Some(handle),
+ }
+ }
+}
+
+impl Drop for DiagnosticsDebouncer {
+ fn drop(&mut self) {
+ self.sender.send(DiagnosticsMessage::Shutdown).unwrap();
+ self.handle.take().unwrap().join().unwrap();
+ }
+}
diff --git a/support/texlab/src/diagnostics/latex.rs b/support/texlab/src/diagnostics/latex.rs
index 95fcaeeacf..b835f88398 100644
--- a/support/texlab/src/diagnostics/latex.rs
+++ b/support/texlab/src/diagnostics/latex.rs
@@ -1,113 +1,129 @@
+use std::sync::Arc;
+
+use cstree::TextRange;
+use lsp_types::{Diagnostic, DiagnosticSeverity};
+use multimap::MultiMap;
+
use crate::{
- protocol::{Diagnostic, DiagnosticSeverity, NumberOrString, Range, RangeExt, Uri},
- workspace::Document,
-};
-use chashmap::CHashMap;
-use futures::{
- future::{AbortHandle, Abortable, Aborted},
- lock::Mutex,
+ syntax::{latex, CstNode},
+ Document, LineIndexExt, Uri, Workspace,
};
-use log::trace;
-use once_cell::sync::Lazy;
-use regex::Regex;
-use std::process::Stdio;
-use tokio::{prelude::*, process::Command};
-
-#[derive(Debug, Default)]
-pub struct LatexDiagnosticsProvider {
- diagnostics_by_uri: CHashMap<Uri, Vec<Diagnostic>>,
- handle: Mutex<Option<AbortHandle>>,
-}
-impl LatexDiagnosticsProvider {
- pub fn get(&self, document: &Document) -> Vec<Diagnostic> {
- match self.diagnostics_by_uri.get(&document.uri) {
- Some(diagnostics) => diagnostics.to_owned(),
- None => Vec::new(),
- }
+pub fn analyze_latex_static(
+ workspace: &dyn Workspace,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ uri: &Uri,
+) -> Option<()> {
+ let document = workspace.get(uri)?;
+ if !document.uri.as_str().ends_with(".tex") {
+ return None;
}
- pub async fn update(&self, uri: &Uri, text: &str) {
- if uri.scheme() != "file" {
- return;
- }
+ let data = document.data.as_latex()?;
- let mut handle_guard = self.handle.lock().await;
- if let Some(handle) = &*handle_guard {
- handle.abort();
- }
+ for node in data.root.descendants() {
+ analyze_environment(&document, diagnostics_by_uri, node)
+ .or_else(|| analyze_curly_group(&document, diagnostics_by_uri, node))
+ .or_else(|| {
+ if node.kind() == latex::ERROR && node.first_token()?.text() == "}" {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document.line_index.line_col_lsp_range(node.text_range()),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Unexpected \"}\"".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
+ },
+ );
+ Some(())
+ } else {
+ None
+ }
+ });
+ }
- let (handle, registration) = AbortHandle::new_pair();
- *handle_guard = Some(handle);
- drop(handle_guard);
+ Some(())
+}
- let future = Abortable::new(
- async move {
- self.diagnostics_by_uri
- .insert(uri.clone(), lint(text.into()).await.unwrap_or_default());
+fn analyze_environment(
+ document: &Document,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ let environment = latex::Environment::cast(node)?;
+ let name1 = environment.begin()?.name()?.word()?;
+ let name2 = environment.end()?.name()?.word()?;
+ if name1.text() != name2.text() {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document.line_index.line_col_lsp_range(name1.text_range()),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Mismatched environment".to_string(),
+ related_information: None,
+ tags: None,
+ data: None,
},
- registration,
);
-
- if let Err(Aborted) = future.await {
- trace!("Killed ChkTeX because it took too long to execute")
- }
}
+ Some(())
}
-pub static LINE_REGEX: Lazy<Regex> =
- Lazy::new(|| Regex::new("(\\d+):(\\d+):(\\d+):(\\w+):(\\w+):(.*)").unwrap());
-
-async fn lint(text: String) -> io::Result<Vec<Diagnostic>> {
- let mut process: tokio::process::Child = Command::new("chktex")
- .args(&["-I0", "-f%l:%c:%d:%k:%n:%m\n"])
- .stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::null())
- .kill_on_drop(true)
- .spawn()?;
-
- process
- .stdin
- .take()
- .unwrap()
- .write_all(text.as_bytes())
- .await?;
-
- let mut stdout = String::new();
- process
- .stdout
- .take()
- .unwrap()
- .read_to_string(&mut stdout)
- .await?;
+fn analyze_curly_group(
+ document: &Document,
+ diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ if !matches!(
+ node.kind(),
+ latex::CURLY_GROUP
+ | latex::CURLY_GROUP_COMMAND
+ | latex::CURLY_GROUP_KEY_VALUE
+ | latex::CURLY_GROUP_WORD
+ | latex::CURLY_GROUP_WORD_LIST
+ ) {
+ return None;
+ }
- let mut diagnostics = Vec::new();
- for line in stdout.lines() {
- if let Some(captures) = LINE_REGEX.captures(line) {
- let line = captures[1].parse::<u64>().unwrap() - 1;
- let character = captures[2].parse::<u64>().unwrap() - 1;
- let digit = captures[3].parse::<u64>().unwrap();
- let kind = &captures[4];
- let code = &captures[5];
- let message = captures[6].into();
- let range = Range::new_simple(line, character, line, character + digit);
- let severity = match kind {
- "Message" => DiagnosticSeverity::Information,
- "Warning" => DiagnosticSeverity::Warning,
- _ => DiagnosticSeverity::Error,
- };
+ let is_inside_verbatim_environment = node
+ .ancestors()
+ .filter_map(latex::Environment::cast)
+ .filter_map(|env| env.begin())
+ .filter_map(|begin| begin.name())
+ .filter_map(|name| name.word())
+ .any(|name| ["asy", "lstlisting", "minted", "verbatim"].contains(&name.text()));
- diagnostics.push(Diagnostic {
- source: Some("chktex".into()),
- code: Some(NumberOrString::String(code.into())),
- message,
- severity: Some(severity),
- range,
+ if !is_inside_verbatim_environment
+ && !node
+ .children_with_tokens()
+ .filter_map(|element| element.into_token())
+ .any(|token| token.kind() == latex::R_CURLY)
+ {
+ diagnostics_by_uri.insert(
+ Arc::clone(&document.uri),
+ Diagnostic {
+ range: document
+ .line_index
+ .line_col_lsp_range(TextRange::empty(node.text_range().end())),
+ severity: Some(DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("texlab".to_string()),
+ message: "Missing \"}\" inserted".to_string(),
related_information: None,
tags: None,
- })
- }
+ data: None,
+ },
+ );
}
- Ok(diagnostics)
+
+ Some(())
}
diff --git a/support/texlab/src/diagnostics/mod.rs b/support/texlab/src/diagnostics/mod.rs
deleted file mode 100644
index 906da9858f..0000000000
--- a/support/texlab/src/diagnostics/mod.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-mod bibtex;
-mod build;
-mod latex;
-
-pub use self::{
- bibtex::{BibtexDiagnosticsProvider, BibtexError, BibtexErrorCode},
- build::BuildDiagnosticsProvider,
- latex::LatexDiagnosticsProvider,
-};
-
-use crate::{protocol::Diagnostic, workspace::Document};
-
-#[derive(Debug, Default)]
-pub struct DiagnosticsManager {
- pub bibtex: BibtexDiagnosticsProvider,
- pub latex: LatexDiagnosticsProvider,
- pub build: BuildDiagnosticsProvider,
-}
-
-impl DiagnosticsManager {
- pub async fn get(&self, doc: &Document) -> Vec<Diagnostic> {
- let mut diagnostics = Vec::new();
- diagnostics.append(&mut self.bibtex.get(doc));
- diagnostics.append(&mut self.latex.get(doc));
- diagnostics.append(&mut self.build.get(doc).await);
- diagnostics
- }
-}
diff --git a/support/texlab/src/dispatch.rs b/support/texlab/src/dispatch.rs
new file mode 100644
index 0000000000..a080016480
--- /dev/null
+++ b/support/texlab/src/dispatch.rs
@@ -0,0 +1,81 @@
+use anyhow::Result;
+use log::warn;
+use lsp_server::{ErrorCode, Notification, Request, RequestId, Response};
+use serde::de::DeserializeOwned;
+
+pub struct NotificationDispatcher {
+ not: Option<Notification>,
+}
+
+impl NotificationDispatcher {
+ pub fn new(not: Notification) -> Self {
+ Self { not: Some(not) }
+ }
+
+ pub fn on<N, F>(mut self, handler: F) -> Result<Self>
+ where
+ N: lsp_types::notification::Notification,
+ N::Params: DeserializeOwned,
+ F: FnOnce(N::Params) -> Result<()>,
+ {
+ if let Some(not) = self.not {
+ match not.extract::<N::Params>(N::METHOD) {
+ Ok(params) => {
+ handler(params)?;
+ self.not = None;
+ }
+ Err(not) => {
+ self.not = Some(not);
+ }
+ };
+ }
+ Ok(self)
+ }
+
+ pub fn default(self) {
+ if let Some(not) = &self.not {
+ warn!("Unknown notification: {}", not.method);
+ }
+ }
+}
+
+pub struct RequestDispatcher {
+ req: Option<Request>,
+}
+
+impl RequestDispatcher {
+ pub fn new(req: Request) -> Self {
+ Self { req: Some(req) }
+ }
+
+ pub fn on<R, F>(mut self, handler: F) -> Result<Self>
+ where
+ R: lsp_types::request::Request,
+ R::Params: DeserializeOwned,
+ F: FnOnce(RequestId, R::Params) -> Result<()>,
+ {
+ if let Some(req) = self.req {
+ match req.extract::<R::Params>(R::METHOD) {
+ Ok((id, params)) => {
+ handler(id, params)?;
+ self.req = None;
+ }
+ Err(req) => {
+ self.req = Some(req);
+ }
+ }
+ }
+ Ok(self)
+ }
+
+ pub fn default(self) -> Option<Response> {
+ self.req.map(|req| {
+ warn!("Unknown request: {}", req.method);
+ Response::new_err(
+ req.id,
+ ErrorCode::MethodNotFound as i32,
+ "method not found".to_string(),
+ )
+ })
+ }
+}
diff --git a/support/texlab/src/distro.rs b/support/texlab/src/distro.rs
new file mode 100644
index 0000000000..1e67a14285
--- /dev/null
+++ b/support/texlab/src/distro.rs
@@ -0,0 +1,74 @@
+mod kpsewhich;
+mod miktex;
+mod texlive;
+
+use std::process::{Command, Stdio};
+
+use anyhow::Result;
+use derive_more::Display;
+use log::warn;
+
+pub use kpsewhich::Resolver;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
+pub enum DistributionKind {
+ #[display(fmt = "TeXLive")]
+ Texlive,
+ #[display(fmt = "MikTeX")]
+ Miktex,
+ #[display(fmt = "Tectonic")]
+ Tectonic,
+ #[display(fmt = "Unknown")]
+ Unknown,
+}
+
+#[derive(Debug, Clone)]
+pub struct Distribution {
+ pub kind: DistributionKind,
+ pub resolver: Resolver,
+}
+
+impl Distribution {
+ pub fn detect() -> Self {
+ let kind = match Command::new("latex").arg("--version").output() {
+ Ok(output) => {
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ if stdout.contains("TeX Live") {
+ DistributionKind::Texlive
+ } else if stdout.contains("MiKTeX") {
+ DistributionKind::Miktex
+ } else {
+ DistributionKind::Unknown
+ }
+ }
+ Err(_) => {
+ if Command::new("tectonic")
+ .arg("--version")
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .status()
+ .is_ok()
+ {
+ DistributionKind::Tectonic
+ } else {
+ DistributionKind::Unknown
+ }
+ }
+ };
+
+ let resolver = match kind {
+ DistributionKind::Texlive => Self::load_resolver(texlive::load_resolver),
+ DistributionKind::Miktex => Self::load_resolver(miktex::load_resolver),
+ DistributionKind::Tectonic | DistributionKind::Unknown => Resolver::default(),
+ };
+ Self { kind, resolver }
+ }
+
+ fn load_resolver(loader: impl FnOnce() -> Result<Resolver>) -> Resolver {
+ match loader() {
+ Ok(resolver) => return resolver,
+ Err(why) => warn!("Failed to load resolver: {}", why),
+ };
+ Resolver::default()
+ }
+}
diff --git a/support/texlab/src/distro/kpsewhich.rs b/support/texlab/src/distro/kpsewhich.rs
new file mode 100644
index 0000000000..2dcc98118f
--- /dev/null
+++ b/support/texlab/src/distro/kpsewhich.rs
@@ -0,0 +1,74 @@
+use std::{
+ env,
+ ffi::OsStr,
+ fs,
+ path::{Path, PathBuf},
+ process::Command,
+};
+
+use anyhow::Result;
+use rustc_hash::FxHashMap;
+use smol_str::SmolStr;
+
+use crate::DocumentLanguage;
+
+#[derive(Debug, PartialEq, Eq, Clone, Default)]
+pub struct Resolver {
+ pub files_by_name: FxHashMap<SmolStr, PathBuf>,
+}
+
+impl Resolver {
+ pub fn new(files_by_name: FxHashMap<SmolStr, PathBuf>) -> Self {
+ Self { files_by_name }
+ }
+}
+
+pub fn parse_database(
+ root_directories: &[PathBuf],
+ mut reader: impl FnMut(&Path) -> Result<Vec<PathBuf>>,
+) -> Result<Resolver> {
+ let mut files_by_name = FxHashMap::default();
+ for directory in root_directories {
+ for path in reader(directory)? {
+ if DocumentLanguage::by_path(&path).is_some() {
+ if let Some(path) = make_absolute(root_directories, &path) {
+ if let Some(name) = path.file_name().and_then(OsStr::to_str).map(Into::into) {
+ files_by_name.insert(name, path);
+ }
+ }
+ }
+ }
+ }
+ Ok(Resolver::new(files_by_name))
+}
+
+fn make_absolute(root_directories: &[PathBuf], relative_path: &Path) -> Option<PathBuf> {
+ for dir in root_directories.iter().rev() {
+ if let Ok(path) = fs::canonicalize(dir.join(&relative_path)) {
+ return Some(path);
+ }
+ }
+ None
+}
+
+pub fn root_directories() -> Result<Vec<PathBuf>> {
+ let texmf = run(&["-var-value", "TEXMF"])?;
+ let expand_arg = format!("--expand-braces={}", texmf);
+ let expanded = run(&[&expand_arg])?;
+ let directories = env::split_paths(&expanded.replace("!", ""))
+ .filter(|path| path.exists())
+ .collect();
+ Ok(directories)
+}
+
+fn run(args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> Result<String> {
+ let output = Command::new("kpsewhich").args(args).output()?;
+
+ let result = String::from_utf8(output.stdout)?
+ .lines()
+ .next()
+ .unwrap()
+ .into();
+
+ Ok(result)
+}
diff --git a/support/texlab/src/tex/miktex.rs b/support/texlab/src/distro/miktex.rs
index b543aa8a1b..563c8445e3 100644
--- a/support/texlab/src/tex/miktex.rs
+++ b/support/texlab/src/distro/miktex.rs
@@ -1,45 +1,19 @@
-use super::{
- compile,
- kpsewhich::{self, KpsewhichError, Resolver},
- Artifacts, CompileError, CompileParams, Distribution, DistributionKind,
-};
-use async_trait::async_trait;
-use byteorder::{LittleEndian, ReadBytesExt};
-use futures::lock::Mutex;
use std::{
ffi::OsStr,
+ fs,
io::{self, Cursor},
path::{Path, PathBuf},
- sync::Arc,
};
-use tokio::fs;
-
-#[derive(Debug, Default)]
-pub struct Miktex {
- resolver: Mutex<Arc<Resolver>>,
-}
-
-#[async_trait]
-impl Distribution for Miktex {
- fn kind(&self) -> DistributionKind {
- DistributionKind::Miktex
- }
- async fn compile<'a>(&'a self, params: CompileParams<'a>) -> Result<Artifacts, CompileError> {
- compile(params).await
- }
+use anyhow::{Context, Result};
+use byteorder::{LittleEndian, ReadBytesExt};
- async fn load(&self) -> Result<(), KpsewhichError> {
- let root_directories = kpsewhich::root_directories().await?;
- let resolver = kpsewhich::parse_database(&root_directories, read_database).await?;
- *self.resolver.lock().await = Arc::new(resolver);
- Ok(())
- }
+use super::kpsewhich::{self, Resolver};
- async fn resolver(&self) -> Arc<Resolver> {
- let resolver = self.resolver.lock().await;
- Arc::clone(&resolver)
- }
+pub fn load_resolver() -> Result<Resolver> {
+ let root_directories = kpsewhich::root_directories()?;
+ let resolver = kpsewhich::parse_database(&root_directories, read_database)?;
+ Ok(resolver)
}
const DATABASE_PATH: &str = "miktex/data/le";
@@ -49,18 +23,17 @@ const FNDB_TABLE_POINTER_OFFSET: usize = 4 * FNDB_WORD_SIZE;
const FNDB_TABLE_SIZE_OFFSET: usize = 6 * FNDB_WORD_SIZE;
const FNDB_ENTRY_SIZE: usize = 4 * FNDB_WORD_SIZE;
-async fn read_database(directory: &Path) -> Result<Vec<PathBuf>, KpsewhichError> {
+fn read_database(directory: &Path) -> Result<Vec<PathBuf>> {
let database_directory = directory.join(DATABASE_PATH);
if !database_directory.exists() {
return Ok(Vec::new());
}
let mut database = Vec::new();
- let mut files: tokio::fs::ReadDir = fs::read_dir(database_directory).await?;
- while let Some(file) = files.next_entry().await? {
+ for file in fs::read_dir(database_directory)?.filter_map(Result::ok) {
if file.path().extension().and_then(OsStr::to_str) == Some("fndb-5") {
- let bytes = fs::read(file.path()).await?;
- database.extend(parse_database(&bytes).map_err(|_| KpsewhichError::CorruptDatabase)?);
+ let bytes = fs::read(file.path())?;
+ database.extend(parse_database(&bytes).context("parsing kpsewhich database")?);
}
}
Ok(database)
diff --git a/support/texlab/src/distro/texlive.rs b/support/texlab/src/distro/texlive.rs
new file mode 100644
index 0000000000..c9b4951e34
--- /dev/null
+++ b/support/texlab/src/distro/texlive.rs
@@ -0,0 +1,43 @@
+use std::{
+ fs, io,
+ path::{Path, PathBuf},
+ str::Lines,
+};
+
+use anyhow::Result;
+
+use super::kpsewhich::{self, Resolver};
+
+pub fn load_resolver() -> Result<Resolver> {
+ let root_directories = kpsewhich::root_directories()?;
+ let resolver = kpsewhich::parse_database(&root_directories, read_database)?;
+ Ok(resolver)
+}
+
+const DATABASE_PATH: &str = "ls-R";
+
+fn read_database(directory: &Path) -> Result<Vec<PathBuf>> {
+ let file = directory.join(DATABASE_PATH);
+ if !file.is_file() {
+ return Ok(Vec::new());
+ }
+
+ let text = fs::read_to_string(file)?;
+ let files = parse_database(text.lines())?;
+ Ok(files)
+}
+
+fn parse_database(lines: Lines) -> io::Result<Vec<PathBuf>> {
+ let mut paths = Vec::new();
+ let mut directory = "";
+
+ for line in lines.filter(|x| !x.trim().is_empty() && !x.starts_with('%')) {
+ if line.ends_with(':') {
+ directory = &line[..line.len() - 1];
+ } else {
+ let path = PathBuf::from(directory).join(line);
+ paths.push(path);
+ }
+ }
+ Ok(paths)
+}
diff --git a/support/texlab/src/feature.rs b/support/texlab/src/feature.rs
deleted file mode 100644
index 2b32b64188..0000000000
--- a/support/texlab/src/feature.rs
+++ /dev/null
@@ -1,405 +0,0 @@
-use crate::{
- components::{Component, COMPONENT_DATABASE},
- protocol::*,
- tex::{Distribution, Language, UnknownDistribution},
- workspace::{Document, DocumentContent, DocumentParams, Snapshot},
-};
-use async_trait::async_trait;
-use itertools::Itertools;
-use std::{
- env,
- path::{Path, PathBuf},
- sync::Arc,
-};
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct DocumentView {
- pub snapshot: Arc<Snapshot>,
- pub current: Arc<Document>,
- pub related: Vec<Arc<Document>>,
-}
-
-impl DocumentView {
- pub fn analyze(
- snapshot: Arc<Snapshot>,
- current: Arc<Document>,
- options: &Options,
- current_dir: &Path,
- ) -> Self {
- let related = snapshot.relations(&current.uri, options, current_dir);
- Self {
- snapshot,
- current,
- related,
- }
- }
-
- pub fn components(&self) -> Vec<&'static Component> {
- let mut start_components = vec![COMPONENT_DATABASE.kernel()];
- for doc in &self.related {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .components
- .iter()
- .flat_map(|file| COMPONENT_DATABASE.find(file))
- .for_each(|component| start_components.push(component))
- }
- }
-
- let mut all_components = Vec::new();
- for component in start_components {
- all_components.push(component);
- component
- .references
- .iter()
- .flat_map(|file| COMPONENT_DATABASE.find(&file))
- .for_each(|component| all_components.push(component))
- }
-
- all_components
- .into_iter()
- .unique_by(|component| &component.file_names)
- .collect()
- }
-}
-
-#[derive(Clone)]
-pub struct FeatureRequest<P> {
- pub params: P,
- pub view: DocumentView,
- pub distro: Arc<dyn Distribution>,
- pub client_capabilities: Arc<ClientCapabilities>,
- pub options: Options,
- pub current_dir: Arc<PathBuf>,
-}
-
-impl<P> FeatureRequest<P> {
- pub fn snapshot(&self) -> &Snapshot {
- &self.view.snapshot
- }
-
- pub fn current(&self) -> &Document {
- &self.view.current
- }
-
- pub fn related(&self) -> &[Arc<Document>] {
- &self.view.related
- }
-}
-
-#[async_trait]
-pub trait FeatureProvider {
- type Params;
- type Output;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output;
-}
-
-type ListProvider<P, O> = Box<dyn FeatureProvider<Params = P, Output = Vec<O>> + Send + Sync>;
-
-#[derive(Default)]
-pub struct ConcatProvider<P, O> {
- providers: Vec<ListProvider<P, O>>,
-}
-
-impl<P, O> ConcatProvider<P, O> {
- pub fn new(providers: Vec<ListProvider<P, O>>) -> Self {
- Self { providers }
- }
-}
-
-#[async_trait]
-impl<P, O> FeatureProvider for ConcatProvider<P, O>
-where
- P: Send + Sync,
- O: Send + Sync,
-{
- type Params = P;
- type Output = Vec<O>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<P>) -> Vec<O> {
- let mut items = Vec::new();
- for provider in &self.providers {
- items.append(&mut provider.execute(req).await);
- }
- items
- }
-}
-
-type OptionProvider<P, O> = Box<dyn FeatureProvider<Params = P, Output = Option<O>> + Send + Sync>;
-
-#[derive(Default)]
-pub struct ChoiceProvider<P, O> {
- providers: Vec<OptionProvider<P, O>>,
-}
-
-impl<P, O> ChoiceProvider<P, O> {
- pub fn new(providers: Vec<OptionProvider<P, O>>) -> Self {
- Self { providers }
- }
-}
-
-#[async_trait]
-impl<P, O> FeatureProvider for ChoiceProvider<P, O>
-where
- P: Send + Sync,
- O: Send + Sync,
-{
- type Params = P;
- type Output = Option<O>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<P>) -> Option<O> {
- for provider in &self.providers {
- let item = provider.execute(req).await;
- if item.is_some() {
- return item;
- }
- }
- None
- }
-}
-
-#[derive(Debug)]
-pub struct FeatureTester {
- main: String,
- files: Vec<(String, String)>,
- distro: Arc<dyn Distribution>,
- position: Position,
- new_name: String,
- include_declaration: bool,
- client_capabilities: Arc<ClientCapabilities>,
- current_dir: Arc<PathBuf>,
- root_dir: Option<PathBuf>,
- output_dir: Option<PathBuf>,
-}
-
-impl Default for FeatureTester {
- fn default() -> Self {
- Self::new()
- }
-}
-
-impl FeatureTester {
- pub fn new() -> Self {
- Self {
- main: String::new(),
- files: Vec::new(),
- distro: Arc::new(UnknownDistribution::default()),
- position: Position::default(),
- new_name: String::new(),
- include_declaration: false,
- client_capabilities: Arc::default(),
- current_dir: Arc::new(env::temp_dir()),
- root_dir: None,
- output_dir: None,
- }
- }
-
- pub fn main<S: Into<String>>(&mut self, name: S) -> &mut Self {
- self.main = name.into();
- self
- }
-
- pub fn file<S, T>(&mut self, name: S, text: T) -> &mut Self
- where
- S: Into<String>,
- T: Into<String>,
- {
- self.files.push((name.into(), text.into()));
- self
- }
-
- pub fn position(&mut self, line: u64, character: u64) -> &mut Self {
- self.position = Position::new(line, character);
- self
- }
-
- pub fn new_name<S: Into<String>>(&mut self, value: S) -> &mut Self {
- self.new_name = value.into();
- self
- }
-
- pub fn include_declaration(&mut self) -> &mut Self {
- self.include_declaration = true;
- self
- }
-
- pub fn root_directory<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
- self.root_dir = Some(path.into());
- self
- }
-
- pub fn output_directory<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
- self.output_dir = Some(path.into());
- self
- }
-
- pub fn uri(name: &str) -> Uri {
- let path = env::temp_dir().join(name);
- Uri::from_file_path(path).unwrap()
- }
-
- fn identifier(&self) -> TextDocumentIdentifier {
- let uri = Self::uri(&self.main);
- TextDocumentIdentifier::new(uri.into())
- }
-
- fn options(&self) -> Options {
- Options {
- latex: Some(LatexOptions {
- build: Some(LatexBuildOptions {
- output_directory: self.output_dir.clone(),
- ..LatexBuildOptions::default()
- }),
- root_directory: self.root_dir.clone(),
- ..LatexOptions::default()
- }),
- ..Options::default()
- }
- }
-
- async fn view(&self) -> DocumentView {
- let mut snapshot = Snapshot::new();
- let resolver = self.distro.resolver().await;
- let options = self.options();
- for (name, text) in &self.files {
- let uri = Self::uri(name);
- let path = uri.to_file_path().unwrap();
- let language = path
- .extension()
- .and_then(|ext| ext.to_str())
- .and_then(Language::by_extension)
- .unwrap();
- let doc = Document::open(DocumentParams {
- uri,
- text: text.trim().into(),
- language,
- resolver: &resolver,
- options: &options,
- current_dir: &self.current_dir,
- });
- snapshot.push(doc);
- }
- let current = snapshot.find(&Self::uri(&self.main)).unwrap();
- DocumentView::analyze(Arc::new(snapshot), current, &options, &self.current_dir)
- }
-
- async fn request<P>(&self, params: P) -> FeatureRequest<P> {
- FeatureRequest {
- params,
- view: self.view().await,
- client_capabilities: Arc::clone(&self.client_capabilities),
- distro: self.distro.clone(),
- options: self.options(),
- current_dir: Arc::clone(&self.current_dir),
- }
- }
-
- pub async fn test_position<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = TextDocumentPositionParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = TextDocumentPositionParams::new(text_document, self.position);
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_completion<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = CompletionParams, Output = O>,
- {
- let req = self.test_completion_request().await;
- provider.execute(&req).await
- }
-
- pub async fn test_completion_request(&self) -> FeatureRequest<CompletionParams> {
- let params = CompletionParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(),
- self.position,
- ),
- context: None,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.request(params).await
- }
-
- pub async fn test_folding<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = FoldingRangeParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = FoldingRangeParams {
- text_document,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_link<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = DocumentLinkParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = DocumentLinkParams {
- text_document,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_reference<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = ReferenceParams, Output = O>,
- {
- let params = ReferenceParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(),
- self.position,
- ),
- context: ReferenceContext {
- include_declaration: self.include_declaration,
- },
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_rename<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = RenameParams, Output = O>,
- {
- let params = RenameParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(),
- self.position,
- ),
- new_name: self.new_name.clone(),
- work_done_progress_params: WorkDoneProgressParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_symbol<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = DocumentSymbolParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = DocumentSymbolParams {
- text_document,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-}
diff --git a/support/texlab/src/features.rs b/support/texlab/src/features.rs
new file mode 100644
index 0000000000..09743c0035
--- /dev/null
+++ b/support/texlab/src/features.rs
@@ -0,0 +1,272 @@
+mod build;
+#[cfg(feature = "completion")]
+mod completion;
+mod cursor;
+mod definition;
+mod folding;
+mod formatting;
+mod forward_search;
+mod highlight;
+mod hover;
+mod link;
+mod lsp_kinds;
+mod reference;
+mod rename;
+#[cfg(feature = "semantic")]
+mod semantic;
+mod symbol;
+
+use std::sync::Arc;
+
+use crate::{Document, ServerContext, Workspace, WorkspaceSubset};
+
+#[cfg(feature = "completion")]
+pub use self::completion::{complete, CompletionItemData, COMPLETION_LIMIT};
+#[cfg(feature = "semantic")]
+pub use self::semantic::{find_semantic_tokens_range, legend};
+pub use self::{
+ build::{build_document, BuildParams, BuildResult, BuildStatus},
+ definition::goto_definition,
+ folding::find_foldings,
+ formatting::format_source_code,
+ forward_search::{execute_forward_search, ForwardSearchResult, ForwardSearchStatus},
+ highlight::find_document_highlights,
+ hover::find_hover,
+ link::find_document_links,
+ reference::find_all_references,
+ rename::{prepare_rename_all, rename_all},
+ symbol::{find_document_symbols, find_workspace_symbols},
+};
+
+#[derive(Clone)]
+pub struct FeatureRequest<P> {
+ pub context: Arc<ServerContext>,
+ pub params: P,
+ pub workspace: Arc<dyn Workspace>,
+ pub subset: WorkspaceSubset,
+}
+
+impl<P> FeatureRequest<P> {
+ pub fn main_document(&self) -> &Document {
+ &self.subset.documents[0]
+ }
+}
+
+#[cfg(test)]
+mod testing {
+ use std::{path::PathBuf, sync::Arc};
+
+ use lsp_types::{
+ ClientCapabilities, ClientInfo, CompletionParams, DocumentFormattingParams,
+ DocumentHighlightParams, DocumentLinkParams, FoldingRangeParams, FormattingOptions,
+ GotoDefinitionParams, HoverParams, PartialResultParams, Position, ReferenceContext,
+ ReferenceParams, RenameParams, TextDocumentIdentifier, TextDocumentPositionParams,
+ WorkDoneProgressParams,
+ };
+ use typed_builder::TypedBuilder;
+
+ use crate::{
+ create_workspace_fast, distro::Resolver, DocumentLanguage, Options, ServerContext, Uri,
+ Workspace, WorkspaceSource,
+ };
+
+ use super::*;
+
+ #[derive(Debug, Clone, TypedBuilder)]
+ pub struct FeatureTester<'a> {
+ main: &'a str,
+
+ files: Vec<(&'a str, &'a str)>,
+
+ #[builder(default)]
+ line: u32,
+
+ #[builder(default)]
+ character: u32,
+
+ #[builder(default)]
+ new_name: &'a str,
+
+ #[builder(default)]
+ include_declaration: bool,
+
+ #[builder(default)]
+ client_capabilities: ClientCapabilities,
+
+ #[builder(default)]
+ client_info: Option<ClientInfo>,
+
+ #[builder(default)]
+ resolver: Resolver,
+
+ #[builder(default=std::env::temp_dir())]
+ current_directory: PathBuf,
+
+ #[builder(default, setter(strip_option))]
+ root_directory: Option<PathBuf>,
+
+ #[builder(default, setter(strip_option))]
+ aux_directory: Option<PathBuf>,
+ }
+
+ impl<'a> FeatureTester<'a> {
+ pub fn uri(&self, name: &str) -> Arc<Uri> {
+ let path = self.current_directory.join(name);
+ Arc::new(Uri::from_file_path(path).unwrap())
+ }
+
+ fn options(&self) -> Options {
+ let mut options = Options::default();
+ options.aux_directory = self.aux_directory.clone();
+ options.root_directory = self.root_directory.clone();
+ options
+ }
+
+ fn identifier(&self) -> TextDocumentIdentifier {
+ let uri = self.uri(&self.main);
+ TextDocumentIdentifier::new(uri.as_ref().clone().into())
+ }
+
+ fn context(&self) -> Arc<ServerContext> {
+ let cx = ServerContext::new(self.current_directory.clone());
+ *cx.client_capabilities.lock().unwrap() = self.client_capabilities.clone();
+ *cx.client_info.lock().unwrap() = self.client_info.clone();
+ *cx.options.write().unwrap() = self.options();
+ *cx.resolver.lock().unwrap() = self.resolver.clone();
+ Arc::new(cx)
+ }
+
+ fn workspace(&self, cx: Arc<ServerContext>) -> Arc<dyn Workspace> {
+ let workspace = create_workspace_fast(cx).unwrap();
+ for (name, source_code) in &self.files {
+ let uri = self.uri(name);
+ let path = uri.to_file_path().unwrap();
+ let language = DocumentLanguage::by_path(&path).expect("unknown document language");
+ workspace.open(
+ uri,
+ source_code.trim().to_string(),
+ language,
+ WorkspaceSource::Client,
+ );
+ }
+ Arc::new(workspace)
+ }
+
+ fn request<P>(&self, params: P) -> FeatureRequest<P> {
+ let cx = self.context();
+ let workspace = self.workspace(Arc::clone(&cx));
+ let subset = workspace.subset(self.uri(self.main)).unwrap();
+ FeatureRequest {
+ context: cx,
+ workspace,
+ subset,
+ params,
+ }
+ }
+
+ pub fn link(self) -> FeatureRequest<DocumentLinkParams> {
+ let text_document = self.identifier();
+ let params = DocumentLinkParams {
+ text_document,
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn folding(self) -> FeatureRequest<FoldingRangeParams> {
+ let text_document = self.identifier();
+ let params = FoldingRangeParams {
+ text_document,
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn reference(self) -> FeatureRequest<ReferenceParams> {
+ let params = ReferenceParams {
+ text_document_position: TextDocumentPositionParams::new(
+ self.identifier(),
+ Position::new(self.line, self.character),
+ ),
+ context: ReferenceContext {
+ include_declaration: self.include_declaration,
+ },
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn hover(self) -> FeatureRequest<HoverParams> {
+ let params = HoverParams {
+ text_document_position_params: TextDocumentPositionParams::new(
+ self.identifier(),
+ Position::new(self.line, self.character),
+ ),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn completion(self) -> FeatureRequest<CompletionParams> {
+ let params = CompletionParams {
+ text_document_position: TextDocumentPositionParams::new(
+ self.identifier(),
+ Position::new(self.line, self.character),
+ ),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ context: None,
+ };
+
+ self.request(params)
+ }
+
+ pub fn definition(self) -> FeatureRequest<GotoDefinitionParams> {
+ let params = GotoDefinitionParams {
+ text_document_position_params: TextDocumentPositionParams::new(
+ self.identifier(),
+ Position::new(self.line, self.character),
+ ),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn rename(self) -> FeatureRequest<RenameParams> {
+ let params = RenameParams {
+ text_document_position: TextDocumentPositionParams::new(
+ self.identifier(),
+ Position::new(self.line, self.character),
+ ),
+ new_name: self.new_name.to_string(),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn formatting(self) -> FeatureRequest<DocumentFormattingParams> {
+ let params = DocumentFormattingParams {
+ text_document: self.identifier(),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ options: FormattingOptions::default(),
+ };
+ self.request(params)
+ }
+
+ pub fn highlight(self) -> FeatureRequest<DocumentHighlightParams> {
+ let params = DocumentHighlightParams {
+ text_document_position_params: TextDocumentPositionParams::new(
+ self.identifier(),
+ Position::new(self.line, self.character),
+ ),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ };
+ self.request(params)
+ }
+ }
+}
diff --git a/support/texlab/src/features/build.rs b/support/texlab/src/features/build.rs
new file mode 100644
index 0000000000..c6a670528f
--- /dev/null
+++ b/support/texlab/src/features/build.rs
@@ -0,0 +1,133 @@
+use std::{
+ io::{self, BufRead, BufReader, Read},
+ path::Path,
+ process::{Command, Stdio},
+ thread,
+};
+
+use cancellation::CancellationToken;
+use crossbeam_channel::Sender;
+use encoding_rs_io::DecodeReaderBytesBuilder;
+use lsp_types::TextDocumentIdentifier;
+use serde::{Deserialize, Serialize};
+use serde_repr::{Deserialize_repr, Serialize_repr};
+
+use crate::Options;
+
+use super::FeatureRequest;
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct BuildParams {
+ pub text_document: TextDocumentIdentifier,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize_repr, Deserialize_repr)]
+#[repr(i32)]
+pub enum BuildStatus {
+ Success = 0,
+ Error = 1,
+ Failure = 2,
+ Cancelled = 3,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct BuildResult {
+ pub status: BuildStatus,
+}
+
+pub fn build_document(
+ request: FeatureRequest<BuildParams>,
+ _cancellation_token: &CancellationToken,
+ log_sender: Sender<String>,
+) -> BuildResult {
+ let document = request
+ .subset
+ .documents
+ .iter()
+ .find(|document| {
+ if let Some(data) = document.data.as_latex() {
+ data.extras.has_document_environment
+ } else {
+ false
+ }
+ })
+ .map(|document| document.as_ref())
+ .unwrap_or_else(|| request.main_document());
+
+ if document.uri.scheme() != "file" {
+ return BuildResult {
+ status: BuildStatus::Failure,
+ };
+ }
+ log::info!("Building document {}", document.uri.as_str());
+
+ let options = { request.context.options.read().unwrap().clone() };
+
+ let status = match build_internal(&document.uri.to_file_path().unwrap(), &options, log_sender) {
+ Ok(true) => BuildStatus::Success,
+ Ok(false) => BuildStatus::Error,
+ Err(why) => {
+ log::error!("Failed to execute textDocument/build: {}", why);
+ BuildStatus::Failure
+ }
+ };
+ BuildResult { status }
+}
+
+fn build_internal(path: &Path, options: &Options, log_sender: Sender<String>) -> io::Result<bool> {
+ let build_dir = options
+ .root_directory
+ .as_ref()
+ .map(AsRef::as_ref)
+ .or_else(|| path.parent())
+ .unwrap();
+
+ let args: Vec<_> = options
+ .build
+ .args()
+ .into_iter()
+ .map(|arg| replace_placeholder(arg, path))
+ .collect();
+
+ let mut process = Command::new(options.build.executable())
+ .args(args)
+ .stdin(Stdio::null())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .current_dir(build_dir)
+ .spawn()?;
+
+ track_output(process.stdout.take().unwrap(), log_sender.clone());
+ track_output(process.stderr.take().unwrap(), log_sender.clone());
+
+ if !options.build.is_continuous {
+ process.wait().map(|status| status.success())
+ } else {
+ Ok(true)
+ }
+}
+
+fn replace_placeholder(arg: String, file: &Path) -> String {
+ if arg.starts_with('"') || arg.ends_with('"') {
+ arg
+ } else {
+ arg.replace("%f", &file.to_string_lossy())
+ }
+}
+
+fn track_output(output: impl Read + Send + 'static, sender: Sender<String>) {
+ let reader = BufReader::new(
+ DecodeReaderBytesBuilder::new()
+ .encoding(Some(encoding_rs::UTF_8))
+ .utf8_passthru(true)
+ .strip_bom(true)
+ .build(output),
+ );
+ thread::spawn(move || {
+ for line in reader.lines() {
+ sender.send(line.unwrap()).unwrap();
+ }
+ });
+}
diff --git a/support/texlab/src/features/completion.rs b/support/texlab/src/features/completion.rs
new file mode 100644
index 0000000000..13c7aad22b
--- /dev/null
+++ b/support/texlab/src/features/completion.rs
@@ -0,0 +1,567 @@
+mod acronym_ref;
+mod argument;
+mod begin_command;
+mod citation;
+mod color;
+mod color_model;
+mod component_command;
+mod component_environment;
+mod entry_type;
+mod field;
+mod glossary_ref;
+mod import;
+mod include;
+mod label;
+mod theorem;
+mod tikz_library;
+mod types;
+mod user_command;
+mod user_environment;
+mod util;
+
+use cancellation::CancellationToken;
+use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
+use lsp_types::{
+ CompletionItem, CompletionList, CompletionParams, CompletionTextEdit, Documentation,
+ InsertTextFormat, MarkupContent, MarkupKind, TextEdit,
+};
+use rustc_hash::FxHashSet;
+
+use crate::{
+ syntax::{bibtex, latex, CstNode},
+ LineIndexExt,
+};
+
+use self::{
+ acronym_ref::complete_acronyms,
+ argument::complete_arguments,
+ begin_command::complete_begin_command,
+ citation::complete_citations,
+ color::complete_colors,
+ color_model::complete_color_models,
+ component_command::complete_component_commands,
+ component_environment::complete_component_environments,
+ entry_type::complete_entry_types,
+ field::complete_fields,
+ glossary_ref::complete_glossary_entries,
+ import::complete_imports,
+ include::complete_includes,
+ label::complete_labels,
+ theorem::complete_theorem_environments,
+ tikz_library::complete_tikz_libraries,
+ types::{InternalCompletionItem, InternalCompletionItemData},
+ user_command::complete_user_commands,
+ user_environment::complete_user_environments,
+ util::{adjust_kind, component_detail, image_documentation},
+};
+
+pub use self::types::CompletionItemData;
+
+use super::{
+ cursor::{Cursor, CursorContext},
+ lsp_kinds::Structure,
+ FeatureRequest,
+};
+
+pub const COMPLETION_LIMIT: usize = 50;
+
+pub fn complete(
+ request: FeatureRequest<CompletionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<CompletionList> {
+ let mut items = Vec::new();
+ let context = CursorContext::new(request);
+ log::debug!("[Completion] Cursor: {:?}", context.cursor);
+ complete_entry_types(&context, &mut items, cancellation_token);
+ complete_fields(&context, &mut items, cancellation_token);
+ complete_arguments(&context, &mut items, cancellation_token);
+ complete_citations(&context, &mut items, cancellation_token);
+ complete_imports(&context, &mut items, cancellation_token);
+ complete_colors(&context, &mut items, cancellation_token);
+ complete_color_models(&context, &mut items, cancellation_token);
+ complete_acronyms(&context, &mut items, cancellation_token);
+ complete_glossary_entries(&context, &mut items, cancellation_token);
+ complete_includes(&context, &mut items, cancellation_token);
+ complete_labels(&context, &mut items, cancellation_token);
+ complete_tikz_libraries(&context, &mut items, cancellation_token);
+ complete_component_environments(&context, &mut items, cancellation_token);
+ complete_theorem_environments(&context, &mut items, cancellation_token);
+ complete_user_environments(&context, &mut items, cancellation_token);
+ complete_begin_command(&context, &mut items, cancellation_token);
+ complete_component_commands(&context, &mut items, cancellation_token);
+ complete_user_commands(&context, &mut items, cancellation_token);
+
+ cancellation_token.result().ok()?;
+
+ let mut items = dedup(items);
+ preselect(&context, &mut items);
+ score(&context, &mut items);
+
+ items.sort_by_key(|item| (!item.preselect, -item.score.unwrap_or(std::i64::MIN + 1)));
+ let items: Vec<_> = items
+ .into_iter()
+ .take(COMPLETION_LIMIT)
+ .filter(|item| item.score.is_some())
+ .map(|item| convert_internal_items(&context, item))
+ .enumerate()
+ .map(|(i, item)| append_sort_text(item, i))
+ .collect();
+
+ let is_incomplete = if context
+ .request
+ .context
+ .client_info
+ .lock()
+ .unwrap()
+ .as_ref()
+ .map(|info| info.name.as_str())
+ .unwrap_or_default()
+ == "Visual Studio Code"
+ {
+ true
+ } else {
+ items.len() >= COMPLETION_LIMIT
+ };
+
+ Some(CompletionList {
+ is_incomplete,
+ items,
+ })
+}
+
+fn dedup(items: Vec<InternalCompletionItem>) -> Vec<InternalCompletionItem> {
+ let mut labels = FxHashSet::default();
+ let mut insert = vec![false; items.len()];
+ for (i, item) in items.iter().enumerate() {
+ insert[i] = labels.insert(item.data.label());
+ }
+ items
+ .into_iter()
+ .enumerate()
+ .filter(|(i, _)| insert[*i])
+ .map(|(_, item)| item)
+ .collect()
+}
+
+fn score(context: &CursorContext<CompletionParams>, items: &mut Vec<InternalCompletionItem>) {
+ let pattern = match &context.cursor {
+ Cursor::Latex(token) if token.kind().is_command_name() => token.text().trim_end(),
+ Cursor::Latex(token) if token.kind() == latex::WORD => token.text(),
+ Cursor::Latex(_) => "",
+ Cursor::Bibtex(token) if token.kind().is_type() => token.text(),
+ Cursor::Bibtex(token) if token.kind() == bibtex::WORD => token.text(),
+ Cursor::Bibtex(token) if token.kind() == bibtex::COMMAND_NAME => token.text().trim_end(),
+ Cursor::Bibtex(_) => "",
+ Cursor::Nothing => "",
+ };
+
+ let file_pattern = pattern.split('/').last().unwrap();
+ let matcher = SkimMatcherV2::default().ignore_case();
+ for item in items {
+ item.score = match &item.data {
+ InternalCompletionItemData::EntryType { ty } => {
+ matcher.fuzzy_match(&ty.name, &pattern[1..])
+ }
+ InternalCompletionItemData::Field { field } => {
+ matcher.fuzzy_match(&field.name, &pattern)
+ }
+ InternalCompletionItemData::Argument { name, .. } => {
+ matcher.fuzzy_match(name, &pattern)
+ }
+ InternalCompletionItemData::BeginCommand => matcher.fuzzy_match("begin", &pattern[1..]),
+ InternalCompletionItemData::Citation { key, .. } => matcher.fuzzy_match(&key, &pattern),
+ InternalCompletionItemData::ComponentCommand { name, .. } => {
+ matcher.fuzzy_match(name, &pattern[1..])
+ }
+ InternalCompletionItemData::ComponentEnvironment { name, .. } => {
+ matcher.fuzzy_match(name, &pattern)
+ }
+ InternalCompletionItemData::Class { name } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::Package { name } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::Color { name } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::ColorModel { name } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::Acronym { name } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::GlossaryEntry { name } => {
+ matcher.fuzzy_match(&name, &pattern)
+ }
+ InternalCompletionItemData::File { name } => matcher.fuzzy_match(&name, file_pattern),
+ InternalCompletionItemData::Directory { name } => {
+ matcher.fuzzy_match(&name, file_pattern)
+ }
+ InternalCompletionItemData::Label { name, .. } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::UserCommand { name } => {
+ matcher.fuzzy_match(&name, &pattern[1..])
+ }
+ InternalCompletionItemData::UserEnvironment { name } => {
+ matcher.fuzzy_match(&name, &pattern)
+ }
+ InternalCompletionItemData::PgfLibrary { name } => matcher.fuzzy_match(&name, &pattern),
+ InternalCompletionItemData::TikzLibrary { name } => {
+ matcher.fuzzy_match(&name, &pattern)
+ }
+ };
+ }
+}
+
+fn preselect(
+ context: &CursorContext<CompletionParams>,
+ items: &mut [InternalCompletionItem],
+) -> Option<()> {
+ let name = context.cursor.as_latex()?;
+ let group = latex::CurlyGroupWord::cast(name.parent())?;
+ let end = latex::End::cast(group.syntax().parent()?)?;
+ let environment = latex::Environment::cast(end.syntax().parent()?)?;
+ let name = environment.begin()?.name()?.word()?.text();
+
+ for item in items {
+ if item.data.label() == name {
+ item.preselect = true;
+ }
+ }
+ Some(())
+}
+
+fn convert_internal_items(
+ context: &CursorContext<CompletionParams>,
+ item: InternalCompletionItem,
+) -> CompletionItem {
+ let range = context
+ .request
+ .main_document()
+ .line_index
+ .line_col_lsp_range(item.range);
+
+ let mut new_item = match item.data {
+ InternalCompletionItemData::EntryType { ty } => {
+ let text_edit = TextEdit::new(range, (&ty.name).into());
+ let kind = Structure::Entry(ty.category).completion_kind();
+ CompletionItem {
+ label: (&ty.name).into(),
+ kind: Some(adjust_kind(&context.request, kind)),
+ documentation: ty.documentation.as_ref().map(|doc| {
+ Documentation::MarkupContent(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: doc.into(),
+ })
+ }),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ data: Some(serde_json::to_value(CompletionItemData::EntryType).unwrap()),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Field { field } => {
+ let text_edit = TextEdit::new(range, (&field.name).into());
+ CompletionItem {
+ label: (&field.name).into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Field.completion_kind(),
+ )),
+ documentation: Some(Documentation::MarkupContent(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: (&field.documentation).into(),
+ })),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ data: Some(serde_json::to_value(CompletionItemData::FieldName).unwrap()),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Argument { name, image } => {
+ let text_edit = TextEdit::new(range, name.into());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Argument.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Argument).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ documentation: image
+ .and_then(|image| image_documentation(&context.request, &name, image)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::BeginCommand => {
+ if context
+ .request
+ .context
+ .client_capabilities
+ .lock()
+ .unwrap()
+ .text_document
+ .as_ref()
+ .and_then(|cap| cap.completion.as_ref())
+ .and_then(|cap| cap.completion_item.as_ref())
+ .and_then(|cap| cap.snippet_support)
+ == Some(true)
+ {
+ CompletionItem {
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Snippet.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::CommandSnippet).unwrap()),
+ insert_text: Some("begin{$1}\n\t$0\n\\end{$1}".into()),
+ insert_text_format: Some(InsertTextFormat::Snippet),
+ ..CompletionItem::new_simple("begin".into(), component_detail(&[]))
+ }
+ } else {
+ let text_edit = TextEdit::new(range, "begin".to_string());
+ CompletionItem {
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Command.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Command).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::new_simple("begin".to_string(), component_detail(&[]))
+ }
+ }
+ }
+ InternalCompletionItemData::Citation { uri, key, text, ty } => {
+ let text_edit = TextEdit::new(range, key.to_string());
+ CompletionItem {
+ label: key.to_string(),
+ kind: Some(adjust_kind(&context.request, ty.completion_kind())),
+ filter_text: Some(text.clone()),
+ sort_text: Some(text),
+ data: Some(
+ serde_json::to_value(CompletionItemData::Citation {
+ uri: uri.as_ref().clone(),
+ key: key.into(),
+ })
+ .unwrap(),
+ ),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::ComponentCommand {
+ name,
+ image,
+ glyph,
+ file_names,
+ } => {
+ let detail = glyph.map_or_else(
+ || component_detail(file_names),
+ |glyph| format!("{}, {}", glyph, component_detail(file_names)),
+ );
+ let documentation =
+ image.and_then(|img| image_documentation(&context.request, &name, img));
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Command.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Command).unwrap()),
+ documentation,
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::new_simple(name.to_string(), detail)
+ }
+ }
+ InternalCompletionItemData::ComponentEnvironment { name, file_names } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Environment.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Environment).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::new_simple(name.to_string(), component_detail(file_names))
+ }
+ }
+ InternalCompletionItemData::Class { name } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Class.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Class).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Package { name } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Package.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Package).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Color { name } => {
+ let text_edit = TextEdit::new(range, name.into());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Color.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Color).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::ColorModel { name } => {
+ let text_edit = TextEdit::new(range, name.into());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::ColorModel.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::ColorModel).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Acronym { name } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::GlossaryEntry.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Acronym).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::GlossaryEntry { name } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::GlossaryEntry.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::GlossaryEntry).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::File { name } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::File.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::File).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Directory { name } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Folder.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Folder).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::Label {
+ name,
+ kind,
+ header,
+ footer,
+ text,
+ } => {
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(&context.request, kind.completion_kind())),
+ detail: header,
+ documentation: footer.map(Documentation::String),
+ sort_text: Some(text.clone()),
+ filter_text: Some(text),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ data: Some(serde_json::to_value(CompletionItemData::Label).unwrap()),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::UserCommand { name } => {
+ let detail = "user-defined".into();
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Command.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Command).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::new_simple(name.into(), detail)
+ }
+ }
+ InternalCompletionItemData::UserEnvironment { name } => {
+ let detail = "user-defined".into();
+ let text_edit = TextEdit::new(range, name.to_string());
+ CompletionItem {
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::Environment.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::Environment).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::new_simple(name.into(), detail)
+ }
+ }
+ InternalCompletionItemData::PgfLibrary { name } => {
+ let text_edit = TextEdit::new(range, name.into());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::PgfLibrary.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::PgfLibrary).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ InternalCompletionItemData::TikzLibrary { name } => {
+ let text_edit = TextEdit::new(range, name.into());
+ CompletionItem {
+ label: name.into(),
+ kind: Some(adjust_kind(
+ &context.request,
+ Structure::TikzLibrary.completion_kind(),
+ )),
+ data: Some(serde_json::to_value(CompletionItemData::TikzLibrary).unwrap()),
+ text_edit: Some(CompletionTextEdit::Edit(text_edit)),
+ ..CompletionItem::default()
+ }
+ }
+ };
+ new_item.preselect = Some(item.preselect);
+ new_item
+}
+
+fn append_sort_text(mut item: CompletionItem, index: usize) -> CompletionItem {
+ let sort_prefix = format!("{:0>2}", index);
+ match &item.sort_text {
+ Some(sort_text) => {
+ item.sort_text = Some(format!("{} {}", sort_prefix, sort_text));
+ }
+ None => {
+ item.sort_text = Some(sort_prefix);
+ }
+ };
+ item
+}
diff --git a/support/texlab/src/features/completion/acronym_ref.rs b/support/texlab/src/features/completion/acronym_ref.rs
new file mode 100644
index 0000000000..9d8bcc6c5f
--- /dev/null
+++ b/support/texlab/src/features/completion/acronym_ref.rs
@@ -0,0 +1,169 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_acronyms<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+
+ latex::AcronymReference::cast(group.syntax().parent()?)?;
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for name in data
+ .root
+ .descendants()
+ .filter_map(latex::AcronymDefinition::cast)
+ .filter_map(|node| node.name())
+ .filter_map(|name| name.word())
+ .map(|name| name.text())
+ {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Acronym { name },
+ ));
+ }
+ }
+ }
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_acronyms(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_acronyms(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\n\\acrshort{f}")])
+ .main("main.tex")
+ .line(1)
+ .character(11)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_acronyms(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(87.into(), 88.into()));
+ }
+ }
+
+ #[test]
+ fn test_empty() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\n\\acrshort{}")])
+ .main("main.tex")
+ .line(1)
+ .character(10)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_acronyms(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(87.into(), 87.into()));
+ }
+ }
+
+ #[test]
+ fn test_after_group() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\n\\acrshort{}")])
+ .main("main.tex")
+ .line(1)
+ .character(11)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_acronyms(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\n\\acrshort{f")])
+ .main("main.tex")
+ .line(1)
+ .character(11)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_acronyms(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(87.into(), 88.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/argument.rs b/support/texlab/src/features/completion/argument.rs
new file mode 100644
index 0000000000..e2637e026f
--- /dev/null
+++ b/support/texlab/src/features/completion/argument.rs
@@ -0,0 +1,189 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ component_db::COMPONENT_DATABASE,
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_arguments<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ let group = latex::CurlyGroup::cast(token.parent())
+ .or_else(|| token.parent().parent().and_then(latex::CurlyGroup::cast))
+ .filter(|group| context.is_inside_latex_curly(group))?;
+
+ let command = latex::GenericCommand::cast(group.syntax().parent()?)?;
+
+ let index = command
+ .syntax()
+ .children()
+ .filter_map(latex::CurlyGroup::cast)
+ .position(|g| g.syntax().text_range() == group.syntax().text_range())?;
+
+ let command_name = &command.name()?.text()[1..];
+
+ for component in COMPONENT_DATABASE.linked_components(&context.request.subset) {
+ for component_command in component
+ .commands
+ .iter()
+ .filter(|command| command.name == command_name)
+ {
+ for (_, param) in component_command
+ .parameters
+ .iter()
+ .enumerate()
+ .filter(|(i, _)| *i == index)
+ {
+ for arg in &param.0 {
+ let item = InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Argument {
+ name: &arg.name,
+ image: arg.image.as_deref(),
+ },
+ );
+ items.push(item);
+ }
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_arguments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_arguments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", r#"\mathbb{}\usepackage{amsfonts}"#)])
+ .main("main.tex")
+ .line(0)
+ .character(8)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_arguments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(8.into(), 8.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_word() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", r#"\mathbb{foo}\usepackage{amsfonts}"#)])
+ .main("main.tex")
+ .line(0)
+ .character(8)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_arguments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(8.into(), 11.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\mathbb{ \\usepackage{amsfonts}")])
+ .main("main.tex")
+ .line(0)
+ .character(8)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_arguments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(8.into(), 8.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace_second() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\mathbb{}{\\usepackage{amsfonts}")])
+ .main("main.tex")
+ .line(0)
+ .character(10)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_arguments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+}
diff --git a/support/texlab/src/features/completion/begin_command.rs b/support/texlab/src/features/completion/begin_command.rs
new file mode 100644
index 0000000000..ebd272711e
--- /dev/null
+++ b/support/texlab/src/features/completion/begin_command.rs
@@ -0,0 +1,84 @@
+use cancellation::CancellationToken;
+use lsp_types::CompletionParams;
+
+use crate::features::cursor::CursorContext;
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_begin_command(
+ context: &CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+ let range = context.cursor.command_range(context.offset)?;
+
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::BeginCommand,
+ ));
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_begin_command(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_begin_command(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\")])
+ .main("main.tex")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_begin_command(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 1.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/citation.rs b/support/texlab/src/features/completion/citation.rs
new file mode 100644
index 0000000000..6df3364099
--- /dev/null
+++ b/support/texlab/src/features/completion/citation.rs
@@ -0,0 +1,244 @@
+use std::sync::Arc;
+
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+use once_cell::sync::Lazy;
+use regex::Regex;
+
+use crate::{
+ features::{cursor::CursorContext, lsp_kinds::Structure},
+ syntax::{
+ bibtex::{self, HasType},
+ latex, CstNode,
+ },
+ BibtexEntryTypeCategory, Document, LANGUAGE_DATA,
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_citations<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+ let token = context.cursor.as_latex()?;
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ check_citation(context, token).or_else(|| check_acronym(token))?;
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_bibtex() {
+ for entry in data.root.children().filter_map(bibtex::Entry::cast) {
+ cancellation_token.result().ok()?;
+ if let Some(item) = make_item(document, entry, range) {
+ items.push(item);
+ }
+ }
+ }
+ }
+
+ Some(())
+}
+
+fn check_citation(
+ context: &CursorContext<CompletionParams>,
+ token: &latex::SyntaxToken,
+) -> Option<()> {
+ let group = latex::CurlyGroupWordList::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ latex::Citation::cast(group.syntax().parent()?)?;
+ Some(())
+}
+
+fn check_acronym(token: &latex::SyntaxToken) -> Option<()> {
+ let pair = token.ancestors().find_map(latex::KeyValuePair::cast)?;
+ let mut key_words = pair.key()?.words();
+ if key_words.next()?.text() != "cite" || key_words.next().is_some() {
+ return None;
+ }
+
+ latex::AcronymDeclaration::cast(pair.syntax().parent()?.parent()?.parent()?)?;
+ Some(())
+}
+
+fn make_item<'a>(
+ document: &'a Document,
+ entry: bibtex::Entry<'a>,
+ range: TextRange,
+) -> Option<InternalCompletionItem<'a>> {
+ let key = entry.key()?.text();
+ let ty = LANGUAGE_DATA
+ .find_entry_type(&entry.ty()?.text()[1..])
+ .map(|ty| Structure::Entry(ty.category))
+ .unwrap_or_else(|| Structure::Entry(BibtexEntryTypeCategory::Misc));
+
+ let entry_code = entry.syntax().text().to_string();
+ let text = format!(
+ "{} {}",
+ key,
+ WHITESPACE_REGEX
+ .replace_all(
+ &entry_code
+ .replace('{', "")
+ .replace('}', "")
+ .replace(',', " ")
+ .replace("=", " "),
+ " "
+ )
+ .trim(),
+ );
+
+ Some(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Citation {
+ uri: Arc::clone(&document.uri),
+ key: key.into(),
+ text,
+ ty,
+ },
+ ))
+}
+
+static WHITESPACE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("\\s+").unwrap());
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{}"),
+ ("main.bib", "@article{foo,}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(6)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(32.into(), 32.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{"),
+ ("main.bib", "@article{foo,}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(6)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(32.into(), 32.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace_second() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo,a"),
+ ("main.bib", "@article{foo,}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(10)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(36.into(), 37.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_acronym() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ (
+ "main.tex",
+ "\\addbibresource{main.bib}\n\\DeclareAcronym{foo}{cite={\n}}",
+ ),
+ ("main.bib", "@article{foo,}"),
+ ])
+ .main("main.tex")
+ .line(2)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(54.into(), 54.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/color.rs b/support/texlab/src/features/completion/color.rs
new file mode 100644
index 0000000000..0e94af15fe
--- /dev/null
+++ b/support/texlab/src/features/completion/color.rs
@@ -0,0 +1,122 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+ LANGUAGE_DATA,
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_colors<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ latex::ColorReference::cast(group.syntax().parent()?)?;
+
+ for name in &LANGUAGE_DATA.colors {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Color { name },
+ ));
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_colors(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_colors(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\color{}")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_colors(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 7.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\color{")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_colors(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 7.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/color_model.rs b/support/texlab/src/features/completion/color_model.rs
new file mode 100644
index 0000000000..f7f09b6367
--- /dev/null
+++ b/support/texlab/src/features/completion/color_model.rs
@@ -0,0 +1,188 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+const MODEL_NAMES: &[&str] = &["gray", "rgb", "RGB", "HTML", "cmyk"];
+
+pub fn complete_color_models<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ check_color_definition(context, token)
+ .or_else(|| check_color_definition_set(context, token))?;
+
+ for name in MODEL_NAMES {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::ColorModel { name },
+ ));
+ }
+
+ Some(())
+}
+
+fn check_color_definition(
+ context: &CursorContext<CompletionParams>,
+ token: &latex::SyntaxToken,
+) -> Option<()> {
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ let definition = latex::ColorDefinition::cast(group.syntax().parent()?)?;
+ definition
+ .model()
+ .filter(|model| model.syntax().text_range() == group.syntax().text_range())?;
+ Some(())
+}
+
+fn check_color_definition_set(
+ context: &CursorContext<CompletionParams>,
+ token: &latex::SyntaxToken,
+) -> Option<()> {
+ let group = latex::CurlyGroupWordList::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ let definition = latex::ColorSetDefinition::cast(group.syntax().parent()?)?;
+ definition
+ .model_list()
+ .filter(|model| model.syntax().text_range() == group.syntax().text_range())?;
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_color_models(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_color_models(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_definition_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\definecolor{foo}{}")])
+ .main("main.tex")
+ .line(0)
+ .character(18)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_color_models(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(18.into(), 18.into()));
+ }
+ }
+
+ #[test]
+ fn test_definition_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\definecolor{foo}{")])
+ .main("main.tex")
+ .line(0)
+ .character(18)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_color_models(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(18.into(), 18.into()));
+ }
+ }
+
+ #[test]
+ fn test_definition_set_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\definecolorset{}")])
+ .main("main.tex")
+ .line(0)
+ .character(16)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_color_models(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(16.into(), 16.into()));
+ }
+ }
+
+ #[test]
+ fn test_definition_set_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\definecolorset{")])
+ .main("main.tex")
+ .line(0)
+ .character(16)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_color_models(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(16.into(), 16.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/component_command.rs b/support/texlab/src/features/completion/component_command.rs
new file mode 100644
index 0000000000..aba5a78597
--- /dev/null
+++ b/support/texlab/src/features/completion/component_command.rs
@@ -0,0 +1,177 @@
+use cancellation::CancellationToken;
+use lsp_types::CompletionParams;
+
+use crate::{component_db::COMPONENT_DATABASE, features::cursor::CursorContext};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_component_commands<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let range = context.cursor.command_range(context.offset)?;
+
+ for component in COMPONENT_DATABASE.linked_components(&context.request.subset) {
+ cancellation_token.result().ok()?;
+ for command in &component.commands {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::ComponentCommand {
+ name: &command.name,
+ image: command.image.as_deref(),
+ glyph: command.glyph.as_deref(),
+ file_names: &component.file_names,
+ },
+ ));
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\")])
+ .main("main.tex")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 1.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_simple_before() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple_package() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\\n\\usepackage{lipsum}")])
+ .main("main.tex")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in &actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 1.into()));
+ }
+
+ assert!(actual_items
+ .iter()
+ .any(|item| item.data.label() == "lipsum"));
+ }
+
+ #[test]
+ fn test_latex_simple_existing() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\foo")])
+ .main("main.tex")
+ .line(0)
+ .character(2)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 4.into()));
+ }
+ }
+
+ #[test]
+ fn test_bibtex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@a{b,c={\\ }}")])
+ .main("main.bib")
+ .line(0)
+ .character(9)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(9.into(), 10.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/component_environment.rs b/support/texlab/src/features/completion/component_environment.rs
new file mode 100644
index 0000000000..fca9d03780
--- /dev/null
+++ b/support/texlab/src/features/completion/component_environment.rs
@@ -0,0 +1,174 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ component_db::COMPONENT_DATABASE,
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_component_environments<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) {
+ return None;
+ }
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ for component in COMPONENT_DATABASE.linked_components(&context.request.subset) {
+ cancellation_token.result().ok()?;
+ for name in &component.environments {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::ComponentEnvironment {
+ name,
+ file_names: &component.file_names,
+ },
+ ));
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\begin{")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 7.into()));
+ }
+ }
+
+ #[test]
+ fn test_simple_end() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\begin{a}\n\\end{")])
+ .main("main.tex")
+ .line(1)
+ .character(5)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(15.into(), 15.into()));
+ }
+ }
+
+ #[test]
+ fn test_simple_class() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\begin{}\n\\documentclass{article}")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in &actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 7.into()));
+ }
+
+ assert!(actual_items
+ .iter()
+ .any(|item| item.data.label() == "theindex"));
+ }
+
+ #[test]
+ fn test_simple_existing() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\begin{d}")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_component_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 8.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/entry_type.rs b/support/texlab/src/features/completion/entry_type.rs
new file mode 100644
index 0000000000..c8774ea3ff
--- /dev/null
+++ b/support/texlab/src/features/completion/entry_type.rs
@@ -0,0 +1,231 @@
+use cancellation::CancellationToken;
+use cstree::{TextRange, TextSize};
+use lsp_types::CompletionParams;
+
+use crate::{features::cursor::CursorContext, LANGUAGE_DATA};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_entry_types<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ if cancellation_token.is_canceled() {
+ return None;
+ }
+
+ let range = context
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind().is_type())
+ .filter(|token| token.text_range().start() != context.offset)
+ .map(|token| token.text_range())
+ .map(|range| TextRange::new(range.start() + TextSize::from(1), range.end()))?;
+
+ for ty in &LANGUAGE_DATA.entry_types {
+ let data = InternalCompletionItemData::EntryType { ty };
+ let item = InternalCompletionItem::new(range, data);
+ items.push(item);
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_at_empty() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@")])
+ .main("main.bib")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 1.into()));
+ }
+ }
+
+ #[test]
+ fn test_before_preamble() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@preamble")])
+ .main("main.bib")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 9.into()));
+ }
+ }
+
+ #[test]
+ fn test_before_string() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@string")])
+ .main("main.bib")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 7.into()));
+ }
+ }
+
+ #[test]
+ fn test_before_article() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article")])
+ .main("main.bib")
+ .line(0)
+ .character(1)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 8.into()));
+ }
+ }
+
+ #[test]
+ fn test_after_preamble() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@preamble{")])
+ .main("main.bib")
+ .line(0)
+ .character(9)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 9.into()));
+ }
+ }
+
+ #[test]
+ fn test_after_string() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@string{")])
+ .main("main.bib")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 7.into()));
+ }
+ }
+
+ #[test]
+ fn test_complete_entry() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, author = {foo}}")])
+ .main("main.bib")
+ .line(0)
+ .character(3)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 8.into()));
+ }
+ }
+
+ #[test]
+ fn test_complete_entry_field() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, author = {foo}}")])
+ .main("main.bib")
+ .line(0)
+ .character(17)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_entry_types(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+}
diff --git a/support/texlab/src/features/completion/field.rs b/support/texlab/src/features/completion/field.rs
new file mode 100644
index 0000000000..d7297b481b
--- /dev/null
+++ b/support/texlab/src/features/completion/field.rs
@@ -0,0 +1,200 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, CstNode},
+ LANGUAGE_DATA,
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_fields<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_bibtex()?;
+ let range = if token.kind() == bibtex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ let parent = token.parent();
+ if let Some(entry) = bibtex::Entry::cast(parent) {
+ if entry.key()?.text_range() == token.text_range() {
+ return None;
+ }
+ } else {
+ bibtex::Field::cast(parent)?;
+ }
+
+ for field in &LANGUAGE_DATA.fields {
+ let data = InternalCompletionItemData::Field { field };
+ let item = InternalCompletionItem::new(range, data);
+ items.push(item);
+ }
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_entry_open() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo,")])
+ .main("main.bib")
+ .line(0)
+ .character(13)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(13.into(), 13.into()));
+ }
+ }
+
+ #[test]
+ fn test_empty_entry_closed() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo,}")])
+ .main("main.bib")
+ .line(0)
+ .character(13)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(13.into(), 13.into()));
+ }
+ }
+
+ #[test]
+ fn test_entry_field_name() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, a")])
+ .main("main.bib")
+ .line(0)
+ .character(15)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(14.into(), 15.into()));
+ }
+ }
+
+ #[test]
+ fn test_entry_field_value() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, author = bar}")])
+ .main("main.bib")
+ .line(0)
+ .character(24)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_entry_two_fields_name_closed() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, author = bar, baz}")])
+ .main("main.bib")
+ .line(0)
+ .character(29)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(28.into(), 31.into()));
+ }
+ }
+
+ #[test]
+ fn test_entry_two_fields_name_open() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, author = bar, baz")])
+ .main("main.bib")
+ .line(0)
+ .character(29)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_fields(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(28.into(), 31.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/glossary_ref.rs b/support/texlab/src/features/completion/glossary_ref.rs
new file mode 100644
index 0000000000..4529129fd7
--- /dev/null
+++ b/support/texlab/src/features/completion/glossary_ref.rs
@@ -0,0 +1,141 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_glossary_entries<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ latex::GlossaryEntryReference::cast(group.syntax().parent()?)?;
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for node in data.root.descendants() {
+ cancellation_token.result().ok()?;
+
+ if let Some(name) = latex::GlossaryEntryDefinition::cast(node)
+ .and_then(|entry| entry.name())
+ .and_then(|name| name.word())
+ .map(|name| name.text())
+ {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::GlossaryEntry { name },
+ ));
+ } else if let Some(name) = latex::AcronymDefinition::cast(node)
+ .and_then(|entry| entry.name())
+ .and_then(|name| name.word())
+ .map(|name| name.text())
+ {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Acronym { name },
+ ));
+ }
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_glossary_entries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_glossary_entries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\n\\gls{f}")])
+ .main("main.tex")
+ .line(1)
+ .character(6)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_glossary_entries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(82.into(), 83.into()));
+ }
+ }
+
+ #[test]
+ fn test_open_brace() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\n\\gls{f")])
+ .main("main.tex")
+ .line(1)
+ .character(6)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_glossary_entries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(82.into(), 83.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/import.rs b/support/texlab/src/features/completion/import.rs
new file mode 100644
index 0000000000..ac5f2e6e40
--- /dev/null
+++ b/support/texlab/src/features/completion/import.rs
@@ -0,0 +1,196 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+use rustc_hash::FxHashSet;
+use smol_str::SmolStr;
+
+use crate::{
+ component_db::COMPONENT_DATABASE,
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_imports<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ let token = context.cursor.as_latex()?;
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ let group = latex::CurlyGroupWordList::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+
+ let (extension, mut factory): (
+ &str,
+ Box<dyn FnMut(SmolStr) -> InternalCompletionItemData<'a>>,
+ ) = match group.syntax().parent()?.kind() {
+ latex::PACKAGE_INCLUDE => (
+ "sty",
+ Box::new(|name| InternalCompletionItemData::Package { name }),
+ ),
+ latex::CLASS_INCLUDE => (
+ "cls",
+ Box::new(|name| InternalCompletionItemData::Class { name }),
+ ),
+ _ => return None,
+ };
+
+ let mut file_names = FxHashSet::default();
+ for file_name in COMPONENT_DATABASE
+ .components
+ .iter()
+ .flat_map(|comp| comp.file_names.iter())
+ .filter(|file_name| file_name.ends_with(extension))
+ {
+ cancellation_token.result().ok()?;
+ file_names.insert(file_name);
+ let stem = &file_name[0..file_name.len() - 4];
+ let data = factory(stem.into());
+ let item = InternalCompletionItem::new(range, data);
+ items.push(item);
+ }
+
+ let resolver = context.request.context.resolver.lock().unwrap();
+ for file_name in resolver
+ .files_by_name
+ .keys()
+ .filter(|file_name| file_name.ends_with(extension) && !file_names.contains(file_name))
+ {
+ cancellation_token.result().ok()?;
+
+ let stem = &file_name[0..file_name.len() - 4];
+ let data = factory(stem.into());
+ let item = InternalCompletionItem::new(range, data);
+ items.push(item);
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_imports(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_imports(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple_package() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\usepackage{}")])
+ .main("main.tex")
+ .line(0)
+ .character(12)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_imports(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(12.into(), 12.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace_package() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\usepackage{ \\foo")])
+ .main("main.tex")
+ .line(0)
+ .character(12)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_imports(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(12.into(), 12.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_simple_class() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\documentclass{}")])
+ .main("main.tex")
+ .line(0)
+ .character(15)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_imports(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(15.into(), 15.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace_class() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\documentclass{ \\foo")])
+ .main("main.tex")
+ .line(0)
+ .character(15)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_imports(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(15.into(), 15.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/include.rs b/support/texlab/src/features/completion/include.rs
new file mode 100644
index 0000000000..c711ea5ce7
--- /dev/null
+++ b/support/texlab/src/features/completion/include.rs
@@ -0,0 +1,181 @@
+use std::{
+ convert::TryFrom,
+ fs,
+ path::{Path, PathBuf},
+};
+
+use cancellation::CancellationToken;
+use cstree::{TextRange, TextSize};
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_includes<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+ if context.request.main_document().uri.scheme() != "file" {
+ return None;
+ }
+
+ let token = context.cursor.as_latex()?;
+ let (path_text, path_range) = if token.kind() == latex::WORD {
+ (token.text(), token.text_range())
+ } else {
+ ("", TextRange::empty(context.offset))
+ };
+
+ let group = latex::CurlyGroupWordList::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ let include = group.syntax().parent()?;
+ let (include_extension, extensions): (bool, &[&str]) = match include.kind() {
+ latex::PACKAGE_INCLUDE => (false, &["sty"]),
+ latex::CLASS_INCLUDE => (false, &["cls"]),
+ latex::LATEX_INCLUDE => {
+ let include = latex::Include::cast(include)?;
+ (
+ matches!(include.command()?.text(), "\\input" | "\\subfile"),
+ &["tex"],
+ )
+ }
+ latex::BIBLATEX_INCLUDE => (true, &["bib"]),
+ latex::BIBTEX_INCLUDE => (false, &["bib"]),
+ latex::GRAPHICS_INCLUDE => (true, &["pdf", "png", "jpg", "jpeg", "bmp"]),
+ latex::SVG_INCLUDE => (true, &["svg"]),
+ latex::INKSCAPE_INCLUDE => (true, &["pdf", "eps", "ps", "png"]),
+ latex::VERBATIM_INCLUDE => (true, &[]),
+ _ => return None,
+ };
+
+ let segment_range = if path_text.is_empty() {
+ path_range
+ } else {
+ let start =
+ path_range.end() - TextSize::try_from(path_text.split('/').last()?.len()).ok()?;
+ TextRange::new(start, path_range.end())
+ };
+
+ let current_dir = current_dir(context, path_text)?;
+ for entry in fs::read_dir(current_dir).ok()?.filter_map(Result::ok) {
+ let mut path = entry.path();
+
+ let file_type = entry.file_type().ok()?;
+ if file_type.is_file() && is_included(&path, extensions) {
+ if !include_extension {
+ remove_extension(&mut path);
+ }
+ let name = path.file_name()?.to_str()?.into();
+ let data = InternalCompletionItemData::File { name };
+ let item = InternalCompletionItem::new(segment_range, data);
+ items.push(item);
+ } else if file_type.is_dir() {
+ let name = path.file_name()?.to_str()?.into();
+ let data = InternalCompletionItemData::Directory { name };
+ let item = InternalCompletionItem::new(segment_range, data);
+ items.push(item);
+ }
+ }
+
+ Some(())
+}
+
+fn current_dir(context: &CursorContext<CompletionParams>, path_text: &str) -> Option<PathBuf> {
+ let mut path = context
+ .request
+ .context
+ .options
+ .read()
+ .unwrap()
+ .root_directory
+ .as_ref()
+ .map(|root_directory| {
+ context
+ .request
+ .context
+ .current_directory
+ .join(root_directory)
+ })
+ .unwrap_or_else(|| {
+ let mut path = context.request.main_document().uri.to_file_path().unwrap();
+ path.pop();
+ path
+ });
+
+ path = PathBuf::from(path.to_str()?.replace('\\', "/"));
+ if !path_text.is_empty() {
+ path.push(&path_text);
+ if !path_text.ends_with('/') {
+ path.pop();
+ }
+ }
+ Some(path)
+}
+
+fn is_included(file: &Path, allowed_extensions: &[&str]) -> bool {
+ allowed_extensions.is_empty()
+ || file
+ .extension()
+ .and_then(|ext| ext.to_str())
+ .map(|ext| ext.to_lowercase())
+ .map(|ext| allowed_extensions.contains(&ext.as_str()))
+ .unwrap_or_default()
+}
+
+fn remove_extension(path: &mut PathBuf) {
+ if let Some(stem) = path
+ .file_stem()
+ .and_then(|stem| stem.to_str())
+ .map(ToOwned::to_owned)
+ {
+ path.pop();
+ path.push(stem);
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_includes(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_includes(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+}
diff --git a/support/texlab/src/features/completion/label.rs b/support/texlab/src/features/completion/label.rs
new file mode 100644
index 0000000000..2f7e2d8f77
--- /dev/null
+++ b/support/texlab/src/features/completion/label.rs
@@ -0,0 +1,196 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::{cursor::CursorContext, lsp_kinds::Structure},
+ render_label,
+ syntax::{latex, CstNode},
+ LabelledObject,
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_labels<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let is_math = latex::CurlyGroupWordList::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))
+ .and_then(|group| group.syntax().parent())
+ .and_then(|reference| latex::LabelReference::cast(reference))
+ .and_then(|refernce| refernce.command())
+ .map(|reference| reference.text() == "\\eqref")
+ .or_else(|| {
+ latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))
+ .and_then(|group| group.syntax().parent())
+ .and_then(|reference| latex::LabelReferenceRange::cast(reference))
+ .map(|_| false)
+ })?;
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for label in data
+ .root
+ .descendants()
+ .filter(|_| !cancellation_token.is_canceled())
+ .filter_map(latex::LabelDefinition::cast)
+ {
+ if let Some(name) = label
+ .name()
+ .and_then(|name| name.word())
+ .map(|name| name.text())
+ {
+ match render_label(&context.request.subset, name, Some(label)) {
+ Some(rendered_label) => {
+ let kind = match &rendered_label.object {
+ LabelledObject::Section { .. } => Structure::Section,
+ LabelledObject::Float { .. } => Structure::Float,
+ LabelledObject::Theorem { .. } => Structure::Theorem,
+ LabelledObject::Equation => Structure::Equation,
+ LabelledObject::EnumItem => Structure::Item,
+ };
+
+ if is_math && kind != Structure::Equation {
+ continue;
+ }
+
+ let header = rendered_label.detail();
+ let footer = match &rendered_label.object {
+ LabelledObject::Float { caption, .. } => Some(caption.clone()),
+ _ => None,
+ };
+
+ let text = format!("{} {}", name, rendered_label.reference());
+
+ let item = InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Label {
+ name,
+ kind,
+ header,
+ footer,
+ text,
+ },
+ );
+ items.push(item);
+ }
+ None => {
+ let kind = Structure::Label;
+ let header = None;
+ let footer = None;
+ let text = name.to_string();
+ let item = InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::Label {
+ name,
+ kind,
+ header,
+ footer,
+ text,
+ },
+ );
+ items.push(item);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_labels(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_labels(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\ref{}\\label{foo}")])
+ .main("main.tex")
+ .line(0)
+ .character(5)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_labels(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(5.into(), 5.into()));
+ }
+ }
+
+ #[test]
+ fn test_simple_range() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\crefrange{\n\\label{foo}")])
+ .main("main.tex")
+ .line(0)
+ .character(11)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_labels(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(11.into(), 11.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/theorem.rs b/support/texlab/src/features/completion/theorem.rs
new file mode 100644
index 0000000000..54db031a4b
--- /dev/null
+++ b/support/texlab/src/features/completion/theorem.rs
@@ -0,0 +1,152 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_theorem_environments<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ token: &CancellationToken,
+) -> Option<()> {
+ if token.is_canceled() {
+ return None;
+ }
+
+ let token = context.cursor.as_latex()?;
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) {
+ return None;
+ }
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for environment in &data.extras.theorem_environments {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::UserEnvironment {
+ name: &environment.name,
+ },
+ ));
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_theorem_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_theorem_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\begin{ \\newtheorem{lemma}{Lemma}")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_theorem_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 7.into()));
+ }
+ }
+
+ #[test]
+ fn test_simple_end() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.tex",
+ "\\newtheorem{lemma}{Lemma}\\begin{a}\n\\end{",
+ )])
+ .main("main.tex")
+ .line(1)
+ .character(5)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_theorem_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(40.into(), 40.into()));
+ }
+ }
+
+ #[test]
+ fn test_simple_existing() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\begin{d}\\newtheorem{lemma}{Lemma}")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_theorem_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 8.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/tikz_library.rs b/support/texlab/src/features/completion/tikz_library.rs
new file mode 100644
index 0000000000..da2a26cc9b
--- /dev/null
+++ b/support/texlab/src/features/completion/tikz_library.rs
@@ -0,0 +1,169 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+ LANGUAGE_DATA,
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_tikz_libraries<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ let group = latex::CurlyGroupWordList::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ let import = latex::TikzLibraryImport::cast(group.syntax().parent()?)?;
+
+ if import.command()?.text() == "\\usepgflibrary" {
+ for name in &LANGUAGE_DATA.pgf_libraries {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::PgfLibrary { name },
+ ));
+ }
+ } else {
+ for name in &LANGUAGE_DATA.tikz_libraries {
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::TikzLibrary { name },
+ ));
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_tikz_libraries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_tikz_libraries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple_pgf() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\usepgflibrary{}")])
+ .main("main.tex")
+ .line(0)
+ .character(15)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_tikz_libraries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(15.into(), 15.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace_pgf() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\usepgflibrary{")])
+ .main("main.tex")
+ .line(0)
+ .character(15)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_tikz_libraries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(15.into(), 15.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_simple_tikz() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\usetikzlibrary{}")])
+ .main("main.tex")
+ .line(0)
+ .character(16)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_tikz_libraries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(16.into(), 16.into()));
+ }
+ }
+
+ #[test]
+ fn test_latex_open_brace_tikz() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\usetikzlibrary{")])
+ .main("main.tex")
+ .line(0)
+ .character(16)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_tikz_libraries(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(16.into(), 16.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/completion/types.rs b/support/texlab/src/features/completion/types.rs
index f1b272f21e..b58a155fc4 100644
--- a/support/texlab/src/completion/types.rs
+++ b/support/texlab/src/features/completion/types.rs
@@ -1,20 +1,21 @@
-use crate::{
- protocol::{Range, Uri},
- syntax::{BibtexEntryTypeDoc, BibtexFieldDoc, Structure},
-};
+use std::sync::Arc;
+
+use cstree::TextRange;
use serde::{Deserialize, Serialize};
-use std::borrow::Cow;
+use smol_str::SmolStr;
+
+use crate::{features::lsp_kinds::Structure, BibtexEntryTypeDoc, BibtexFieldDoc, Uri};
#[derive(Debug, Clone)]
-pub struct Item<'a> {
- pub range: Range,
- pub data: ItemData<'a>,
+pub struct InternalCompletionItem<'a> {
+ pub range: TextRange,
+ pub data: InternalCompletionItemData<'a>,
pub preselect: bool,
pub score: Option<i64>,
}
-impl<'a> Item<'a> {
- pub fn new(range: Range, data: ItemData<'a>) -> Self {
+impl<'a> InternalCompletionItem<'a> {
+ pub fn new(range: TextRange, data: InternalCompletionItemData<'a>) -> Self {
Self {
range,
data,
@@ -25,98 +26,102 @@ impl<'a> Item<'a> {
}
#[derive(Debug, Clone)]
-pub enum ItemData<'a> {
- ComponentCommand {
+pub enum InternalCompletionItemData<'a> {
+ EntryType {
+ ty: &'a BibtexEntryTypeDoc,
+ },
+ Field {
+ field: &'a BibtexFieldDoc,
+ },
+ Argument {
name: &'a str,
image: Option<&'a str>,
+ },
+ BeginCommand,
+ Citation {
+ uri: Arc<Uri>,
+ key: &'a str,
+ text: String,
+ ty: Structure,
+ },
+ ComponentCommand {
+ name: &'a SmolStr,
+ image: Option<&'a str>,
glyph: Option<&'a str>,
- file_names: &'a [String],
+ file_names: &'a [SmolStr],
},
ComponentEnvironment {
- name: &'a str,
- file_names: &'a [String],
+ name: &'a SmolStr,
+ file_names: &'a [SmolStr],
},
- UserCommand {
- name: &'a str,
+ Class {
+ name: SmolStr,
},
- UserEnvironment {
- name: &'a str,
+ Package {
+ name: SmolStr,
},
- Label {
+ Color {
name: &'a str,
- kind: Structure,
- header: Option<String>,
- footer: Option<String>,
- text: String,
},
- PgfLibrary {
+ ColorModel {
name: &'a str,
},
- TikzLibrary {
+ Acronym {
name: &'a str,
},
- Package {
- name: Cow<'a, str>,
- },
- Class {
- name: Cow<'a, str>,
+ GlossaryEntry {
+ name: &'a str,
},
File {
- name: String,
+ name: SmolStr,
},
Directory {
- name: String,
+ name: SmolStr,
},
- Citation {
- uri: &'a Uri,
- key: &'a str,
+ Label {
+ name: &'a str,
+ kind: Structure,
+ header: Option<String>,
+ footer: Option<String>,
text: String,
- ty: Structure,
},
- Argument {
+ UserCommand {
name: &'a str,
- image: Option<&'a str>,
},
- BeginCommand,
- Color {
+ UserEnvironment {
name: &'a str,
},
- ColorModel {
+ PgfLibrary {
name: &'a str,
},
- GlossaryEntry {
+ TikzLibrary {
name: &'a str,
},
- EntryType {
- ty: &'a BibtexEntryTypeDoc,
- },
- Field {
- field: &'a BibtexFieldDoc,
- },
}
-impl<'a> ItemData<'a> {
- pub fn label<'b: 'a>(&'b self) -> &'b str {
+impl<'a> InternalCompletionItemData<'a> {
+ pub fn label<'b: 'a>(&'b self) -> &'a str {
match self {
+ Self::EntryType { ty } => &ty.name,
+ Self::Field { field } => &field.name,
+ Self::Argument { name, .. } => name,
+ Self::BeginCommand => "begin",
+ Self::Citation { key, .. } => &key,
Self::ComponentCommand { name, .. } => name,
Self::ComponentEnvironment { name, .. } => name,
+ Self::Class { name } => name,
+ Self::Package { name } => name,
+ Self::Color { name } => name,
+ Self::ColorModel { name } => name,
+ Self::Acronym { name } => name,
+ Self::GlossaryEntry { name } => name,
+ Self::File { name } => name,
+ Self::Directory { name } => name,
+ Self::Label { name, .. } => name,
Self::UserCommand { name } => name,
Self::UserEnvironment { name } => name,
- Self::Label { name, .. } => name,
- Self::Class { name } => &name,
- Self::Package { name } => &name,
Self::PgfLibrary { name } => name,
Self::TikzLibrary { name } => name,
- Self::File { name } => &name,
- Self::Directory { name } => &name,
- Self::Citation { key, .. } => key,
- Self::Argument { name, .. } => name,
- Self::BeginCommand => "begin",
- Self::Color { name } => name,
- Self::ColorModel { name } => name,
- Self::GlossaryEntry { name } => name,
- Self::EntryType { ty } => &ty.name,
- Self::Field { field } => &field.name,
}
}
}
@@ -138,13 +143,8 @@ pub enum CompletionItemData {
Class,
EntryType,
FieldName,
- Citation { uri: Uri, key: String },
+ Citation { uri: Uri, key: SmolStr },
Argument,
+ Acronym,
GlossaryEntry,
}
-
-impl Into<serde_json::Value> for CompletionItemData {
- fn into(self) -> serde_json::Value {
- serde_json::to_value(self).unwrap()
- }
-}
diff --git a/support/texlab/src/features/completion/user_command.rs b/support/texlab/src/features/completion/user_command.rs
new file mode 100644
index 0000000000..8b4473f31c
--- /dev/null
+++ b/support/texlab/src/features/completion/user_command.rs
@@ -0,0 +1,100 @@
+use cancellation::CancellationToken;
+use lsp_types::CompletionParams;
+
+use crate::features::cursor::CursorContext;
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_user_commands<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let range = context.cursor.command_range(context.offset)?;
+ let token = context.cursor.as_latex()?;
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for name in data
+ .extras
+ .command_names
+ .iter()
+ .filter(|name| name.as_str() != token.text())
+ .map(|name| &name[1..])
+ {
+ cancellation_token.result().ok()?;
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::UserCommand { name },
+ ));
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_user_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_user_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\foo\\bar")])
+ .main("main.tex")
+ .line(0)
+ .character(4)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_user_commands(&context, &mut actual_items, CancellationToken::none());
+
+ assert_eq!(actual_items.len(), 1);
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(1.into(), 4.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/user_environment.rs b/support/texlab/src/features/completion/user_environment.rs
new file mode 100644
index 0000000000..a1a5701fac
--- /dev/null
+++ b/support/texlab/src/features/completion/user_environment.rs
@@ -0,0 +1,116 @@
+use cancellation::CancellationToken;
+use cstree::TextRange;
+use lsp_types::CompletionParams;
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+};
+
+use super::types::{InternalCompletionItem, InternalCompletionItemData};
+
+pub fn complete_user_environments<'a>(
+ context: &'a CursorContext<CompletionParams>,
+ items: &mut Vec<InternalCompletionItem<'a>>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let token = context.cursor.as_latex()?;
+ let group = latex::CurlyGroupWord::cast(token.parent())
+ .filter(|group| context.is_inside_latex_curly(group))?;
+ if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) {
+ return None;
+ }
+
+ let range = if token.kind() == latex::WORD {
+ token.text_range()
+ } else {
+ TextRange::empty(context.offset)
+ };
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for name in data
+ .extras
+ .environment_names
+ .iter()
+ .filter(|name| name.as_str() != token.text())
+ {
+ cancellation_token.result().ok()?;
+ items.push(InternalCompletionItem::new(
+ range,
+ InternalCompletionItemData::UserEnvironment { name },
+ ));
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use cstree::TextRange;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_user_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_user_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(actual_items.is_empty());
+ }
+
+ #[test]
+ fn test_latex_simple() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.tex",
+ "\\begin{foo}\\end{foo} \\begin{bar}\\end{bar}",
+ )])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_user_environments(&context, &mut actual_items, CancellationToken::none());
+
+ assert_eq!(actual_items.len(), 1);
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(7.into(), 10.into()));
+ }
+ }
+}
diff --git a/support/texlab/src/features/completion/util.rs b/support/texlab/src/features/completion/util.rs
new file mode 100644
index 0000000000..296d6d25d9
--- /dev/null
+++ b/support/texlab/src/features/completion/util.rs
@@ -0,0 +1,66 @@
+use lsp_types::{CompletionItemKind, CompletionParams, Documentation, MarkupContent, MarkupKind};
+use smol_str::SmolStr;
+
+use crate::features::FeatureRequest;
+
+pub fn component_detail(file_names: &[SmolStr]) -> String {
+ if file_names.is_empty() {
+ "built-in".to_owned()
+ } else {
+ file_names.join(", ")
+ }
+}
+
+pub fn image_documentation(
+ request: &FeatureRequest<CompletionParams>,
+ name: &str,
+ image: &str,
+) -> Option<Documentation> {
+ if supports_images(request) {
+ Some(Documentation::MarkupContent(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: format!(
+ "![{}](data:image/png;base64,{}|width=48,height=48)",
+ name, image
+ ),
+ }))
+ } else {
+ None
+ }
+}
+
+fn supports_images(request: &FeatureRequest<CompletionParams>) -> bool {
+ request
+ .context
+ .client_capabilities
+ .lock()
+ .unwrap()
+ .text_document
+ .as_ref()
+ .and_then(|cap| cap.completion.as_ref())
+ .and_then(|cap| cap.completion_item.as_ref())
+ .and_then(|cap| cap.documentation_format.as_ref())
+ .map_or(true, |formats| formats.contains(&MarkupKind::Markdown))
+}
+
+pub fn adjust_kind(
+ request: &FeatureRequest<CompletionParams>,
+ kind: CompletionItemKind,
+) -> CompletionItemKind {
+ if let Some(value_set) = request
+ .context
+ .client_capabilities
+ .lock()
+ .unwrap()
+ .text_document
+ .as_ref()
+ .and_then(|cap| cap.completion.as_ref())
+ .and_then(|cap| cap.completion_item_kind.as_ref())
+ .and_then(|cap| cap.value_set.as_ref())
+ {
+ if value_set.contains(&kind) {
+ return kind;
+ }
+ }
+ CompletionItemKind::Text
+}
diff --git a/support/texlab/src/features/cursor.rs b/support/texlab/src/features/cursor.rs
new file mode 100644
index 0000000000..19079b841b
--- /dev/null
+++ b/support/texlab/src/features/cursor.rs
@@ -0,0 +1,252 @@
+use cstree::{TextRange, TextSize};
+use lsp_types::{
+ CompletionParams, GotoDefinitionParams, HoverParams, Position, ReferenceParams, RenameParams,
+ TextDocumentPositionParams,
+};
+
+use crate::{
+ syntax::{bibtex, latex, CstNode},
+ DocumentData, LineIndexExt,
+};
+
+use super::FeatureRequest;
+
+#[derive(Debug)]
+pub enum Cursor {
+ Latex(latex::SyntaxToken),
+ Bibtex(bibtex::SyntaxToken),
+ Nothing,
+}
+
+impl Cursor {
+ pub fn new_latex(
+ left: Option<latex::SyntaxToken>,
+ right: Option<latex::SyntaxToken>,
+ ) -> Option<Self> {
+ let left = left?;
+ let right = right?;
+
+ if left.kind().is_command_name() {
+ return Some(Self::Latex(left));
+ }
+
+ if right.kind() == latex::WORD {
+ return Some(Self::Latex(right));
+ }
+
+ if left.kind() == latex::WORD {
+ return Some(Self::Latex(left));
+ }
+
+ if right.kind().is_command_name() {
+ return Some(Self::Latex(right));
+ }
+
+ Some(Self::Latex(right))
+ }
+
+ pub fn new_bibtex(
+ left: Option<bibtex::SyntaxToken>,
+ right: Option<bibtex::SyntaxToken>,
+ ) -> Option<Self> {
+ let left = left?;
+ let right = right?;
+
+ if right.kind().is_type() {
+ return Some(Self::Bibtex(right));
+ }
+
+ if left.kind().is_type() {
+ return Some(Self::Bibtex(left));
+ }
+
+ if left.kind() == bibtex::COMMAND_NAME {
+ return Some(Self::Bibtex(left));
+ }
+
+ if right.kind() == bibtex::WORD {
+ return Some(Self::Bibtex(right));
+ }
+
+ if left.kind() == bibtex::WORD {
+ return Some(Self::Bibtex(left));
+ }
+
+ if right.kind() == bibtex::COMMAND_NAME {
+ return Some(Self::Bibtex(right));
+ }
+
+ Some(Self::Bibtex(right))
+ }
+
+ pub fn as_latex(&self) -> Option<&latex::SyntaxToken> {
+ if let Self::Latex(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
+
+ pub fn as_bibtex(&self) -> Option<&bibtex::SyntaxToken> {
+ if let Self::Bibtex(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
+
+ pub fn command_range(&self, offset: TextSize) -> Option<TextRange> {
+ self.as_latex()
+ .filter(|token| token.kind().is_command_name())
+ .filter(|token| token.text_range().start() != offset)
+ .map(|token| token.text_range())
+ .map(|range| TextRange::new(range.start() + TextSize::from(1), range.end()))
+ .or_else(|| {
+ self.as_bibtex()
+ .filter(|token| token.kind() == bibtex::COMMAND_NAME)
+ .filter(|token| token.text_range().start() != offset)
+ .map(|token| token.text_range())
+ .map(|range| TextRange::new(range.start() + TextSize::from(1), range.end()))
+ })
+ }
+}
+
+pub struct CursorContext<P> {
+ pub request: FeatureRequest<P>,
+ pub cursor: Cursor,
+ pub offset: TextSize,
+}
+
+impl<P: HasPosition> CursorContext<P> {
+ pub fn new(request: FeatureRequest<P>) -> Self {
+ let main_document = request.main_document();
+ let offset = main_document
+ .line_index
+ .offset_lsp(request.params.position());
+
+ let cursor = match &main_document.data {
+ DocumentData::Latex(data) => {
+ let left = data.root.token_at_offset(offset).left_biased();
+ let right = data.root.token_at_offset(offset).right_biased();
+ Cursor::new_latex(left, right)
+ }
+ DocumentData::Bibtex(data) => {
+ let left = data.root.token_at_offset(offset).left_biased();
+ let right = data.root.token_at_offset(offset).right_biased();
+ Cursor::new_bibtex(left, right)
+ }
+ DocumentData::BuildLog(_) => None,
+ };
+
+ Self {
+ request,
+ cursor: cursor.unwrap_or(Cursor::Nothing),
+ offset,
+ }
+ }
+
+ pub fn is_inside_latex_curly<'a>(&self, group: &impl latex::HasCurly<'a>) -> bool {
+ group.small_range().contains(self.offset) || group.right_curly().is_none()
+ }
+
+ pub fn find_citation_key_word(&self) -> Option<(&str, TextRange)> {
+ let key = self
+ .cursor
+ .as_latex()
+ .filter(|token| token.kind() == latex::WORD)?;
+
+ let group = latex::CurlyGroupWordList::cast(key.parent())?;
+ latex::Citation::cast(group.syntax().parent()?)?;
+ Some((key.text(), key.text_range()))
+ }
+
+ pub fn find_citation_key_command(&self) -> Option<(&str, TextRange)> {
+ let command = self.cursor.as_latex()?;
+
+ let citation = latex::Citation::cast(command.parent())?;
+ let key = citation.key_list()?.words().next()?;
+ Some((key.text(), key.text_range()))
+ }
+
+ pub fn find_entry_key(&self) -> Option<(&str, TextRange)> {
+ let key = self
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind() == bibtex::WORD)?;
+
+ bibtex::Entry::cast(key.parent())?;
+ Some((key.text(), key.text_range()))
+ }
+
+ pub fn find_label_name_word(&self) -> Option<(&str, TextRange)> {
+ let name = self
+ .cursor
+ .as_latex()
+ .filter(|token| token.kind() == latex::WORD)?;
+
+ if matches!(
+ name.parent().parent()?.kind(),
+ latex::LABEL_DEFINITION | latex::LABEL_REFERENCE | latex::LABEL_REFERENCE_RANGE
+ ) {
+ Some((name.text(), name.text_range()))
+ } else {
+ None
+ }
+ }
+
+ pub fn find_label_name_command(&self) -> Option<(&str, TextRange)> {
+ let node = self.cursor.as_latex()?.parent();
+ if let Some(label) = latex::LabelDefinition::cast(node) {
+ let name = label.name()?.word()?;
+ Some((name.text(), name.text_range()))
+ } else if let Some(label) = latex::LabelReference::cast(node) {
+ let name = label.name_list()?.words().next()?;
+ Some((name.text(), name.text_range()))
+ } else if let Some(label) = latex::LabelReferenceRange::cast(node) {
+ let name = label.from()?.word()?;
+ Some((name.text(), name.text_range()))
+ } else {
+ None
+ }
+ }
+}
+
+pub trait HasPosition {
+ fn position(&self) -> Position;
+}
+
+impl HasPosition for CompletionParams {
+ fn position(&self) -> Position {
+ self.text_document_position.position
+ }
+}
+
+impl HasPosition for TextDocumentPositionParams {
+ fn position(&self) -> Position {
+ self.position
+ }
+}
+
+impl HasPosition for RenameParams {
+ fn position(&self) -> Position {
+ self.text_document_position.position
+ }
+}
+
+impl HasPosition for ReferenceParams {
+ fn position(&self) -> Position {
+ self.text_document_position.position
+ }
+}
+
+impl HasPosition for HoverParams {
+ fn position(&self) -> Position {
+ self.text_document_position_params.position
+ }
+}
+
+impl HasPosition for GotoDefinitionParams {
+ fn position(&self) -> Position {
+ self.text_document_position_params.position
+ }
+}
diff --git a/support/texlab/src/features/definition.rs b/support/texlab/src/features/definition.rs
new file mode 100644
index 0000000000..c49f172399
--- /dev/null
+++ b/support/texlab/src/features/definition.rs
@@ -0,0 +1,29 @@
+mod command;
+mod document;
+mod entry;
+mod label;
+mod string;
+
+use cancellation::CancellationToken;
+use lsp_types::{GotoDefinitionParams, GotoDefinitionResponse};
+
+use self::{
+ command::goto_command_definition, document::goto_document_definition,
+ entry::goto_entry_definition, label::goto_label_definition, string::goto_string_definition,
+};
+
+use super::{cursor::CursorContext, FeatureRequest};
+
+pub fn goto_definition(
+ request: FeatureRequest<GotoDefinitionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<GotoDefinitionResponse> {
+ let context = CursorContext::new(request);
+ log::debug!("[Definition] Cursor: {:?}", context.cursor);
+ let links = goto_command_definition(&context, cancellation_token)
+ .or_else(|| goto_document_definition(&context, cancellation_token))
+ .or_else(|| goto_entry_definition(&context, cancellation_token))
+ .or_else(|| goto_label_definition(&context, cancellation_token))
+ .or_else(|| goto_string_definition(&context, cancellation_token))?;
+ Some(GotoDefinitionResponse::Link(links))
+}
diff --git a/support/texlab/src/features/definition/command.rs b/support/texlab/src/features/definition/command.rs
new file mode 100644
index 0000000000..a69796c33f
--- /dev/null
+++ b/support/texlab/src/features/definition/command.rs
@@ -0,0 +1,131 @@
+use cancellation::CancellationToken;
+use lsp_types::{GotoDefinitionParams, LocationLink};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{latex, CstNode},
+ LineIndexExt,
+};
+
+pub fn goto_command_definition(
+ context: &CursorContext<GotoDefinitionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<LocationLink>> {
+ let main_document = context.request.main_document();
+
+ let name = context
+ .cursor
+ .as_latex()
+ .filter(|token| token.kind().is_command_name())?;
+
+ let origin_selection_range = main_document
+ .line_index
+ .line_col_lsp_range(name.text_range());
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ for node in data.root.descendants() {
+ cancellation_token.result().ok()?;
+
+ if let Some(defintion) = latex::CommandDefinition::cast(node).filter(|def| {
+ def.name()
+ .and_then(|name| name.command())
+ .map(|name| name.text())
+ == Some(name.text())
+ }) {
+ let target_selection_range = document
+ .line_index
+ .line_col_lsp_range(defintion.name()?.command()?.text_range());
+
+ let target_range = document
+ .line_index
+ .line_col_lsp_range(defintion.small_range());
+
+ return Some(vec![LocationLink {
+ origin_selection_range: Some(origin_selection_range),
+ target_uri: document.uri.as_ref().clone().into(),
+ target_range,
+ target_selection_range,
+ }]);
+ }
+ }
+ }
+ }
+
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use indoc::indoc;
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+
+ let actual_links = goto_command_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_command_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_command_definition() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.tex",
+ indoc! {
+ r#"
+ \DeclareMathOperator{\foo}{foo}
+ \foo
+ "#
+ },
+ )])
+ .main("main.tex")
+ .line(1)
+ .character(2)
+ .build();
+ let target_uri = tester.uri("main.tex").as_ref().clone().into();
+
+ let request = tester.definition();
+ let context = CursorContext::new(request);
+ let actual_links = goto_command_definition(&context, CancellationToken::none()).unwrap();
+
+ let expected_links = vec![LocationLink {
+ origin_selection_range: Some(Range::new_simple(1, 0, 1, 4)),
+ target_uri,
+ target_range: Range::new_simple(0, 0, 0, 31),
+ target_selection_range: Range::new_simple(0, 21, 0, 25),
+ }];
+
+ assert_eq!(actual_links, expected_links);
+ }
+}
diff --git a/support/texlab/src/features/definition/document.rs b/support/texlab/src/features/definition/document.rs
new file mode 100644
index 0000000000..b2b713f260
--- /dev/null
+++ b/support/texlab/src/features/definition/document.rs
@@ -0,0 +1,112 @@
+use cancellation::CancellationToken;
+use lsp_types::{GotoDefinitionParams, LocationLink, Range};
+
+use crate::{features::cursor::CursorContext, LineIndexExt, RangeExt};
+
+pub fn goto_document_definition(
+ context: &CursorContext<GotoDefinitionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<LocationLink>> {
+ let main_document = context.request.main_document();
+ if let Some(data) = main_document.data.as_latex() {
+ for include in data
+ .extras
+ .explicit_links
+ .iter()
+ .filter(|link| link.stem_range.contains_inclusive(context.offset))
+ {
+ for target in &include.targets {
+ cancellation_token.result().ok()?;
+
+ if context
+ .request
+ .subset
+ .documents
+ .iter()
+ .any(|document| document.uri.as_ref() == target.as_ref())
+ {
+ return Some(vec![LocationLink {
+ origin_selection_range: Some(
+ main_document
+ .line_index
+ .line_col_lsp_range(include.stem_range),
+ ),
+ target_uri: target.as_ref().clone().into(),
+ target_range: Range::new_simple(0, 0, 0, 0),
+ target_selection_range: Range::new_simple(0, 0, 0, 0),
+ }]);
+ }
+ }
+ }
+ }
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_document_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_document_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_simple() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\addbibresource{baz.bib}"#),
+ ("bar.bib", r#"@article{foo, bar = {baz}}"#),
+ ("baz.bib", r#"@article{foo, bar = {baz}}"#),
+ ])
+ .main("foo.tex")
+ .line(0)
+ .character(18)
+ .build();
+ let target_uri = tester.uri("baz.bib").as_ref().clone().into();
+
+ let request = tester.definition();
+ let context = CursorContext::new(request);
+ let actual_links = goto_document_definition(&context, CancellationToken::none()).unwrap();
+
+ let expected_links = vec![LocationLink {
+ origin_selection_range: Some(Range::new_simple(0, 16, 0, 23)),
+ target_uri,
+ target_range: Range::new_simple(0, 0, 0, 0),
+ target_selection_range: Range::new_simple(0, 0, 0, 0),
+ }];
+
+ assert_eq!(actual_links, expected_links);
+ }
+}
diff --git a/support/texlab/src/features/definition/entry.rs b/support/texlab/src/features/definition/entry.rs
new file mode 100644
index 0000000000..7f489ec848
--- /dev/null
+++ b/support/texlab/src/features/definition/entry.rs
@@ -0,0 +1,125 @@
+use cancellation::CancellationToken;
+use lsp_types::{GotoDefinitionParams, LocationLink};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, latex, CstNode},
+ LineIndexExt,
+};
+
+pub fn goto_entry_definition(
+ context: &CursorContext<GotoDefinitionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<LocationLink>> {
+ let main_document = context.request.main_document();
+
+ let key = context
+ .cursor
+ .as_latex()
+ .filter(|token| token.kind() == latex::WORD)?;
+
+ latex::Citation::cast(key.parent().parent()?)?;
+
+ let origin_selection_range = main_document
+ .line_index
+ .line_col_lsp_range(key.text_range());
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_bibtex() {
+ for entry in data.root.children().filter_map(bibtex::Entry::cast) {
+ cancellation_token.result().ok()?;
+
+ if let Some(key) = entry.key().filter(|k| k.text() == key.text()) {
+ return Some(vec![LocationLink {
+ origin_selection_range: Some(origin_selection_range),
+ target_uri: document.uri.as_ref().clone().into(),
+ target_selection_range: document
+ .line_index
+ .line_col_lsp_range(key.text_range()),
+ target_range: document.line_index.line_col_lsp_range(entry.small_range()),
+ }]);
+ }
+ }
+ }
+ }
+
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use indoc::indoc;
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_entry_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_entry_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_simple() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ (
+ "foo.tex",
+ indoc!(
+ r#"
+ \addbibresource{baz.bib}
+ \cite{foo}
+ "#
+ ),
+ ),
+ ("bar.bib", r#"@article{foo, bar = {baz}}"#),
+ ("baz.bib", r#"@article{foo, bar = {baz}}"#),
+ ])
+ .main("foo.tex")
+ .line(1)
+ .character(6)
+ .build();
+ let target_uri = tester.uri("baz.bib").as_ref().clone().into();
+
+ let request = tester.definition();
+ let context = CursorContext::new(request);
+ let actual_links = goto_entry_definition(&context, CancellationToken::none()).unwrap();
+
+ let expected_links = vec![LocationLink {
+ origin_selection_range: Some(Range::new_simple(1, 6, 1, 9)),
+ target_uri,
+ target_range: Range::new_simple(0, 0, 0, 26),
+ target_selection_range: Range::new_simple(0, 9, 0, 12),
+ }];
+
+ assert_eq!(actual_links, expected_links);
+ }
+}
diff --git a/support/texlab/src/features/definition/label.rs b/support/texlab/src/features/definition/label.rs
new file mode 100644
index 0000000000..65f0981de0
--- /dev/null
+++ b/support/texlab/src/features/definition/label.rs
@@ -0,0 +1,80 @@
+use cancellation::CancellationToken;
+use lsp_types::{GotoDefinitionParams, LocationLink};
+
+use crate::{features::cursor::CursorContext, find_label_definition, render_label, LineIndexExt};
+
+pub fn goto_label_definition(
+ context: &CursorContext<GotoDefinitionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<LocationLink>> {
+ let main_document = context.request.main_document();
+
+ let (name_text, name_range) = context
+ .find_label_name_word()
+ .or_else(|| context.find_label_name_command())?;
+
+ let origin_selection_range = main_document.line_index.line_col_lsp_range(name_range);
+
+ for document in &context.request.subset.documents {
+ cancellation_token.result().ok()?;
+ if let Some(data) = document.data.as_latex() {
+ if let Some(definition) = find_label_definition(&data.root, name_text) {
+ let target_selection_range = definition.name()?.word()?.text_range();
+ let target_range =
+ render_label(&context.request.subset, name_text, Some(definition))
+ .map(|label| label.range)
+ .unwrap_or(target_selection_range);
+
+ return Some(vec![LocationLink {
+ origin_selection_range: Some(origin_selection_range),
+ target_uri: document.uri.as_ref().clone().into(),
+ target_range: document.line_index.line_col_lsp_range(target_range),
+ target_selection_range: document
+ .line_index
+ .line_col_lsp_range(target_selection_range),
+ }]);
+ }
+ }
+ }
+
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_label_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_label_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+}
diff --git a/support/texlab/src/features/definition/string.rs b/support/texlab/src/features/definition/string.rs
new file mode 100644
index 0000000000..7162c8b722
--- /dev/null
+++ b/support/texlab/src/features/definition/string.rs
@@ -0,0 +1,176 @@
+use cancellation::CancellationToken;
+use lsp_types::{GotoDefinitionParams, LocationLink};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, CstNode},
+ LineIndexExt,
+};
+
+pub fn goto_string_definition(
+ context: &CursorContext<GotoDefinitionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<LocationLink>> {
+ let main_document = context.request.main_document();
+
+ let data = main_document.data.as_bibtex()?;
+ let name = context
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind() == bibtex::WORD)?;
+
+ bibtex::Token::cast(name.parent())?;
+
+ let origin_selection_range = main_document
+ .line_index
+ .line_col_lsp_range(name.text_range());
+
+ for string in data.root.children().filter_map(bibtex::String::cast) {
+ cancellation_token.result().ok()?;
+
+ if let Some(string_name) = string.name().filter(|n| n.text() == name.text()) {
+ return Some(vec![LocationLink {
+ origin_selection_range: Some(origin_selection_range),
+ target_uri: main_document.uri.as_ref().clone().into(),
+ target_selection_range: main_document
+ .line_index
+ .line_col_lsp_range(string_name.text_range()),
+ target_range: main_document
+ .line_index
+ .line_col_lsp_range(string.small_range()),
+ }]);
+ }
+ }
+
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use indoc::indoc;
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_string_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .definition();
+
+ let context = CursorContext::new(request);
+ let actual_links = goto_string_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_simple() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! {
+ r#"
+ @string{foo = {bar}}
+ @article{bar, author = foo}
+ "#
+ },
+ )])
+ .main("main.bib")
+ .line(1)
+ .character(24)
+ .build();
+ let target_uri = tester.uri("main.bib").as_ref().clone().into();
+
+ let request = tester.definition();
+ let context = CursorContext::new(request);
+ let actual_links = goto_string_definition(&context, CancellationToken::none()).unwrap();
+
+ let expected_links = vec![LocationLink {
+ origin_selection_range: Some(Range::new_simple(1, 23, 1, 26)),
+ target_uri,
+ target_range: Range::new_simple(0, 0, 0, 20),
+ target_selection_range: Range::new_simple(0, 8, 0, 11),
+ }];
+
+ assert_eq!(actual_links, expected_links);
+ }
+
+ #[test]
+ fn concat() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! {
+ r#"
+ @string{foo = {bar}}
+ @article{bar, author = foo # "bar"}
+ "#
+ },
+ )])
+ .main("main.bib")
+ .line(1)
+ .character(24)
+ .build();
+ let target_uri = tester.uri("main.bib").as_ref().clone().into();
+
+ let request = tester.definition();
+ let context = CursorContext::new(request);
+ let actual_links = goto_string_definition(&context, CancellationToken::none()).unwrap();
+
+ let expected_links = vec![LocationLink {
+ origin_selection_range: Some(Range::new_simple(1, 23, 1, 26)),
+ target_uri,
+ target_range: Range::new_simple(0, 0, 0, 20),
+ target_selection_range: Range::new_simple(0, 8, 0, 11),
+ }];
+
+ assert_eq!(actual_links, expected_links);
+ }
+
+ #[test]
+ fn test_field() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! {
+ r#"
+ @string{foo = {bar}}
+ @article{bar, author = foo}
+ "#
+ },
+ )])
+ .main("main.bib")
+ .line(1)
+ .character(18)
+ .build();
+
+ let request = tester.definition();
+ let context = CursorContext::new(request);
+ let actual_links = goto_string_definition(&context, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+}
diff --git a/support/texlab/src/features/folding.rs b/support/texlab/src/features/folding.rs
new file mode 100644
index 0000000000..0c44b6aa61
--- /dev/null
+++ b/support/texlab/src/features/folding.rs
@@ -0,0 +1,237 @@
+use cancellation::CancellationToken;
+use lsp_types::{FoldingRange, FoldingRangeKind, FoldingRangeParams, Range};
+
+use crate::{
+ syntax::{bibtex, latex, CstNode},
+ DocumentData, LineIndexExt,
+};
+
+use super::FeatureRequest;
+
+pub fn find_foldings(
+ request: FeatureRequest<FoldingRangeParams>,
+ token: &CancellationToken,
+) -> Vec<FoldingRange> {
+ let mut foldings = Vec::new();
+ let main_document = request.main_document();
+ match &main_document.data {
+ DocumentData::Latex(data) => {
+ for node in data.root.descendants() {
+ if token.is_canceled() {
+ break;
+ }
+
+ if let Some(folding) = latex::Environment::cast(node)
+ .map(|node| node.small_range())
+ .or_else(|| latex::Section::cast(node).map(|node| node.small_range()))
+ .or_else(|| latex::EnumItem::cast(node).map(|node| node.small_range()))
+ .map(|node| main_document.line_index.line_col_lsp_range(node))
+ .map(create_range)
+ {
+ foldings.push(folding);
+ }
+ }
+ }
+ DocumentData::Bibtex(data) => {
+ for node in data.root.descendants() {
+ if token.is_canceled() {
+ break;
+ }
+
+ if let Some(folding) = bibtex::Preamble::cast(node)
+ .map(|node| node.small_range())
+ .or_else(|| bibtex::String::cast(node).map(|node| node.small_range()))
+ .or_else(|| bibtex::Entry::cast(node).map(|node| node.small_range()))
+ .map(|node| main_document.line_index.line_col_lsp_range(node))
+ .map(create_range)
+ {
+ foldings.push(folding);
+ }
+ }
+ }
+ DocumentData::BuildLog(_) => {}
+ }
+ foldings
+}
+
+fn create_range(range: Range) -> FoldingRange {
+ FoldingRange {
+ start_line: range.start.line,
+ start_character: Some(range.start.character),
+ end_line: range.end.line,
+ end_character: Some(range.end.character),
+ kind: Some(FoldingRangeKind::Region),
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use indoc::indoc;
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .build()
+ .folding();
+
+ let actual_foldings = find_foldings(request, CancellationToken::none());
+ assert!(actual_foldings.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .build()
+ .folding();
+
+ let actual_foldings = find_foldings(request, CancellationToken::none());
+ assert!(actual_foldings.is_empty());
+ }
+
+ #[test]
+ fn test_latex() {
+ let req = FeatureTester::builder()
+ .files(vec![(
+ "main.tex",
+ indoc! {r#"
+ \begin{document}
+ \section{Foo}
+ foo
+ \subsection{Bar}
+ bar
+ \section{Baz}
+ baz
+ \section{Qux}
+ \end{document}"# },
+ )])
+ .main("main.tex")
+ .build()
+ .folding();
+
+ let mut actual_foldings = find_foldings(req, CancellationToken::none());
+ actual_foldings.sort_by_key(|folding| (folding.start_line, folding.start_character));
+
+ assert_eq!(actual_foldings.len(), 5);
+ assert_eq!(
+ actual_foldings[0],
+ FoldingRange {
+ start_line: 0,
+ start_character: Some(0),
+ end_line: 8,
+ end_character: Some(14),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ assert_eq!(
+ actual_foldings[1],
+ FoldingRange {
+ start_line: 1,
+ start_character: Some(4),
+ end_line: 4,
+ end_character: Some(7),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ assert_eq!(
+ actual_foldings[2],
+ FoldingRange {
+ start_line: 3,
+ start_character: Some(4),
+ end_line: 4,
+ end_character: Some(7),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ assert_eq!(
+ actual_foldings[3],
+ FoldingRange {
+ start_line: 5,
+ start_character: Some(4),
+ end_line: 6,
+ end_character: Some(7),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ assert_eq!(
+ actual_foldings[4],
+ FoldingRange {
+ start_line: 7,
+ start_character: Some(4),
+ end_line: 7,
+ end_character: Some(17),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ }
+
+ #[test]
+ fn test_bibtex() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! {r#"
+ some junk
+ here
+
+ @article{foo,
+ author = {bar},
+ title = {baz}
+ }
+
+ @string{foo = "bar"}
+
+ @comment{foo,
+ author = {bar},
+ title = {baz}
+ }
+
+ @preamble{"foo"}"# },
+ )])
+ .main("main.bib")
+ .build()
+ .folding();
+
+ let mut actual_foldings = find_foldings(request, CancellationToken::none());
+ actual_foldings.sort_by_key(|folding| (folding.start_line, folding.start_character));
+
+ assert_eq!(actual_foldings.len(), 3);
+ assert_eq!(
+ actual_foldings[0],
+ FoldingRange {
+ start_line: 3,
+ start_character: Some(0),
+ end_line: 6,
+ end_character: Some(1),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ assert_eq!(
+ actual_foldings[1],
+ FoldingRange {
+ start_line: 8,
+ start_character: Some(0),
+ end_line: 8,
+ end_character: Some(20),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ assert_eq!(
+ actual_foldings[2],
+ FoldingRange {
+ start_line: 15,
+ start_character: Some(0),
+ end_line: 15,
+ end_character: Some(16),
+ kind: Some(FoldingRangeKind::Region)
+ }
+ );
+ }
+}
diff --git a/support/texlab/src/features/formatting.rs b/support/texlab/src/features/formatting.rs
new file mode 100644
index 0000000000..4492a0532d
--- /dev/null
+++ b/support/texlab/src/features/formatting.rs
@@ -0,0 +1,24 @@
+mod bibtex_internal;
+mod latexindent;
+
+use cancellation::CancellationToken;
+use lsp_types::{DocumentFormattingParams, TextEdit};
+
+use crate::BibtexFormatter;
+
+use self::{bibtex_internal::format_bibtex_internal, latexindent::format_with_latexindent};
+
+use super::FeatureRequest;
+
+pub fn format_source_code(
+ request: FeatureRequest<DocumentFormattingParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<TextEdit>> {
+ let mut edits = None;
+ if request.context.options.read().unwrap().bibtex_formatter == BibtexFormatter::Texlab {
+ edits = edits.or_else(|| format_bibtex_internal(&request, cancellation_token));
+ }
+
+ edits = edits.or_else(|| format_with_latexindent(&request, cancellation_token));
+ edits
+}
diff --git a/support/texlab/src/features/formatting/bibtex_internal.rs b/support/texlab/src/features/formatting/bibtex_internal.rs
new file mode 100644
index 0000000000..8481f561e7
--- /dev/null
+++ b/support/texlab/src/features/formatting/bibtex_internal.rs
@@ -0,0 +1,381 @@
+use cancellation::CancellationToken;
+use cstree::NodeOrToken;
+use lsp_types::{DocumentFormattingParams, TextEdit};
+
+use crate::{
+ features::FeatureRequest,
+ syntax::{
+ bibtex::{self, HasType},
+ CstNode,
+ },
+ LineIndex, LineIndexExt,
+};
+
+pub fn format_bibtex_internal(
+ request: &FeatureRequest<DocumentFormattingParams>,
+ _cancellation_token: &CancellationToken,
+) -> Option<Vec<TextEdit>> {
+ let mut indent = String::new();
+ if request.params.options.insert_spaces {
+ for _ in 0..request.params.options.tab_size {
+ indent.push(' ');
+ }
+ } else {
+ indent.push('\t');
+ }
+
+ let line_length = {
+ request
+ .context
+ .options
+ .read()
+ .unwrap()
+ .formatter_line_length
+ .map(|value| {
+ if value <= 0 {
+ usize::MAX
+ } else {
+ value as usize
+ }
+ })
+ .unwrap_or(80)
+ };
+
+ let document = request.main_document();
+ let data = document.data.as_bibtex()?;
+ let mut edits = Vec::new();
+
+ for node in data.root.children() {
+ let range = if let Some(entry) = bibtex::Entry::cast(node) {
+ entry.small_range()
+ } else if let Some(string) = bibtex::String::cast(node) {
+ string.small_range()
+ } else if let Some(preamble) = bibtex::Preamble::cast(node) {
+ preamble.small_range()
+ } else {
+ continue;
+ };
+
+ let mut formatter = Formatter::new(
+ indent.clone(),
+ request.params.options.tab_size,
+ line_length,
+ &document.line_index,
+ );
+
+ formatter.visit_node(node);
+ edits.push(TextEdit {
+ range: document.line_index.line_col_lsp_range(range),
+ new_text: formatter.output,
+ });
+ }
+
+ Some(edits)
+}
+
+struct Formatter<'a> {
+ indent: String,
+ tab_size: u32,
+ line_length: usize,
+ output: String,
+ align: Vec<usize>,
+ line_index: &'a LineIndex,
+}
+
+impl<'a> Formatter<'a> {
+ fn new(indent: String, tab_size: u32, line_length: usize, line_index: &'a LineIndex) -> Self {
+ Self {
+ indent,
+ tab_size,
+ line_length,
+ output: String::new(),
+ align: Vec::new(),
+ line_index,
+ }
+ }
+
+ fn visit_token_lowercase(&mut self, token: &bibtex::SyntaxToken) {
+ self.output.push_str(&token.text().to_lowercase());
+ }
+
+ fn should_insert_space(
+ &self,
+ previous: &bibtex::SyntaxToken,
+ current: &bibtex::SyntaxToken,
+ ) -> bool {
+ let previous_range = self.line_index.line_col_lsp_range(previous.text_range());
+ let current_range = self.line_index.line_col_lsp_range(current.text_range());
+ previous_range.start.line != current_range.start.line
+ || previous_range.end.character < current_range.start.character
+ }
+
+ fn base_align(&self) -> usize {
+ self.output[self.output.rfind('\n').unwrap_or(0)..]
+ .chars()
+ .count()
+ }
+
+ fn visit_node(&mut self, parent: &bibtex::SyntaxNode) {
+ match parent.kind() {
+ bibtex::PREAMBLE => {
+ let preamble = bibtex::Preamble::cast(parent).unwrap();
+ self.visit_token_lowercase(preamble.ty().unwrap());
+ self.output.push('{');
+ if preamble.syntax().arity() > 0 {
+ self.align.push(self.base_align());
+ for node in preamble.syntax().children() {
+ self.visit_node(node);
+ }
+ self.output.push('}');
+ }
+ }
+ bibtex::STRING => {
+ let string = bibtex::String::cast(parent).unwrap();
+ self.visit_token_lowercase(string.ty().unwrap());
+ self.output.push('{');
+ if let Some(name) = string.name() {
+ self.output.push_str(name.text());
+ self.output.push_str(" = ");
+ if let Some(value) = string.value() {
+ self.align.push(self.base_align());
+ self.visit_node(value.syntax());
+ self.output.push('}');
+ }
+ }
+ }
+ bibtex::ENTRY => {
+ let entry = bibtex::Entry::cast(parent).unwrap();
+ self.visit_token_lowercase(entry.ty().unwrap());
+ self.output.push('{');
+ if let Some(key) = entry.key() {
+ self.output.push_str(key.text());
+ self.output.push(',');
+ self.output.push('\n');
+ for field in entry.fields() {
+ self.visit_node(field.syntax());
+ }
+ self.output.push('}');
+ }
+ }
+ bibtex::FIELD => {
+ let field = bibtex::Field::cast(parent).unwrap();
+ self.output.push_str(&self.indent);
+ let name = field.name().unwrap();
+ self.output.push_str(name.text());
+ self.output.push_str(" = ");
+ if let Some(value) = field.value() {
+ let count = name.text().chars().count();
+ self.align.push(self.tab_size as usize + count + 3);
+ self.visit_node(value.syntax());
+ self.output.push(',');
+ self.output.push('\n');
+ }
+ }
+ bibtex::VALUE => {
+ let tokens: Vec<_> = parent
+ .descendants_with_tokens()
+ .filter_map(|element| element.into_token())
+ .filter(|token| token.kind() != bibtex::WHITESPACE)
+ .collect();
+
+ self.output.push_str(tokens[0].text());
+
+ let align = self.align.pop().unwrap_or_default();
+ let mut length = align + tokens[0].text().chars().count();
+ for i in 1..tokens.len() {
+ let previous = tokens[i - 1];
+ let current = tokens[i];
+ let current_length = current.text().chars().count();
+
+ let insert_space = self.should_insert_space(previous, current);
+ let space_length = if insert_space { 1 } else { 0 };
+
+ if length + current_length + space_length > self.line_length {
+ self.output.push('\n');
+ self.output.push_str(self.indent.as_ref());
+ for _ in 0..=align - self.tab_size as usize {
+ self.output.push(' ');
+ }
+ length = align;
+ } else if insert_space {
+ self.output.push(' ');
+ length += 1;
+ }
+ self.output.push_str(current.text());
+ length += current_length;
+ }
+ }
+ bibtex::ROOT | bibtex::JUNK | bibtex::COMMENT => {
+ for element in parent.children_with_tokens() {
+ match element {
+ NodeOrToken::Token(token) => {
+ self.output.push_str(token.text());
+ }
+ NodeOrToken::Node(node) => {
+ self.visit_node(node);
+ }
+ }
+ }
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use insta::{assert_debug_snapshot, assert_display_snapshot};
+
+ use crate::features::testing::FeatureTester;
+
+ use super::*;
+
+ #[test]
+ fn test_wrap_long_lines() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ "@article{foo, bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.},}",
+ )])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_multiple_entries() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ "@article{foo, bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.},}\n\n@article{foo, bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.},}",
+ )])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let mut edits = format_bibtex_internal(&request, CancellationToken::none()).unwrap();
+ let edit2 = edits.pop().unwrap();
+ let edit1 = edits.pop().unwrap();
+
+ assert_debug_snapshot!((edit1.new_text, edit2.new_text));
+ }
+
+ #[test]
+ fn test_trailing_comma() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, bar = baz}")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_insert_braces() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, bar = baz,")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_command() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, bar = \"\\baz\",}")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_concatenation() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article{foo, bar = \"baz\" # \"qux\"}")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_parens() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@article(foo,)")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_string() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@string{foo=\"bar\"}")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+
+ #[test]
+ fn test_preamble() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "@preamble{\n\"foo bar baz\"}")])
+ .main("main.bib")
+ .build()
+ .formatting();
+
+ let edit = format_bibtex_internal(&request, CancellationToken::none())
+ .unwrap()
+ .pop()
+ .unwrap();
+
+ assert_display_snapshot!(edit.new_text);
+ }
+}
diff --git a/support/texlab/src/features/formatting/latexindent.rs b/support/texlab/src/features/formatting/latexindent.rs
new file mode 100644
index 0000000000..f603728a5d
--- /dev/null
+++ b/support/texlab/src/features/formatting/latexindent.rs
@@ -0,0 +1,50 @@
+use std::{
+ io::{BufWriter, Write},
+ process::{Command, Stdio},
+};
+
+use cancellation::CancellationToken;
+use cstree::{TextLen, TextRange};
+use lsp_types::{DocumentFormattingParams, TextEdit};
+
+use crate::{features::FeatureRequest, LineIndexExt};
+
+pub fn format_with_latexindent(
+ request: &FeatureRequest<DocumentFormattingParams>,
+ _cancellation_token: &CancellationToken,
+) -> Option<Vec<TextEdit>> {
+ let document = request.main_document();
+
+ let current_dir = &request.context.current_directory;
+ let options = request.context.options.read().unwrap();
+ let current_dir = match &options.root_directory {
+ Some(root_directory) => current_dir.join(root_directory),
+ None => current_dir.clone(),
+ };
+ drop(options);
+
+ let mut process = Command::new("latexindent")
+ .arg("-l")
+ .current_dir(current_dir)
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::null())
+ .spawn()
+ .ok()?;
+
+ let stdin = process.stdin.take()?;
+ let mut stdin = BufWriter::new(stdin);
+ stdin.write_all(document.text.as_bytes()).ok()?;
+ drop(stdin);
+
+ let output = process.wait_with_output().ok()?;
+
+ let new_text = String::from_utf8_lossy(&output.stdout).into_owned();
+
+ Some(vec![TextEdit {
+ range: document
+ .line_index
+ .line_col_lsp_range(TextRange::new(0.into(), document.text.text_len())),
+ new_text,
+ }])
+}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__command.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__command.snap
new file mode 100644
index 0000000000..792e7be277
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__command.snap
@@ -0,0 +1,8 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@article{foo,
+ bar = "\baz",
+}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__concatenation.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__concatenation.snap
new file mode 100644
index 0000000000..8cd51dfa92
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__concatenation.snap
@@ -0,0 +1,8 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@article{foo,
+ bar = "baz" # "qux",
+}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__insert_braces.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__insert_braces.snap
new file mode 100644
index 0000000000..3be9b15e9d
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__insert_braces.snap
@@ -0,0 +1,8 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@article{foo,
+ bar = baz,
+}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__multiple_entries.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__multiple_entries.snap
new file mode 100644
index 0000000000..636b4b665c
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__multiple_entries.snap
@@ -0,0 +1,9 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: "(edit1.new_text, edit2.new_text)"
+
+---
+(
+ "@article{foo,\n\tbar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum\n\t dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet,\n\t consectetur adipiscing elit.},\n}",
+ "@article{foo,\n\tbar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum\n\t dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet,\n\t consectetur adipiscing elit.},\n}",
+)
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__parens.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__parens.snap
new file mode 100644
index 0000000000..5aff28cb5f
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__parens.snap
@@ -0,0 +1,7 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@article{foo,
+}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__preamble.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__preamble.snap
new file mode 100644
index 0000000000..663569eb5b
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__preamble.snap
@@ -0,0 +1,6 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@preamble{"foo bar baz"}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__string.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__string.snap
new file mode 100644
index 0000000000..6d37a69e8e
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__string.snap
@@ -0,0 +1,6 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@string{foo = "bar"}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__trailing_comma.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__trailing_comma.snap
new file mode 100644
index 0000000000..3be9b15e9d
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__trailing_comma.snap
@@ -0,0 +1,8 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@article{foo,
+ bar = baz,
+}
diff --git a/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__wrap_long_lines.snap b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__wrap_long_lines.snap
new file mode 100644
index 0000000000..6c0ec724b5
--- /dev/null
+++ b/support/texlab/src/features/formatting/snapshots/texlab__features__formatting__bibtex_internal__tests__wrap_long_lines.snap
@@ -0,0 +1,10 @@
+---
+source: src/features/formatting/bibtex_internal.rs
+expression: edit.new_text
+
+---
+@article{foo,
+ bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum
+ dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit.},
+}
diff --git a/support/texlab/src/features/forward_search.rs b/support/texlab/src/features/forward_search.rs
new file mode 100644
index 0000000000..39470a64ec
--- /dev/null
+++ b/support/texlab/src/features/forward_search.rs
@@ -0,0 +1,124 @@
+use std::{
+ io,
+ path::Path,
+ process::{Command, Stdio},
+};
+
+use cancellation::CancellationToken;
+use log::error;
+use lsp_types::TextDocumentPositionParams;
+use serde::{Deserialize, Serialize};
+use serde_repr::{Deserialize_repr, Serialize_repr};
+
+use super::FeatureRequest;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize_repr, Deserialize_repr)]
+#[repr(i32)]
+pub enum ForwardSearchStatus {
+ Success = 0,
+ Error = 1,
+ Failure = 2,
+ Unconfigured = 3,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+pub struct ForwardSearchResult {
+ pub status: ForwardSearchStatus,
+}
+
+pub fn execute_forward_search(
+ request: FeatureRequest<TextDocumentPositionParams>,
+ _cancellation_token: &CancellationToken,
+) -> Option<ForwardSearchResult> {
+ let options = {
+ request
+ .context
+ .options
+ .read()
+ .unwrap()
+ .forward_search
+ .clone()
+ .unwrap_or_default()
+ };
+
+ if options.executable.is_none() || options.args.is_none() {
+ return Some(ForwardSearchResult {
+ status: ForwardSearchStatus::Unconfigured,
+ });
+ }
+
+ let root_document = request
+ .subset
+ .documents
+ .iter()
+ .find(|document| {
+ if let Some(data) = document.data.as_latex() {
+ data.extras.has_document_environment
+ && !data
+ .extras
+ .explicit_links
+ .iter()
+ .filter_map(|link| link.as_component_name())
+ .any(|name| name == "subfiles.cls")
+ } else {
+ false
+ }
+ })
+ .filter(|document| document.uri.scheme() == "file")?;
+
+ let data = root_document.data.as_latex()?;
+ let pdf_path = data
+ .extras
+ .implicit_links
+ .pdf
+ .iter()
+ .filter_map(|uri| uri.to_file_path().ok())
+ .find(|path| path.exists())?;
+
+ let tex_path = request.main_document().uri.to_file_path().ok()?;
+
+ let args: Vec<String> = options
+ .args
+ .unwrap()
+ .into_iter()
+ .flat_map(|arg| {
+ replace_placeholder(&tex_path, &pdf_path, request.params.position.line, arg)
+ })
+ .collect();
+
+ let status = match run_process(options.executable.unwrap(), args) {
+ Ok(()) => ForwardSearchStatus::Success,
+ Err(why) => {
+ error!("Unable to execute forward search: {}", why);
+ ForwardSearchStatus::Failure
+ }
+ };
+ Some(ForwardSearchResult { status })
+}
+
+fn replace_placeholder(
+ tex_file: &Path,
+ pdf_file: &Path,
+ line_number: u32,
+ argument: String,
+) -> Option<String> {
+ let result = if argument.starts_with('"') || argument.ends_with('"') {
+ argument
+ } else {
+ argument
+ .replace("%f", tex_file.to_str()?)
+ .replace("%p", pdf_file.to_str()?)
+ .replace("%l", &(line_number + 1).to_string())
+ };
+ Some(result)
+}
+
+fn run_process(executable: String, args: Vec<String>) -> io::Result<()> {
+ Command::new(executable)
+ .args(args)
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .status()?;
+ Ok(())
+}
diff --git a/support/texlab/src/features/highlight.rs b/support/texlab/src/features/highlight.rs
new file mode 100644
index 0000000000..e1aea6e2ad
--- /dev/null
+++ b/support/texlab/src/features/highlight.rs
@@ -0,0 +1,15 @@
+mod label;
+
+use cancellation::CancellationToken;
+use lsp_types::{DocumentHighlight, DocumentHighlightParams};
+
+use self::label::find_label_highlights;
+
+use super::FeatureRequest;
+
+pub fn find_document_highlights(
+ request: FeatureRequest<DocumentHighlightParams>,
+ token: &CancellationToken,
+) -> Option<Vec<DocumentHighlight>> {
+ find_label_highlights(&request, token)
+}
diff --git a/support/texlab/src/features/highlight/label.rs b/support/texlab/src/features/highlight/label.rs
new file mode 100644
index 0000000000..4c94180f2a
--- /dev/null
+++ b/support/texlab/src/features/highlight/label.rs
@@ -0,0 +1,167 @@
+use cancellation::CancellationToken;
+use lsp_types::{DocumentHighlight, DocumentHighlightKind, DocumentHighlightParams};
+
+use crate::{
+ features::FeatureRequest,
+ syntax::{latex, CstNode},
+ LineIndexExt,
+};
+
+pub fn find_label_highlights(
+ request: &FeatureRequest<DocumentHighlightParams>,
+ token: &CancellationToken,
+) -> Option<Vec<DocumentHighlight>> {
+ let main_document = request.main_document();
+
+ let offset = main_document
+ .line_index
+ .offset_lsp(request.params.text_document_position_params.position);
+
+ let data = main_document.data.as_latex()?;
+ let name = data.root.token_at_offset(offset).right_biased()?;
+ if name.kind() != latex::WORD {
+ return None;
+ }
+
+ if !matches!(
+ name.parent().parent()?.kind(),
+ latex::LABEL_DEFINITION | latex::LABEL_REFERENCE | latex::LABEL_REFERENCE_RANGE
+ ) {
+ return None;
+ }
+
+ let mut highlights = Vec::new();
+ for node in data.root.descendants() {
+ if token.is_canceled() {
+ return None;
+ }
+
+ if let Some(label_name) = latex::LabelDefinition::cast(node)
+ .and_then(|label| label.name())
+ .and_then(|label_name| label_name.word())
+ .filter(|label_name| label_name.text() == name.text())
+ {
+ let range = main_document
+ .line_index
+ .line_col_lsp_range(label_name.text_range());
+
+ highlights.push(DocumentHighlight {
+ range,
+ kind: Some(DocumentHighlightKind::Write),
+ });
+ } else if let Some(label) = latex::LabelReference::cast(node) {
+ for label_name in label
+ .name_list()
+ .into_iter()
+ .flat_map(|name| name.words())
+ .filter(|label_name| label_name.text() == name.text())
+ {
+ let range = main_document
+ .line_index
+ .line_col_lsp_range(label_name.text_range());
+
+ highlights.push(DocumentHighlight {
+ range,
+ kind: Some(DocumentHighlightKind::Read),
+ });
+ }
+ } else if let Some(label) = latex::LabelReferenceRange::cast(node) {
+ if let Some(label_name) = label
+ .from()
+ .and_then(|label_name| label_name.word())
+ .filter(|label_name| label_name.text() == name.text())
+ {
+ let range = main_document
+ .line_index
+ .line_col_lsp_range(label_name.text_range());
+
+ highlights.push(DocumentHighlight {
+ range,
+ kind: Some(DocumentHighlightKind::Read),
+ });
+ }
+
+ if let Some(label_name) = label
+ .to()
+ .and_then(|label_name| label_name.word())
+ .filter(|label_name| label_name.text() == name.text())
+ {
+ let range = main_document
+ .line_index
+ .line_col_lsp_range(label_name.text_range());
+
+ highlights.push(DocumentHighlight {
+ range,
+ kind: Some(DocumentHighlightKind::Read),
+ });
+ }
+ }
+ }
+
+ Some(highlights)
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .highlight();
+
+ let actual_links = find_label_highlights(&request, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .highlight();
+
+ let actual_links = find_label_highlights(&request, CancellationToken::none());
+
+ assert!(actual_links.is_none());
+ }
+
+ #[test]
+ fn test_label() {
+ let tester = FeatureTester::builder()
+ .files(vec![("main.tex", "\\label{foo}\n\\ref{foo}\\label{bar}")])
+ .main("main.tex")
+ .line(0)
+ .character(7)
+ .build();
+ let request = tester.highlight();
+
+ let actual_highlights = find_label_highlights(&request, CancellationToken::none()).unwrap();
+
+ let expected_highlights = vec![
+ DocumentHighlight {
+ range: Range::new_simple(0, 7, 0, 10),
+ kind: Some(DocumentHighlightKind::Write),
+ },
+ DocumentHighlight {
+ range: Range::new_simple(1, 5, 1, 8),
+ kind: Some(DocumentHighlightKind::Read),
+ },
+ ];
+
+ assert_eq!(actual_highlights, expected_highlights);
+ }
+}
diff --git a/support/texlab/src/features/hover.rs b/support/texlab/src/features/hover.rs
new file mode 100644
index 0000000000..a78978bc33
--- /dev/null
+++ b/support/texlab/src/features/hover.rs
@@ -0,0 +1,43 @@
+#[cfg(feature = "citeproc")]
+mod citation;
+mod component;
+mod entry_type;
+mod field;
+mod label;
+mod string_ref;
+
+use cancellation::CancellationToken;
+use cfg_if::cfg_if;
+use lsp_types::{Hover, HoverParams};
+
+use crate::features::cursor::CursorContext;
+
+use self::{
+ component::find_component_hover, entry_type::find_entry_type_hover, field::find_field_hover,
+ label::find_label_hover, string_ref::find_string_reference_hover,
+};
+
+use super::FeatureRequest;
+
+pub fn find_hover(
+ request: FeatureRequest<HoverParams>,
+ cabcellation_token: &CancellationToken,
+) -> Option<Hover> {
+ let context = CursorContext::new(request);
+ log::debug!("[Hover] Cursor: {:?}", context.cursor);
+ let mut hover = find_label_hover(&context, cabcellation_token);
+
+ cfg_if! {
+ if #[cfg(feature = "citation")] {
+ hover = hover.or_else(|| self::citation::find_citation_hover(&context, cabcellation_token));
+ }
+ }
+
+ hover = hover
+ .or_else(|| find_component_hover(&context, cabcellation_token))
+ .or_else(|| find_string_reference_hover(&context, cabcellation_token))
+ .or_else(|| find_field_hover(&context, cabcellation_token))
+ .or_else(|| find_entry_type_hover(&context, cabcellation_token));
+
+ hover
+}
diff --git a/support/texlab/src/features/hover/citation.rs b/support/texlab/src/features/hover/citation.rs
new file mode 100644
index 0000000000..1fd6d6c06b
--- /dev/null
+++ b/support/texlab/src/features/hover/citation.rs
@@ -0,0 +1,133 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams};
+
+use crate::{citation, features::cursor::CursorContext, LineIndexExt};
+
+pub fn find_citation_hover(
+ context: &CursorContext<HoverParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Hover> {
+ cancellation_token.result().ok()?;
+ let main_document = context.request.main_document();
+
+ let (key_text, key_range) = context
+ .find_citation_key_word()
+ .or_else(|| context.find_citation_key_command())
+ .or_else(|| context.find_entry_key())?;
+
+ let contents = context
+ .request
+ .subset
+ .documents
+ .iter()
+ .find_map(|document| {
+ document
+ .data
+ .as_bibtex()
+ .and_then(|data| citation::render_citation(&data.root, &key_text))
+ })?;
+
+ Some(Hover {
+ range: Some(main_document.line_index.line_col_lsp_range(key_range)),
+ contents: HoverContents::Markup(contents),
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::{MarkupContent, MarkupKind, Range};
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_inside_cite() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ (
+ "main.bib",
+ "@article{foo, author = {Foo Bar}, title = {Baz Qux}, year = 1337}",
+ ),
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(7)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none()).unwrap();
+
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: "Bar, F. (1337). *Baz Qux*.".into(),
+ }),
+ range: Some(Range::new_simple(1, 6, 1, 9)),
+ };
+ assert_eq!(actual_hover, expected_hover);
+ }
+
+ #[test]
+ fn test_inside_entry() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ (
+ "main.bib",
+ "@article{foo, author = {Foo Bar}, title = {Baz Qux}, year = 1337}",
+ ),
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ])
+ .main("main.bib")
+ .line(0)
+ .character(11)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none()).unwrap();
+
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: "Bar, F. (1337). *Baz Qux*.".into(),
+ }),
+ range: Some(Range::new_simple(0, 9, 0, 12)),
+ };
+ assert_eq!(actual_hover, expected_hover);
+ }
+}
diff --git a/support/texlab/src/features/hover/component.rs b/support/texlab/src/features/hover/component.rs
new file mode 100644
index 0000000000..abfdb781f1
--- /dev/null
+++ b/support/texlab/src/features/hover/component.rs
@@ -0,0 +1,105 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams};
+
+use crate::{
+ component_db::COMPONENT_DATABASE, features::cursor::CursorContext, syntax::latex, LineIndexExt,
+};
+
+pub fn find_component_hover(
+ context: &CursorContext<HoverParams>,
+ token: &CancellationToken,
+) -> Option<Hover> {
+ let main_document = context.request.main_document();
+ let data = main_document.data.as_latex()?;
+ for link in &data.extras.explicit_links {
+ if token.is_canceled() {
+ break;
+ }
+
+ if matches!(
+ link.kind,
+ latex::ExplicitLinkKind::Package | latex::ExplicitLinkKind::Class
+ ) && link.stem_range.contains_inclusive(context.offset)
+ {
+ let docs = COMPONENT_DATABASE.documentation(&link.stem)?;
+ return Some(Hover {
+ contents: HoverContents::Markup(docs),
+ range: Some(main_document.line_index.line_col_lsp_range(link.stem_range)),
+ });
+ }
+ }
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_component_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_component_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_known_package() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", r#"\usepackage{amsmath}"#)])
+ .main("main.tex")
+ .line(0)
+ .character(15)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_component_hover(&context, CancellationToken::none()).unwrap();
+
+ assert_eq!(actual_hover.range.unwrap(), Range::new_simple(0, 12, 0, 19));
+ }
+
+ #[test]
+ fn test_unknown_class() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", r#"\documentclass{abcdefghijklmnop}"#)])
+ .main("main.tex")
+ .line(0)
+ .character(20)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_component_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+}
diff --git a/support/texlab/src/features/hover/entry_type.rs b/support/texlab/src/features/hover/entry_type.rs
new file mode 100644
index 0000000000..e480b2f835
--- /dev/null
+++ b/support/texlab/src/features/hover/entry_type.rs
@@ -0,0 +1,128 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams, MarkupContent};
+
+use crate::{features::cursor::CursorContext, LineIndexExt, LANGUAGE_DATA};
+
+pub fn find_entry_type_hover(
+ context: &CursorContext<HoverParams>,
+ _token: &CancellationToken,
+) -> Option<Hover> {
+ let name = context
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind().is_type())?;
+
+ let docs = LANGUAGE_DATA.entry_type_documentation(&name.text()[1..])?;
+ Some(Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: lsp_types::MarkupKind::Markdown,
+ value: docs.to_string(),
+ }),
+ range: Some(
+ context
+ .request
+ .main_document()
+ .line_index
+ .line_col_lsp_range(name.text_range()),
+ ),
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::{MarkupKind, Range};
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_entry_type_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_entry_type_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_known_entry_type() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", r#"@article{foo,}"#)])
+ .main("main.bib")
+ .line(0)
+ .character(3)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_entry_type_hover(&context, CancellationToken::none()).unwrap();
+
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: LANGUAGE_DATA
+ .entry_type_documentation("article")
+ .unwrap()
+ .into(),
+ }),
+ range: Some(Range::new_simple(0, 0, 0, 8)),
+ };
+ assert_eq!(actual_hover, expected_hover);
+ }
+
+ #[test]
+ fn test_unknown_field() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", r#"@foo{bar,}"#)])
+ .main("main.bib")
+ .line(0)
+ .character(3)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_entry_type_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_entry_key() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", r#"@article{foo,}"#)])
+ .main("main.bib")
+ .line(0)
+ .character(11)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_entry_type_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+}
diff --git a/support/texlab/src/features/hover/field.rs b/support/texlab/src/features/hover/field.rs
new file mode 100644
index 0000000000..54a8718d69
--- /dev/null
+++ b/support/texlab/src/features/hover/field.rs
@@ -0,0 +1,128 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams, MarkupContent};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, CstNode},
+ LineIndexExt, LANGUAGE_DATA,
+};
+
+pub fn find_field_hover(
+ context: &CursorContext<HoverParams>,
+ _token: &CancellationToken,
+) -> Option<Hover> {
+ let main_document = context.request.main_document();
+
+ let name = context
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind() == bibtex::WORD)?;
+
+ bibtex::Field::cast(name.parent())?;
+
+ let docs = LANGUAGE_DATA.field_documentation(&name.text())?;
+ Some(Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: lsp_types::MarkupKind::Markdown,
+ value: docs.to_string(),
+ }),
+ range: Some(
+ main_document
+ .line_index
+ .line_col_lsp_range(name.text_range()),
+ ),
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::{MarkupKind, Range};
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_field_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_field_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_known_field() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", r#"@article{foo, author = bar}"#)])
+ .main("main.bib")
+ .line(0)
+ .character(15)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_field_hover(&context, CancellationToken::none()).unwrap();
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: LANGUAGE_DATA.field_documentation("author").unwrap().into(),
+ }),
+ range: Some(Range::new_simple(0, 14, 0, 20)),
+ };
+ assert_eq!(actual_hover, expected_hover);
+ }
+
+ #[test]
+ fn test_unknown_field() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", r#"@article{foo, bar = baz}"#)])
+ .main("main.bib")
+ .line(0)
+ .character(15)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_field_hover(&context, CancellationToken::none());
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_entry_key() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", r#"@article{foo, author = bar}"#)])
+ .main("main.bib")
+ .line(0)
+ .character(11)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_field_hover(&context, CancellationToken::none());
+ assert_eq!(actual_hover, None);
+ }
+}
diff --git a/support/texlab/src/features/hover/label.rs b/support/texlab/src/features/hover/label.rs
new file mode 100644
index 0000000000..79afe7d250
--- /dev/null
+++ b/support/texlab/src/features/hover/label.rs
@@ -0,0 +1,79 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams};
+
+use crate::{features::cursor::CursorContext, render_label, LineIndexExt};
+
+pub fn find_label_hover(
+ context: &CursorContext<HoverParams>,
+ _token: &CancellationToken,
+) -> Option<Hover> {
+ let main_document = context.request.main_document();
+
+ let (name_text, name_range) = context
+ .find_label_name_word()
+ .or_else(|| context.find_label_name_command())?;
+
+ let label = render_label(&context.request.subset, name_text, None)?;
+
+ Some(Hover {
+ range: Some(main_document.line_index.line_col_lsp_range(name_range)),
+ contents: HoverContents::Markup(label.documentation()),
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_label_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_label_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_section() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", r#"\section{Foo}\label{sec:foo}"#)])
+ .main("main.tex")
+ .line(0)
+ .character(23)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_label_hover(&context, CancellationToken::none()).unwrap();
+
+ assert_eq!(actual_hover.range.unwrap(), Range::new_simple(0, 20, 0, 27));
+ }
+}
diff --git a/support/texlab/src/features/hover/string_ref.rs b/support/texlab/src/features/hover/string_ref.rs
new file mode 100644
index 0000000000..f6e7f1c873
--- /dev/null
+++ b/support/texlab/src/features/hover/string_ref.rs
@@ -0,0 +1,141 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams, MarkupContent, MarkupKind};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, CstNode},
+ LineIndexExt,
+};
+
+pub fn find_string_reference_hover(
+ context: &CursorContext<HoverParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Hover> {
+ let main_document = context.request.main_document();
+ let data = main_document.data.as_bibtex()?;
+
+ let name = context
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind() == bibtex::WORD)
+ .filter(|name| matches!(name.parent().kind(), bibtex::TOKEN | bibtex::STRING))?;
+
+ for string in data.root.children().filter_map(bibtex::String::cast) {
+ if cancellation_token.is_canceled() {
+ return None;
+ }
+
+ if string.name().filter(|n| n.text() == name.text()).is_some() {
+ let value = string.value()?.syntax().text().to_string();
+ return Some(Hover {
+ range: Some(
+ main_document
+ .line_index
+ .line_col_lsp_range(name.text_range()),
+ ),
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::PlainText,
+ value,
+ }),
+ });
+ }
+ }
+
+ None
+}
+
+#[cfg(test)]
+mod tests {
+ use indoc::indoc;
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_string_reference_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_string_reference_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_inside_reference() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! { r#"
+ @string{foo = "Foo"}
+ @string{bar = "Bar"}
+ @article{baz, author = bar}
+ "# },
+ )])
+ .main("main.bib")
+ .line(2)
+ .character(24)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover =
+ find_string_reference_hover(&context, CancellationToken::none()).unwrap();
+
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::PlainText,
+ value: "\"Bar\"".into(),
+ }),
+ range: Some(Range::new_simple(2, 23, 2, 26)),
+ };
+
+ assert_eq!(actual_hover, expected_hover);
+ }
+
+ #[test]
+ fn test_inside_field() {
+ let request = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! { r#"
+ @string{foo = "Foo"}
+ @string{bar = "Bar"}
+ @article{baz, author = bar}
+ "# },
+ )])
+ .main("main.bib")
+ .line(2)
+ .character(20)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_string_reference_hover(&context, CancellationToken::none());
+ assert_eq!(actual_hover, None);
+ }
+}
diff --git a/support/texlab/src/features/link.rs b/support/texlab/src/features/link.rs
new file mode 100644
index 0000000000..a6016c9f76
--- /dev/null
+++ b/support/texlab/src/features/link.rs
@@ -0,0 +1,115 @@
+use cancellation::CancellationToken;
+use lsp_types::{DocumentLink, DocumentLinkParams};
+
+use crate::LineIndexExt;
+
+use super::FeatureRequest;
+
+pub fn find_document_links(
+ request: FeatureRequest<DocumentLinkParams>,
+ cancellation_token: &CancellationToken,
+) -> Vec<DocumentLink> {
+ let mut links = Vec::new();
+ let main_document = request.main_document();
+ if let Some(data) = main_document.data.as_latex() {
+ for include in &data.extras.explicit_links {
+ for target in &include.targets {
+ if cancellation_token.is_canceled() {
+ return links;
+ }
+
+ if request
+ .subset
+ .documents
+ .iter()
+ .any(|document| document.uri.as_ref() == target.as_ref())
+ {
+ links.push(DocumentLink {
+ range: main_document
+ .line_index
+ .line_col_lsp_range(include.stem_range),
+ target: Some(target.as_ref().clone().into()),
+ tooltip: None,
+ data: None,
+ });
+ break;
+ }
+ }
+ }
+ }
+ links
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .build()
+ .link();
+
+ let items = find_document_links(request, CancellationToken::none());
+ assert!(items.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .build()
+ .link();
+
+ let items = find_document_links(request, CancellationToken::none());
+ assert!(items.is_empty());
+ }
+
+ #[test]
+ fn test_includes() {
+ let tester = FeatureTester::builder()
+ .files(vec![("foo.tex", r#"\input{bar.tex}"#), ("bar.tex", r#""#)])
+ .main("foo.tex")
+ .build();
+ let target = tester.uri("bar.tex");
+
+ let actual_items = find_document_links(tester.link(), CancellationToken::none());
+
+ let expected_items = vec![DocumentLink {
+ range: Range::new_simple(0, 7, 0, 14),
+ target: Some(target.as_ref().clone().into()),
+ tooltip: None,
+ data: None,
+ }];
+ assert_eq!(actual_items, expected_items);
+ }
+
+ #[test]
+ fn test_imports() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\import{bar/}{baz}"#),
+ ("bar/baz.tex", r#""#),
+ ])
+ .main("foo.tex")
+ .build();
+ let target = tester.uri("bar/baz.tex");
+
+ let actual_items = find_document_links(tester.link(), CancellationToken::none());
+
+ let expected_items = vec![DocumentLink {
+ range: Range::new_simple(0, 14, 0, 17),
+ target: Some(target.as_ref().clone().into()),
+ tooltip: None,
+ data: None,
+ }];
+ assert_eq!(actual_items, expected_items);
+ }
+}
diff --git a/support/texlab/src/syntax/lsp_kind.rs b/support/texlab/src/features/lsp_kinds.rs
index 7d92fd4ee4..fbfc50cace 100644
--- a/support/texlab/src/syntax/lsp_kind.rs
+++ b/support/texlab/src/features/lsp_kinds.rs
@@ -1,5 +1,6 @@
-use super::lang_data::BibtexEntryTypeCategory;
-use crate::protocol::{CompletionItemKind, SymbolKind};
+use lsp_types::{CompletionItemKind, SymbolKind};
+
+use crate::BibtexEntryTypeCategory;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Structure {
diff --git a/support/texlab/src/features/reference.rs b/support/texlab/src/features/reference.rs
new file mode 100644
index 0000000000..14cf3bc297
--- /dev/null
+++ b/support/texlab/src/features/reference.rs
@@ -0,0 +1,25 @@
+mod entry;
+mod label;
+mod string;
+
+use cancellation::CancellationToken;
+use lsp_types::{Location, ReferenceParams};
+
+use self::{
+ entry::find_entry_references, label::find_label_references, string::find_string_references,
+};
+
+use super::{cursor::CursorContext, FeatureRequest};
+
+pub fn find_all_references(
+ request: FeatureRequest<ReferenceParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Vec<Location>> {
+ let mut references = Vec::new();
+ let context = CursorContext::new(request);
+ log::debug!("[References] Cursor: {:?}", context.cursor);
+ find_label_references(&context, cancellation_token, &mut references);
+ find_entry_references(&context, cancellation_token, &mut references);
+ find_string_references(&context, cancellation_token, &mut references);
+ Some(references)
+}
diff --git a/support/texlab/src/features/reference/entry.rs b/support/texlab/src/features/reference/entry.rs
new file mode 100644
index 0000000000..fbbcbdb4cc
--- /dev/null
+++ b/support/texlab/src/features/reference/entry.rs
@@ -0,0 +1,198 @@
+use cancellation::CancellationToken;
+use lsp_types::{Location, ReferenceParams};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, latex, CstNode},
+ DocumentData, LineIndexExt,
+};
+
+pub fn find_entry_references(
+ context: &CursorContext<ReferenceParams>,
+ cancellation_token: &CancellationToken,
+ references: &mut Vec<Location>,
+) -> Option<()> {
+ let (key_text, _) = context
+ .find_citation_key_word()
+ .or_else(|| context.find_citation_key_command())
+ .or_else(|| context.find_entry_key())?;
+
+ for document in &context.request.subset.documents {
+ cancellation_token.result().ok()?;
+
+ match &document.data {
+ DocumentData::Latex(data) => {
+ data.root
+ .descendants()
+ .filter_map(latex::Citation::cast)
+ .filter_map(|citation| citation.key_list())
+ .flat_map(|keys| keys.words())
+ .filter(|key| key.text() == key_text)
+ .map(|key| document.line_index.line_col_lsp_range(key.text_range()))
+ .for_each(|range| {
+ references.push(Location::new(document.uri.as_ref().clone().into(), range));
+ });
+ }
+ DocumentData::Bibtex(data) if context.request.params.context.include_declaration => {
+ data.root
+ .children()
+ .filter_map(bibtex::Entry::cast)
+ .filter_map(|entry| entry.key())
+ .filter(|key| key.text() == key_text)
+ .map(|key| document.line_index.line_col_lsp_range(key.text_range()))
+ .for_each(|range| {
+ references.push(Location::new(document.uri.as_ref().clone().into(), range));
+ });
+ }
+ DocumentData::Bibtex(_) | DocumentData::BuildLog(_) => {}
+ }
+ }
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .reference();
+
+ let mut actual_references = Vec::new();
+ let context = CursorContext::new(request);
+ find_entry_references(&context, CancellationToken::none(), &mut actual_references);
+
+ assert!(actual_references.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .reference();
+
+ let mut actual_references = Vec::new();
+ let context = CursorContext::new(request);
+ find_entry_references(&context, CancellationToken::none(), &mut actual_references);
+
+ assert!(actual_references.is_empty());
+ }
+
+ #[test]
+ fn test_definition() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.bib", r#"@article{foo,}"#),
+ ("bar.tex", r#"\cite{foo}\addbibresource{foo.bib}"#),
+ ])
+ .main("foo.bib")
+ .line(0)
+ .character(11)
+ .build();
+ let uri = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_entry_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![Location::new(
+ uri.as_ref().clone().into(),
+ Range::new_simple(0, 6, 0, 9),
+ )];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_definition_include_declaration() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.bib", r#"@article{foo,}"#),
+ ("bar.tex", r#"\cite{foo}\addbibresource{foo.bib}"#),
+ ])
+ .main("foo.bib")
+ .line(0)
+ .character(11)
+ .include_declaration(true)
+ .build();
+ let uri1 = tester.uri("foo.bib");
+ let uri2 = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_entry_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 9, 0, 12)),
+ Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 6, 0, 9)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_reference() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.bib", r#"@article{foo,}"#),
+ ("bar.tex", r#"\cite{foo}\addbibresource{foo.bib}"#),
+ ])
+ .main("bar.tex")
+ .line(0)
+ .character(8)
+ .build();
+ let uri = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_entry_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![Location::new(
+ uri.as_ref().clone().into(),
+ Range::new_simple(0, 6, 0, 9),
+ )];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_reference_include_declaration() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.bib", r#"@article{foo,}"#),
+ ("bar.tex", r#"\cite{foo}\addbibresource{foo.bib}"#),
+ ])
+ .main("bar.tex")
+ .line(0)
+ .character(6)
+ .include_declaration(true)
+ .build();
+ let uri1 = tester.uri("foo.bib");
+ let uri2 = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_entry_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 6, 0, 9)),
+ Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 9, 0, 12)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+}
diff --git a/support/texlab/src/features/reference/label.rs b/support/texlab/src/features/reference/label.rs
new file mode 100644
index 0000000000..e9aa3a8510
--- /dev/null
+++ b/support/texlab/src/features/reference/label.rs
@@ -0,0 +1,187 @@
+use cancellation::CancellationToken;
+use lsp_types::{Location, ReferenceParams};
+
+use crate::{features::cursor::CursorContext, LineIndexExt};
+
+pub fn find_label_references(
+ context: &CursorContext<ReferenceParams>,
+ cancellation_token: &CancellationToken,
+ references: &mut Vec<Location>,
+) -> Option<()> {
+ cancellation_token.result().ok()?;
+
+ let (name_text, _) = context
+ .find_label_name_word()
+ .or_else(|| context.find_label_name_command())?;
+
+ for document in &context.request.subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ cancellation_token.result().ok()?;
+ for name in data
+ .extras
+ .label_names
+ .iter()
+ .filter(|name| name.text == name_text)
+ .filter(|name| {
+ !name.is_definition || context.request.params.context.include_declaration
+ })
+ {
+ references.push(Location::new(
+ document.uri.as_ref().clone().into(),
+ document.line_index.line_col_lsp_range(name.range),
+ ));
+ }
+ }
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_definition() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\label{foo}"#),
+ ("bar.tex", r#"\ref{foo}\input{foo.tex}"#),
+ ])
+ .main("foo.tex")
+ .line(0)
+ .character(8)
+ .build();
+ let uri = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_label_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![Location::new(
+ uri.as_ref().clone().into(),
+ Range::new_simple(0, 5, 0, 8),
+ )];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_definition_include_declaration() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\label{foo}\input{bar.tex}"#),
+ ("bar.tex", r#"\ref{foo}"#),
+ ])
+ .main("foo.tex")
+ .line(0)
+ .character(9)
+ .include_declaration(true)
+ .build();
+ let uri1 = tester.uri("foo.tex");
+ let uri2 = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_label_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 7, 0, 10)),
+ Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_reference() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\label{foo}\input{bar.tex}"#),
+ ("bar.tex", r#"\ref{foo}"#),
+ ("baz.tex", r#"\ref{foo}\input{bar.tex}"#),
+ ])
+ .main("bar.tex")
+ .line(0)
+ .character(7)
+ .build();
+ let uri1 = tester.uri("bar.tex");
+ let uri2 = tester.uri("baz.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_label_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)),
+ Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_reference_include_declaration() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\label{foo}"#),
+ ("bar.tex", r#"\ref{foo}\input{foo.tex}"#),
+ ])
+ .main("bar.tex")
+ .line(0)
+ .character(7)
+ .include_declaration(true)
+ .build();
+ let uri1 = tester.uri("foo.tex");
+ let uri2 = tester.uri("bar.tex");
+ let mut actual_references = Vec::new();
+
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_label_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)),
+ Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 7, 0, 10)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .reference();
+ let mut actual_references = Vec::new();
+
+ let context = CursorContext::new(request);
+ find_label_references(&context, CancellationToken::none(), &mut actual_references);
+
+ assert!(actual_references.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .reference();
+ let mut actual_references = Vec::new();
+
+ let context = CursorContext::new(request);
+ find_label_references(&context, CancellationToken::none(), &mut actual_references);
+
+ assert!(actual_references.is_empty());
+ }
+}
diff --git a/support/texlab/src/features/reference/string.rs b/support/texlab/src/features/reference/string.rs
new file mode 100644
index 0000000000..b7dd4e039a
--- /dev/null
+++ b/support/texlab/src/features/reference/string.rs
@@ -0,0 +1,206 @@
+use cancellation::CancellationToken;
+use lsp_types::{Location, ReferenceParams};
+
+use crate::{
+ features::cursor::CursorContext,
+ syntax::{bibtex, CstNode},
+ LineIndexExt,
+};
+
+pub fn find_string_references(
+ context: &CursorContext<ReferenceParams>,
+ cancellation_token: &CancellationToken,
+ items: &mut Vec<Location>,
+) -> Option<()> {
+ let name_text = context
+ .cursor
+ .as_bibtex()
+ .filter(|token| token.kind() == bibtex::WORD)
+ .filter(|token| matches!(token.parent().kind(), bibtex::TOKEN | bibtex::STRING))?
+ .text();
+
+ let document = context.request.main_document();
+ let data = document.data.as_bibtex()?;
+ for node in data.root.descendants() {
+ cancellation_token.result().ok()?;
+ if let Some(name) = bibtex::String::cast(node)
+ .and_then(|string| string.name())
+ .filter(|name| {
+ context.request.params.context.include_declaration && name.text() == name_text
+ })
+ .or_else(|| {
+ bibtex::Token::cast(node)
+ .and_then(|token| token.syntax().first_token())
+ .filter(|name| name.text() == name_text)
+ })
+ {
+ items.push(Location::new(
+ document.uri.as_ref().clone().into(),
+ document.line_index.line_col_lsp_range(name.text_range()),
+ ));
+ }
+ }
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use indoc::indoc;
+ use lsp_types::Range;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_definition() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! { r#"
+ @string{foo = {Foo}}
+ @string{bar = {Bar}}
+ @article{baz, author = foo}
+ "# },
+ )])
+ .main("main.bib")
+ .line(2)
+ .character(24)
+ .build();
+ let uri = tester.uri("main.bib");
+
+ let mut actual_references = Vec::new();
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_string_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![Location::new(
+ uri.as_ref().clone().into(),
+ Range::new_simple(2, 23, 2, 26),
+ )];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_definition_include_declaration() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! { r#"
+ @string{foo = {Foo}}
+ @string{bar = {Bar}}
+ @article{baz, author = foo}
+ "# },
+ )])
+ .main("main.bib")
+ .line(2)
+ .character(24)
+ .include_declaration(true)
+ .build();
+ let uri = tester.uri("main.bib");
+
+ let mut actual_references = Vec::new();
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_string_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri.as_ref().clone().into(), Range::new_simple(0, 8, 0, 11)),
+ Location::new(uri.as_ref().clone().into(), Range::new_simple(2, 23, 2, 26)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_reference() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! { r#"
+ @string{foo = {Foo}}
+ @string{bar = {Bar}}
+ @article{baz, author = foo}
+ "# },
+ )])
+ .main("main.bib")
+ .line(0)
+ .character(10)
+ .build();
+ let uri = tester.uri("main.bib");
+
+ let mut actual_references = Vec::new();
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_string_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![Location::new(
+ uri.as_ref().clone().into(),
+ Range::new_simple(2, 23, 2, 26),
+ )];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_reference_include_declaration() {
+ let tester = FeatureTester::builder()
+ .files(vec![(
+ "main.bib",
+ indoc! { r#"
+ @string{foo = {Foo}}
+ @string{bar = {Bar}}
+ @article{baz, author = foo}
+ "# },
+ )])
+ .main("main.bib")
+ .line(0)
+ .character(10)
+ .include_declaration(true)
+ .build();
+ let uri = tester.uri("main.bib");
+
+ let mut actual_references = Vec::new();
+ let request = tester.reference();
+ let context = CursorContext::new(request);
+ find_string_references(&context, CancellationToken::none(), &mut actual_references);
+
+ let expected_references = vec![
+ Location::new(uri.as_ref().clone().into(), Range::new_simple(0, 8, 0, 11)),
+ Location::new(uri.as_ref().clone().into(), Range::new_simple(2, 23, 2, 26)),
+ ];
+ assert_eq!(actual_references, expected_references);
+ }
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .reference();
+
+ let mut actual_references = Vec::new();
+ let context = CursorContext::new(request);
+ find_string_references(&context, CancellationToken::none(), &mut actual_references);
+
+ assert!(actual_references.is_empty());
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .reference();
+
+ let mut actual_references = Vec::new();
+ let context = CursorContext::new(request);
+ find_string_references(&context, CancellationToken::none(), &mut actual_references);
+
+ assert!(actual_references.is_empty());
+ }
+}
diff --git a/support/texlab/src/features/rename.rs b/support/texlab/src/features/rename.rs
new file mode 100644
index 0000000000..ba09fa268c
--- /dev/null
+++ b/support/texlab/src/features/rename.rs
@@ -0,0 +1,34 @@
+mod command;
+mod entry;
+mod label;
+
+use cancellation::CancellationToken;
+use lsp_types::{Range, RenameParams, TextDocumentPositionParams, WorkspaceEdit};
+
+use self::{
+ command::{prepare_command_rename, rename_command},
+ entry::{prepare_entry_rename, rename_entry},
+ label::{prepare_label_rename, rename_label},
+};
+
+use super::{cursor::CursorContext, FeatureRequest};
+
+pub fn prepare_rename_all(
+ request: FeatureRequest<TextDocumentPositionParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Range> {
+ let context = CursorContext::new(request);
+ prepare_entry_rename(&context, cancellation_token)
+ .or_else(|| prepare_label_rename(&context, cancellation_token))
+ .or_else(|| prepare_command_rename(&context, cancellation_token))
+}
+
+pub fn rename_all(
+ request: FeatureRequest<RenameParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<WorkspaceEdit> {
+ let context = CursorContext::new(request);
+ rename_entry(&context, cancellation_token)
+ .or_else(|| rename_label(&context, cancellation_token))
+ .or_else(|| rename_command(&context, cancellation_token))
+}
diff --git a/support/texlab/src/features/rename/command.rs b/support/texlab/src/features/rename/command.rs
new file mode 100644
index 0000000000..402783f3ae
--- /dev/null
+++ b/support/texlab/src/features/rename/command.rs
@@ -0,0 +1,98 @@
+use std::collections::HashMap;
+
+use cancellation::CancellationToken;
+use cstree::{TextRange, TextSize};
+use lsp_types::{Range, RenameParams, TextEdit, WorkspaceEdit};
+
+use crate::{
+ features::cursor::{CursorContext, HasPosition},
+ LineIndexExt,
+};
+
+pub fn prepare_command_rename<P: HasPosition>(
+ context: &CursorContext<P>,
+ _cancellation_token: &CancellationToken,
+) -> Option<Range> {
+ Some(
+ context
+ .request
+ .main_document()
+ .line_index
+ .line_col_lsp_range(context.cursor.command_range(context.offset)?),
+ )
+}
+
+pub fn rename_command(
+ context: &CursorContext<RenameParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<WorkspaceEdit> {
+ cancellation_token.result().ok()?;
+ prepare_command_rename(context, cancellation_token)?;
+ let name = context.cursor.as_latex()?.text();
+ let mut changes = HashMap::new();
+ for document in &context.request.subset.documents {
+ cancellation_token.result().ok()?;
+
+ if let Some(data) = document.data.as_latex() {
+ let edits = data
+ .root
+ .descendants_with_tokens()
+ .filter_map(|element| element.into_token())
+ .filter(|token| token.kind().is_command_name() && token.text() == name)
+ .map(|token| {
+ let range = token.text_range();
+ let range = document.line_index.line_col_lsp_range(TextRange::new(
+ range.start() + TextSize::from(1),
+ range.end(),
+ ));
+ TextEdit::new(range, context.request.params.new_name.clone())
+ })
+ .collect();
+
+ changes.insert(document.uri.as_ref().clone().into(), edits);
+ }
+ }
+
+ Some(WorkspaceEdit::new(changes))
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_command() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\baz\include{bar.tex}"#),
+ ("bar.tex", r#"\baz"#),
+ ])
+ .main("foo.tex")
+ .line(0)
+ .character(2)
+ .new_name("qux")
+ .build();
+
+ let uri1 = tester.uri("foo.tex");
+ let uri2 = tester.uri("bar.tex");
+ let req = tester.rename();
+
+ let context = CursorContext::new(req);
+ let actual_edit = rename_command(&context, CancellationToken::none()).unwrap();
+
+ let mut expected_changes = HashMap::new();
+ expected_changes.insert(
+ uri1.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(0, 1, 0, 4), "qux".into())],
+ );
+ expected_changes.insert(
+ uri2.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(0, 1, 0, 4), "qux".into())],
+ );
+ let expected_edit = WorkspaceEdit::new(expected_changes);
+
+ assert_eq!(actual_edit, expected_edit);
+ }
+}
diff --git a/support/texlab/src/features/rename/entry.rs b/support/texlab/src/features/rename/entry.rs
new file mode 100644
index 0000000000..14fbfd42d7
--- /dev/null
+++ b/support/texlab/src/features/rename/entry.rs
@@ -0,0 +1,161 @@
+use std::collections::HashMap;
+
+use cancellation::CancellationToken;
+use lsp_types::{Range, RenameParams, TextEdit, WorkspaceEdit};
+
+use crate::{
+ features::cursor::{Cursor, CursorContext, HasPosition},
+ syntax::{bibtex, latex, CstNode},
+ DocumentData, LineIndexExt,
+};
+
+pub fn prepare_entry_rename<P: HasPosition>(
+ context: &CursorContext<P>,
+ _cancellation_token: &CancellationToken,
+) -> Option<Range> {
+ let range = match &context.cursor {
+ Cursor::Latex(token) if token.kind() == latex::WORD => {
+ let group = latex::CurlyGroupWordList::cast(token.parent())?;
+ latex::Citation::cast(group.syntax().parent()?)?;
+ token.text_range()
+ }
+ Cursor::Bibtex(token) if token.kind() == bibtex::WORD => {
+ bibtex::Entry::cast(token.parent())?;
+ token.text_range()
+ }
+ _ => return None,
+ };
+
+ Some(
+ context
+ .request
+ .main_document()
+ .line_index
+ .line_col_lsp_range(range),
+ )
+}
+
+pub fn rename_entry(
+ context: &CursorContext<RenameParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<WorkspaceEdit> {
+ cancellation_token.result().ok()?;
+ prepare_entry_rename(context, cancellation_token)?;
+ let key_text = context
+ .cursor
+ .as_latex()
+ .map(|token| token.text())
+ .or_else(|| context.cursor.as_bibtex().map(|token| token.text()))?;
+
+ let mut changes = HashMap::new();
+ for document in &context.request.subset.documents {
+ cancellation_token.result().ok()?;
+ match &document.data {
+ DocumentData::Latex(data) => {
+ let edits: Vec<_> = data
+ .root
+ .descendants()
+ .filter_map(latex::Citation::cast)
+ .filter_map(|citation| citation.key_list())
+ .flat_map(|keys| keys.words())
+ .filter(|key| key.text() == key_text)
+ .map(|key| document.line_index.line_col_lsp_range(key.text_range()))
+ .map(|range| TextEdit::new(range, context.request.params.new_name.clone()))
+ .collect();
+ changes.insert(document.uri.as_ref().clone().into(), edits);
+ }
+ DocumentData::Bibtex(data) => {
+ let edits: Vec<_> = data
+ .root
+ .descendants()
+ .filter_map(bibtex::Entry::cast)
+ .filter_map(|entry| entry.key())
+ .filter(|key| key.text() == key_text)
+ .map(|key| document.line_index.line_col_lsp_range(key.text_range()))
+ .map(|range| TextEdit::new(range, context.request.params.new_name.clone()))
+ .collect();
+ changes.insert(document.uri.as_ref().clone().into(), edits);
+ }
+ DocumentData::BuildLog(_) => {}
+ }
+ }
+
+ Some(WorkspaceEdit::new(changes))
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::TextEdit;
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_entry() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("main.bib", r#"@article{foo, bar = baz}"#),
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ])
+ .main("main.bib")
+ .line(0)
+ .character(9)
+ .new_name("qux")
+ .build();
+
+ let uri1 = tester.uri("main.bib");
+ let uri2 = tester.uri("main.tex");
+ let request = tester.rename();
+
+ let context = CursorContext::new(request);
+ let actual_edit = rename_entry(&context, CancellationToken::none()).unwrap();
+
+ let mut expected_changes = HashMap::new();
+ expected_changes.insert(
+ uri1.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(0, 9, 0, 12), "qux".into())],
+ );
+ expected_changes.insert(
+ uri2.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(1, 6, 1, 9), "qux".into())],
+ );
+ let expected_edit = WorkspaceEdit::new(expected_changes);
+
+ assert_eq!(actual_edit, expected_edit);
+ }
+
+ #[test]
+ fn test_citation() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("main.bib", r#"@article{foo, bar = baz}"#),
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(6)
+ .new_name("qux")
+ .build();
+
+ let uri1 = tester.uri("main.bib");
+ let uri2 = tester.uri("main.tex");
+ let request = tester.rename();
+
+ let context = CursorContext::new(request);
+ let actual_edit = rename_entry(&context, CancellationToken::none()).unwrap();
+
+ let mut expected_changes = HashMap::new();
+ expected_changes.insert(
+ uri1.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(0, 9, 0, 12), "qux".into())],
+ );
+ expected_changes.insert(
+ uri2.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(1, 6, 1, 9), "qux".into())],
+ );
+ let expected_edit = WorkspaceEdit::new(expected_changes);
+
+ assert_eq!(actual_edit, expected_edit);
+ }
+}
diff --git a/support/texlab/src/features/rename/label.rs b/support/texlab/src/features/rename/label.rs
new file mode 100644
index 0000000000..11b414ccfa
--- /dev/null
+++ b/support/texlab/src/features/rename/label.rs
@@ -0,0 +1,142 @@
+use std::collections::HashMap;
+
+use cancellation::CancellationToken;
+use lsp_types::{Range, RenameParams, TextEdit, WorkspaceEdit};
+
+use crate::{
+ features::cursor::{CursorContext, HasPosition},
+ syntax::{latex, CstNode},
+ LineIndexExt,
+};
+
+pub fn prepare_label_rename<P: HasPosition>(
+ context: &CursorContext<P>,
+ _cancellation_token: &CancellationToken,
+) -> Option<Range> {
+ let name = context.cursor.as_latex()?;
+ name.parent().parent().filter(|node| {
+ matches!(
+ node.kind(),
+ latex::LABEL_DEFINITION | latex::LABEL_REFERENCE | latex::LABEL_REFERENCE_RANGE
+ )
+ })?;
+
+ Some(
+ context
+ .request
+ .main_document()
+ .line_index
+ .line_col_lsp_range(name.text_range()),
+ )
+}
+
+pub fn rename_label(
+ context: &CursorContext<RenameParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<WorkspaceEdit> {
+ prepare_label_rename(context, cancellation_token)?;
+ let name_text = context.cursor.as_latex()?.text();
+ let mut changes = HashMap::new();
+ for document in &context.request.subset.documents {
+ cancellation_token.result().ok()?;
+ if let Some(data) = document.data.as_latex() {
+ let mut edits = Vec::new();
+ for node in data.root.descendants() {
+ if let Some(range) = latex::LabelDefinition::cast(node)
+ .and_then(|label| label.name())
+ .and_then(|name| name.word())
+ .filter(|name| name.text() == name_text)
+ .map(|name| document.line_index.line_col_lsp_range(name.text_range()))
+ {
+ edits.push(TextEdit::new(
+ range,
+ context.request.params.new_name.clone(),
+ ));
+ }
+
+ latex::LabelReference::cast(node)
+ .and_then(|label| label.name_list())
+ .into_iter()
+ .flat_map(|label| label.words())
+ .filter(|name| name.text() == name_text)
+ .map(|name| document.line_index.line_col_lsp_range(name.text_range()))
+ .for_each(|range| {
+ edits.push(TextEdit::new(
+ range,
+ context.request.params.new_name.clone(),
+ ));
+ });
+
+ if let Some(label) = latex::LabelReferenceRange::cast(node) {
+ if let Some(name1) = label
+ .from()
+ .and_then(|name| name.word())
+ .filter(|name| name.text() == name_text)
+ {
+ edits.push(TextEdit::new(
+ document.line_index.line_col_lsp_range(name1.text_range()),
+ context.request.params.new_name.clone(),
+ ));
+ }
+
+ if let Some(name2) = label
+ .from()
+ .and_then(|name| name.word())
+ .filter(|name| name.text() == name_text)
+ {
+ edits.push(TextEdit::new(
+ document.line_index.line_col_lsp_range(name2.text_range()),
+ context.request.params.new_name.clone(),
+ ));
+ }
+ }
+ }
+
+ changes.insert(document.uri.as_ref().clone().into(), edits);
+ }
+ }
+
+ Some(WorkspaceEdit::new(changes))
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_label() {
+ let tester = FeatureTester::builder()
+ .files(vec![
+ ("foo.tex", r#"\label{foo}\include{bar}"#),
+ ("bar.tex", r#"\ref{foo}"#),
+ ("baz.tex", r#"\ref{foo}"#),
+ ])
+ .main("foo.tex")
+ .line(0)
+ .character(7)
+ .new_name("bar")
+ .build();
+
+ let uri1 = tester.uri("foo.tex");
+ let uri2 = tester.uri("bar.tex");
+ let request = tester.rename();
+
+ let context = CursorContext::new(request);
+ let actual_edit = rename_label(&context, CancellationToken::none()).unwrap();
+
+ let mut expected_changes = HashMap::new();
+ expected_changes.insert(
+ uri1.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(0, 7, 0, 10), "bar".into())],
+ );
+ expected_changes.insert(
+ uri2.as_ref().clone().into(),
+ vec![TextEdit::new(Range::new_simple(0, 5, 0, 8), "bar".into())],
+ );
+ let expected_edit = WorkspaceEdit::new(expected_changes);
+
+ assert_eq!(actual_edit, expected_edit);
+ }
+}
diff --git a/support/texlab/src/features/semantic.rs b/support/texlab/src/features/semantic.rs
new file mode 100644
index 0000000000..8dd2674601
--- /dev/null
+++ b/support/texlab/src/features/semantic.rs
@@ -0,0 +1,21 @@
+mod bibtex;
+pub mod legend;
+
+use cancellation::CancellationToken;
+use lsp_types::{SemanticTokens, SemanticTokensRangeParams};
+
+use self::bibtex::find_bibtex_semantic_tokens_range;
+
+use super::FeatureRequest;
+
+pub fn find_semantic_tokens_range(
+ request: FeatureRequest<SemanticTokensRangeParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<SemanticTokens> {
+ let mut data = Vec::new();
+ find_bibtex_semantic_tokens_range(&request, &mut data, cancellation_token);
+ Some(SemanticTokens {
+ result_id: None,
+ data,
+ })
+}
diff --git a/support/texlab/src/features/semantic/bibtex.rs b/support/texlab/src/features/semantic/bibtex.rs
new file mode 100644
index 0000000000..6d6a46b6ce
--- /dev/null
+++ b/support/texlab/src/features/semantic/bibtex.rs
@@ -0,0 +1,289 @@
+use cancellation::CancellationToken;
+use cstree::{NodeOrToken, TextRange};
+use lsp_types::{
+ SemanticToken, SemanticTokenModifier, SemanticTokenType, SemanticTokensRangeParams,
+};
+
+use crate::{
+ features::FeatureRequest,
+ syntax::{bibtex, CstNode},
+ BibtexEntryTypeCategory, LineIndex, LineIndexExt, LANGUAGE_DATA,
+};
+
+use super::legend::*;
+
+struct Context<'a> {
+ line_index: &'a LineIndex,
+ previous_line: u32,
+ previous_character: u32,
+ tokens: &'a mut Vec<SemanticToken>,
+ cancellation_token: &'a CancellationToken,
+}
+
+impl<'a> Context<'a> {
+ pub fn insert(
+ &mut self,
+ range: TextRange,
+ token_type: SemanticTokenType,
+ token_modifiers_bitset: ModifierSet,
+ ) {
+ let range = self.line_index.line_col_lsp_range(range);
+
+ let mut delta_line = range.start.line;
+ let mut delta_start = range.start.character;
+ if !self.tokens.is_empty() {
+ delta_line -= self.previous_line;
+ if delta_line == 0 {
+ delta_start -= self.previous_character;
+ }
+ }
+ self.tokens.push(SemanticToken {
+ delta_line,
+ delta_start,
+ length: range.end.character - range.start.character,
+ token_type: type_index(token_type),
+ token_modifiers_bitset: token_modifiers_bitset.0,
+ });
+
+ self.previous_line = range.start.line;
+ self.previous_character = range.start.character;
+ }
+}
+
+pub fn find_bibtex_semantic_tokens_range(
+ request: &FeatureRequest<SemanticTokensRangeParams>,
+ tokens: &mut Vec<SemanticToken>,
+ cancellation_token: &CancellationToken,
+) -> Option<()> {
+ let document = request.main_document();
+ let data = document.data.as_bibtex()?;
+
+ let mut context = Context {
+ line_index: &document.line_index,
+ previous_line: 0,
+ previous_character: 0,
+ tokens,
+ cancellation_token,
+ };
+
+ let range = document.line_index.offset_lsp_range(request.params.range);
+
+ for node in data
+ .root
+ .children()
+ .filter(|node| node.text_range().intersect(range).is_some())
+ {
+ cancellation_token.result().ok()?;
+ visit_junk(&mut context, node)
+ .or_else(|| visit_preamble(&mut context, node))
+ .or_else(|| visit_string(&mut context, node))
+ .or_else(|| visit_entry(&mut context, node));
+ }
+
+ Some(())
+}
+
+fn visit_junk(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ let junk = bibtex::Junk::cast(node)?;
+ for token in junk
+ .syntax()
+ .children_with_tokens()
+ .filter_map(|element| element.into_token())
+ .filter(|token| token.kind() != bibtex::WHITESPACE)
+ {
+ context.insert(token.text_range(), JUNK, ModifierSet::default());
+ }
+ Some(())
+}
+
+fn visit_preamble(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ let preamble = bibtex::Preamble::cast(node)?;
+ for element in preamble.syntax().children_with_tokens() {
+ match element {
+ NodeOrToken::Node(value) => {
+ visit_value(context, value);
+ }
+ NodeOrToken::Token(token) => match token.kind() {
+ bibtex::PREAMBLE_TYPE => {
+ context.insert(token.text_range(), PREAMBLE_TYPE, ModifierSet::default());
+ }
+ bibtex::L_CURLY | bibtex::R_CURLY => {
+ context.insert(token.text_range(), CURLY, ModifierSet::default());
+ }
+ bibtex::L_PAREN | bibtex::R_PAREN => {
+ context.insert(token.text_range(), PAREN, ModifierSet::default());
+ }
+ _ => {}
+ },
+ }
+ }
+
+ Some(())
+}
+
+fn visit_string(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ let string = bibtex::String::cast(node)?;
+ for element in string.syntax().children_with_tokens() {
+ match element {
+ NodeOrToken::Node(value) => {
+ visit_value(context, value);
+ }
+ NodeOrToken::Token(token) => match token.kind() {
+ bibtex::STRING_TYPE => {
+ context.insert(token.text_range(), STRING_TYPE, ModifierSet::default());
+ }
+ bibtex::L_CURLY | bibtex::R_CURLY => {
+ context.insert(token.text_range(), CURLY, ModifierSet::default());
+ }
+ bibtex::L_PAREN | bibtex::R_PAREN => {
+ context.insert(token.text_range(), PAREN, ModifierSet::default());
+ }
+ bibtex::WORD => {
+ context.insert(
+ token.text_range(),
+ STRING_NAME,
+ ModifierSet::default() | SemanticTokenModifier::DEFINITION,
+ );
+ }
+ bibtex::EQUALITY_SIGN => {
+ context.insert(token.text_range(), EQUALITY_SIGN, ModifierSet::default());
+ }
+ _ => {}
+ },
+ }
+ }
+
+ Some(())
+}
+
+fn visit_entry(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ let entry = bibtex::Entry::cast(node)?;
+
+ for element in entry.syntax().children_with_tokens() {
+ match element {
+ NodeOrToken::Node(field) => {
+ visit_field(context, field);
+ }
+ NodeOrToken::Token(token) => match token.kind() {
+ bibtex::ENTRY_TYPE => {
+ context.insert(
+ token.text_range(),
+ match LANGUAGE_DATA.find_entry_type(&token.text()[1..]) {
+ Some(ty) => match ty.category {
+ BibtexEntryTypeCategory::Article => ARTICLE_TYPE,
+ BibtexEntryTypeCategory::Misc => MISC_TYPE,
+ BibtexEntryTypeCategory::String => STRING_TYPE,
+ BibtexEntryTypeCategory::Book => BOOK_TYPE,
+ BibtexEntryTypeCategory::Collection => COLLECTION_TYPE,
+ BibtexEntryTypeCategory::Part => PART_TYPE,
+ BibtexEntryTypeCategory::Thesis => THESIS_TYPE,
+ },
+ None => UNKNOWN_TYPE,
+ },
+ ModifierSet::default(),
+ );
+ }
+ bibtex::L_CURLY | bibtex::R_CURLY => {
+ context.insert(token.text_range(), CURLY, ModifierSet::default());
+ }
+ bibtex::L_PAREN | bibtex::R_PAREN => {
+ context.insert(token.text_range(), PAREN, ModifierSet::default());
+ }
+ bibtex::WORD => {
+ context.insert(
+ token.text_range(),
+ ENTRY_KEY,
+ ModifierSet::default()
+ | SemanticTokenModifier::DEFINITION
+ | SemanticTokenModifier::READONLY,
+ );
+ }
+ bibtex::COMMA => {
+ context.insert(token.text_range(), COMMA, ModifierSet::default());
+ }
+ _ => {}
+ },
+ }
+ }
+
+ Some(())
+}
+
+fn visit_field(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ context.cancellation_token.result().ok()?;
+ let field = bibtex::Field::cast(node)?;
+ context.insert(field.name()?.text_range(), FIELD, ModifierSet::default());
+ if let Some(token) = field.equality_sign() {
+ context.insert(token.text_range(), EQUALITY_SIGN, ModifierSet::default());
+ }
+
+ if let Some(value) = field.value() {
+ visit_value(context, value.syntax());
+ }
+ Some(())
+}
+
+fn visit_value(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ context.cancellation_token.result().ok()?;
+ let value = bibtex::Value::cast(node)?;
+ for child in value.syntax().children_with_tokens() {
+ match child {
+ NodeOrToken::Token(token) if token.kind() == bibtex::HASH => {
+ context.insert(token.text_range(), HASH, ModifierSet::default());
+ }
+ NodeOrToken::Token(_) => {}
+ NodeOrToken::Node(token) => {
+ if let Some(word) = token
+ .first_child_or_token()
+ .and_then(|child| child.into_token())
+ {
+ if word.text().chars().all(|c| c.is_ascii_digit()) {
+ context.insert(
+ word.text_range(),
+ SemanticTokenType::NUMBER,
+ ModifierSet::default(),
+ );
+ } else {
+ context.insert(word.text_range(), STRING_NAME, ModifierSet::default());
+ }
+ } else {
+ visit_content(context, token);
+ }
+ }
+ }
+ }
+ Some(())
+}
+
+fn visit_content(context: &mut Context, node: &bibtex::SyntaxNode) -> Option<()> {
+ for token in node
+ .descendants_with_tokens()
+ .filter_map(|element| element.into_token())
+ {
+ match token.kind() {
+ bibtex::WORD => {
+ context.insert(token.text_range(), TEXT, ModifierSet::default());
+ }
+ bibtex::COMMA => {
+ context.insert(token.text_range(), COMMA, ModifierSet::default());
+ }
+ bibtex::L_CURLY | bibtex::R_CURLY => {
+ context.insert(token.text_range(), CURLY, ModifierSet::default());
+ }
+ bibtex::L_PAREN | bibtex::R_PAREN => {
+ context.insert(token.text_range(), PAREN, ModifierSet::default());
+ }
+ bibtex::SyntaxKind::QUOTE => {
+ context.insert(token.text_range(), QUOTE, ModifierSet::default());
+ }
+ bibtex::SyntaxKind::EQUALITY_SIGN => {
+ context.insert(token.text_range(), EQUALITY_SIGN, ModifierSet::default());
+ }
+ bibtex::SyntaxKind::COMMAND_NAME => {
+ context.insert(token.text_range(), GENERIC_COMMAND, ModifierSet::default());
+ }
+ _ => {}
+ }
+ }
+ Some(())
+}
diff --git a/support/texlab/src/features/semantic/legend.rs b/support/texlab/src/features/semantic/legend.rs
new file mode 100644
index 0000000000..0b2a53cd38
--- /dev/null
+++ b/support/texlab/src/features/semantic/legend.rs
@@ -0,0 +1,83 @@
+use std::ops;
+
+use lsp_types::{SemanticTokenModifier, SemanticTokenType};
+
+macro_rules! define_semantic_token_types {
+ ($(($ident:ident, $string:literal)),*$(,)?) => {
+ $(pub const $ident: SemanticTokenType = SemanticTokenType::new($string);)*
+
+ pub const SUPPORTED_TYPES: &[SemanticTokenType] = &[
+ SemanticTokenType::COMMENT,
+ SemanticTokenType::NUMBER,
+ $($ident),*
+ ];
+ };
+}
+
+define_semantic_token_types![
+ (JUNK, "junk"),
+ (PREAMBLE_TYPE, "preambleType"),
+ (STRING_TYPE, "stringType"),
+ (COMMENT_TYPE, "commentType"),
+ (ARTICLE_TYPE, "articleType"),
+ (BOOK_TYPE, "bookType"),
+ (COLLECTION_TYPE, "collectionType"),
+ (PART_TYPE, "partType"),
+ (THESIS_TYPE, "thesisType"),
+ (MISC_TYPE, "miscType"),
+ (UNKNOWN_TYPE, "unknownType"),
+ (CURLY, "curly"),
+ (BRACK, "brack"),
+ (PAREN, "paren"),
+ (COMMA, "comma"),
+ (ENTRY_KEY, "entryKey"),
+ (FIELD, "field"),
+ (TEXT, "text"),
+ (STRING_NAME, "string"),
+ (EQUALITY_SIGN, "equalitySign"),
+ (HASH, "hash"),
+ (QUOTE, "quote"),
+ (GENERIC_COMMAND, "genericCommand"),
+];
+
+macro_rules! define_semantic_token_modifiers {
+ ($(($ident:ident, $string:literal)),*$(,)?) => {
+ $(pub const $ident: SemanticTokenModifier = SemanticTokenModifier::new($string);)*
+
+ pub const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
+ SemanticTokenModifier::DEFAULT_LIBRARY,
+ SemanticTokenModifier::DECLARATION,
+ SemanticTokenModifier::DEFINITION,
+ SemanticTokenModifier::READONLY,
+ $($ident),*
+ ];
+ };
+}
+
+define_semantic_token_modifiers![(ITALIC, "italic"),];
+
+pub fn type_index(ty: SemanticTokenType) -> u32 {
+ SUPPORTED_TYPES.iter().position(|t| *t == ty).unwrap() as u32
+}
+
+#[derive(Default)]
+pub struct ModifierSet(pub u32);
+
+impl ops::BitOrAssign<SemanticTokenModifier> for ModifierSet {
+ fn bitor_assign(&mut self, rhs: SemanticTokenModifier) {
+ let index = SUPPORTED_MODIFIERS
+ .iter()
+ .position(|modifier| modifier == &rhs)
+ .unwrap();
+ self.0 |= 1 << index;
+ }
+}
+
+impl ops::BitOr<SemanticTokenModifier> for ModifierSet {
+ type Output = ModifierSet;
+
+ fn bitor(mut self, rhs: SemanticTokenModifier) -> Self::Output {
+ self |= rhs;
+ self
+ }
+}
diff --git a/support/texlab/src/features/symbol.rs b/support/texlab/src/features/symbol.rs
new file mode 100644
index 0000000000..349b6d0a37
--- /dev/null
+++ b/support/texlab/src/features/symbol.rs
@@ -0,0 +1,125 @@
+mod bibtex;
+mod latex;
+mod project_order;
+mod types;
+
+use std::{cmp::Reverse, sync::Arc};
+
+use cancellation::CancellationToken;
+use lsp_types::{
+ DocumentSymbolParams, DocumentSymbolResponse, SymbolInformation, WorkspaceSymbolParams,
+};
+
+use crate::{ClientCapabilitiesExt, Uri, Workspace};
+
+use self::{
+ bibtex::find_bibtex_symbols, latex::find_latex_symbols, project_order::ProjectOrdering,
+};
+
+use super::FeatureRequest;
+
+pub fn find_document_symbols(
+ req: FeatureRequest<DocumentSymbolParams>,
+ token: &CancellationToken,
+) -> DocumentSymbolResponse {
+ let mut buf = Vec::new();
+ find_latex_symbols(&req.subset, &mut buf, token);
+ find_bibtex_symbols(&req.subset, &mut buf, token);
+ if req
+ .context
+ .client_capabilities
+ .lock()
+ .unwrap()
+ .has_hierarchical_document_symbol_support()
+ {
+ DocumentSymbolResponse::Nested(
+ buf.into_iter()
+ .map(|symbol| symbol.into_document_symbol())
+ .collect(),
+ )
+ } else {
+ let mut new_buf = Vec::new();
+ for symbol in buf {
+ symbol.flatten(&mut new_buf);
+ }
+ let mut new_buf = new_buf
+ .into_iter()
+ .map(|symbol| symbol.into_symbol_info(req.main_document().uri.as_ref().clone()))
+ .collect();
+ sort_symbols(req.workspace.as_ref(), &mut new_buf);
+ DocumentSymbolResponse::Flat(new_buf)
+ }
+}
+
+#[derive(Debug, Clone)]
+struct WorkspaceSymbol {
+ info: SymbolInformation,
+ search_text: String,
+}
+
+pub fn find_workspace_symbols(
+ workspace: &dyn Workspace,
+ params: &WorkspaceSymbolParams,
+ token: &CancellationToken,
+) -> Vec<SymbolInformation> {
+ let mut symbols = Vec::new();
+
+ for document in workspace.documents() {
+ if let Some(subset) = workspace.subset(Arc::clone(&document.uri)) {
+ let mut buf = Vec::new();
+ find_latex_symbols(&subset, &mut buf, token);
+ find_bibtex_symbols(&subset, &mut buf, token);
+ let mut new_buf = Vec::new();
+
+ for symbol in buf {
+ symbol.flatten(&mut new_buf);
+ }
+
+ for symbol in new_buf {
+ symbols.push(WorkspaceSymbol {
+ search_text: symbol.search_text(),
+ info: symbol.into_symbol_info(document.uri.as_ref().clone()),
+ });
+ }
+ }
+ }
+
+ let query_words: Vec<_> = params
+ .query
+ .split_whitespace()
+ .map(str::to_lowercase)
+ .collect();
+ let mut filtered = Vec::new();
+ for symbol in symbols {
+ let mut included = true;
+ for word in &query_words {
+ if !symbol.search_text.contains(word) {
+ included = false;
+ break;
+ }
+ }
+
+ if included {
+ filtered.push(symbol.info);
+ }
+ }
+ sort_symbols(workspace, &mut filtered);
+ filtered
+}
+
+fn sort_symbols(workspace: &dyn Workspace, symbols: &mut Vec<SymbolInformation>) {
+ let ordering = ProjectOrdering::from(workspace);
+ symbols.sort_by(|left, right| {
+ let left_key = (
+ ordering.get(&Uri::from(left.location.uri.clone())),
+ left.location.range.start,
+ Reverse(left.location.range.end),
+ );
+ let right_key = (
+ ordering.get(&Uri::from(right.location.uri.clone())),
+ right.location.range.start,
+ Reverse(right.location.range.end),
+ );
+ left_key.cmp(&right_key)
+ });
+}
diff --git a/support/texlab/src/features/symbol/bibtex.rs b/support/texlab/src/features/symbol/bibtex.rs
new file mode 100644
index 0000000000..e030195880
--- /dev/null
+++ b/support/texlab/src/features/symbol/bibtex.rs
@@ -0,0 +1,88 @@
+use cancellation::CancellationToken;
+
+use crate::{
+ syntax::{
+ bibtex::{self, HasType},
+ CstNode,
+ },
+ BibtexEntryTypeCategory, LineIndexExt, WorkspaceSubset, LANGUAGE_DATA,
+};
+
+use super::types::{InternalSymbol, InternalSymbolKind};
+
+pub fn find_bibtex_symbols(
+ subset: &WorkspaceSubset,
+ buf: &mut Vec<InternalSymbol>,
+ token: &CancellationToken,
+) -> Option<()> {
+ let main_document = subset.documents.first()?;
+ let data = main_document.data.as_bibtex()?;
+
+ for node in data.root.children() {
+ if token.is_canceled() {
+ return None;
+ }
+
+ if let Some(string) = bibtex::String::cast(node) {
+ if let Some(name) = string.name() {
+ buf.push(InternalSymbol {
+ name: name.text().into(),
+ label: None,
+ kind: InternalSymbolKind::String,
+ deprecated: false,
+ full_range: main_document
+ .line_index
+ .line_col_lsp_range(string.small_range()),
+ selection_range: main_document
+ .line_index
+ .line_col_lsp_range(name.text_range()),
+ children: Vec::new(),
+ })
+ }
+ } else if let Some(entry) = bibtex::Entry::cast(node) {
+ if let Some(ty) = entry.ty() {
+ if let Some(key) = entry.key() {
+ let mut children = Vec::new();
+ for field in entry.fields() {
+ if let Some(name) = field.name() {
+ let symbol = InternalSymbol {
+ name: name.text().to_string(),
+ label: None,
+ kind: InternalSymbolKind::Field,
+ deprecated: false,
+ full_range: main_document
+ .line_index
+ .line_col_lsp_range(field.small_range()),
+ selection_range: main_document
+ .line_index
+ .line_col_lsp_range(name.text_range()),
+ children: Vec::new(),
+ };
+ children.push(symbol);
+ }
+ }
+
+ let category = LANGUAGE_DATA
+ .find_entry_type(&ty.text()[1..])
+ .map(|ty| ty.category)
+ .unwrap_or(BibtexEntryTypeCategory::Misc);
+
+ buf.push(InternalSymbol {
+ name: key.text().to_string(),
+ label: None,
+ kind: InternalSymbolKind::Entry(category),
+ deprecated: false,
+ full_range: main_document
+ .line_index
+ .line_col_lsp_range(entry.small_range()),
+ selection_range: main_document
+ .line_index
+ .line_col_lsp_range(key.text_range()),
+ children,
+ });
+ }
+ }
+ }
+ }
+ Some(())
+}
diff --git a/support/texlab/src/features/symbol/latex.rs b/support/texlab/src/features/symbol/latex.rs
new file mode 100644
index 0000000000..ce584c0c76
--- /dev/null
+++ b/support/texlab/src/features/symbol/latex.rs
@@ -0,0 +1,488 @@
+use std::str::FromStr;
+
+use cancellation::CancellationToken;
+use lsp_types::Range;
+use smol_str::SmolStr;
+use titlecase::titlecase;
+
+use crate::{
+ find_caption_by_parent, find_label_number,
+ syntax::{
+ latex::{self, HasBrack, HasCurly},
+ CstNode,
+ },
+ LabelledFloatKind, LatexDocumentData, LineIndexExt, WorkspaceSubset, LANGUAGE_DATA,
+};
+
+use super::types::{InternalSymbol, InternalSymbolKind};
+
+pub fn find_latex_symbols(
+ subset: &WorkspaceSubset,
+ buf: &mut Vec<InternalSymbol>,
+ token: &CancellationToken,
+) -> Option<()> {
+ let main_document = subset
+ .documents
+ .first()
+ .filter(|document| document.uri.as_str().ends_with(".tex"))?;
+
+ let data = main_document.data.as_latex()?;
+ let mut context = Context {
+ subset,
+ data,
+ token,
+ };
+
+ let root = &context.data.root;
+ let mut symbols = visit(&mut context, root);
+ buf.append(&mut symbols);
+ Some(())
+}
+
+struct Context<'a> {
+ subset: &'a WorkspaceSubset,
+ data: &'a LatexDocumentData,
+ token: &'a CancellationToken,
+}
+
+fn visit(context: &mut Context, node: &latex::SyntaxNode) -> Vec<InternalSymbol> {
+ let symbol = match node.kind() {
+ latex::PART
+ | latex::CHAPTER
+ | latex::SECTION
+ | latex::SUBSECTION
+ | latex::SUBSUBSECTION
+ | latex::PARAGRAPH
+ | latex::SUBPARAGRAPH => visit_section(context, node),
+ latex::ENUM_ITEM => visit_enum_item(context, node),
+ latex::EQUATION => visit_equation(context, node),
+ latex::ENVIRONMENT => latex::Environment::cast(node)
+ .and_then(|env| env.begin())
+ .and_then(|begin| begin.name())
+ .and_then(|name| name.word())
+ .map(|name| name.text())
+ .and_then(|name| {
+ if LANGUAGE_DATA
+ .math_environments
+ .iter()
+ .any(|env| env == name)
+ {
+ visit_equation_environment(context, node)
+ } else if LANGUAGE_DATA
+ .enum_environments
+ .iter()
+ .any(|env| env == name)
+ {
+ visit_enumeration(context, node, name)
+ } else if let Ok(float_kind) = LabelledFloatKind::from_str(name) {
+ visit_float(context, node, float_kind)
+ } else {
+ visit_theorem(context, node, name)
+ }
+ }),
+ _ => None,
+ };
+
+ match symbol {
+ Some(mut parent) => {
+ for child in node.children() {
+ if context.token.is_canceled() {
+ break;
+ }
+
+ parent.children.append(&mut visit(context, child));
+ }
+ vec![parent]
+ }
+ None => {
+ let mut symbols = Vec::new();
+ for child in node.children() {
+ if context.token.is_canceled() {
+ break;
+ }
+ symbols.append(&mut visit(context, child));
+ }
+ symbols
+ }
+ }
+}
+
+fn visit_section(context: &mut Context, node: &latex::SyntaxNode) -> Option<InternalSymbol> {
+ let section = latex::Section::cast(node)?;
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(section.small_range());
+
+ let group = section.name()?;
+ let group_text = group.content_text()?;
+
+ let symbol = match find_label_by_parent(context, section.syntax()) {
+ Some(NumberedLabel {
+ name: label,
+ range: selection_range,
+ number,
+ }) => {
+ let name = match number {
+ Some(number) => format!("{} {}", number, group_text),
+ None => group_text.to_string(),
+ };
+
+ InternalSymbol {
+ name,
+ label: Some(label),
+ kind: InternalSymbolKind::Section,
+ deprecated: false,
+ full_range,
+ selection_range,
+ children: Vec::new(),
+ }
+ }
+ None => InternalSymbol {
+ name: group_text.to_string(),
+ label: None,
+ kind: InternalSymbolKind::Section,
+ deprecated: false,
+ full_range,
+ selection_range: full_range,
+ children: Vec::new(),
+ },
+ };
+ Some(symbol)
+}
+
+fn visit_enum_item(context: &mut Context, node: &latex::SyntaxNode) -> Option<InternalSymbol> {
+ let enum_item = latex::EnumItem::cast(node)?;
+ if !enum_item
+ .syntax()
+ .ancestors()
+ .filter_map(latex::Environment::cast)
+ .filter_map(|environment| environment.begin())
+ .filter_map(|begin| begin.name())
+ .filter_map(|name| name.word())
+ .any(|name| {
+ LANGUAGE_DATA
+ .enum_environments
+ .iter()
+ .any(|e| e == name.text())
+ })
+ {
+ return None;
+ }
+
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(enum_item.small_range());
+
+ let name = enum_item
+ .label()
+ .and_then(|label| label.content_text())
+ .unwrap_or_else(|| "Item".to_string());
+
+ let symbol = match find_label_by_parent(context, node) {
+ Some(NumberedLabel {
+ name: label,
+ range: selection_range,
+ number,
+ }) => InternalSymbol {
+ name: number.map(Into::into).unwrap_or_else(|| name.to_string()),
+ label: Some(label),
+ kind: InternalSymbolKind::EnumerationItem,
+ deprecated: false,
+ full_range,
+ selection_range,
+ children: Vec::new(),
+ },
+ None => InternalSymbol {
+ name: name.to_string(),
+ label: None,
+ kind: InternalSymbolKind::EnumerationItem,
+ deprecated: false,
+ full_range,
+ selection_range: full_range,
+ children: Vec::new(),
+ },
+ };
+ Some(symbol)
+}
+
+fn visit_equation(context: &mut Context, node: &latex::SyntaxNode) -> Option<InternalSymbol> {
+ let equation = latex::Equation::cast(node)?;
+
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(equation.small_range());
+
+ make_equation_symbol(context, node, full_range)
+}
+
+fn visit_equation_environment(
+ context: &mut Context,
+ node: &latex::SyntaxNode,
+) -> Option<InternalSymbol> {
+ let environment = latex::Environment::cast(node)?;
+
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(environment.small_range());
+
+ make_equation_symbol(context, node, full_range)
+}
+
+fn make_equation_symbol(
+ context: &mut Context,
+ node: &cstree::ResolvedNode<latex::Language>,
+ full_range: Range,
+) -> Option<InternalSymbol> {
+ let symbol = match find_label_by_parent(context, node) {
+ Some(NumberedLabel {
+ name: label,
+ range: selection_range,
+ number,
+ }) => {
+ let name = match number {
+ Some(number) => format!("Equation ({})", number),
+ None => "Equation".to_string(),
+ };
+
+ InternalSymbol {
+ name,
+ label: Some(label),
+ kind: InternalSymbolKind::Equation,
+ deprecated: false,
+ full_range,
+ selection_range,
+ children: Vec::new(),
+ }
+ }
+ None => InternalSymbol {
+ name: "Equation".to_string(),
+ label: None,
+ kind: InternalSymbolKind::Equation,
+ deprecated: false,
+ full_range,
+ selection_range: full_range,
+ children: Vec::new(),
+ },
+ };
+ Some(symbol)
+}
+
+fn visit_enumeration(
+ context: &mut Context,
+ node: &latex::SyntaxNode,
+ env_name: &str,
+) -> Option<InternalSymbol> {
+ let environment = latex::Environment::cast(node)?;
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(environment.small_range());
+
+ let name = titlecase(env_name);
+ let symbol = match find_label_by_parent(context, environment.syntax()) {
+ Some(NumberedLabel {
+ name: label,
+ range: selection_range,
+ number,
+ }) => {
+ let name = match number {
+ Some(number) => format!("{} {}", name, number),
+ None => name,
+ };
+
+ InternalSymbol {
+ name,
+ label: Some(label),
+ kind: InternalSymbolKind::Enumeration,
+ deprecated: false,
+ full_range,
+ selection_range,
+ children: Vec::new(),
+ }
+ }
+ None => InternalSymbol {
+ name,
+ label: None,
+ kind: InternalSymbolKind::Enumeration,
+ deprecated: false,
+ full_range,
+ selection_range: full_range,
+ children: Vec::new(),
+ },
+ };
+ Some(symbol)
+}
+
+fn visit_float(
+ context: &mut Context,
+ node: &latex::SyntaxNode,
+ float_kind: LabelledFloatKind,
+) -> Option<InternalSymbol> {
+ let environment = latex::Environment::cast(node)?;
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(environment.small_range());
+
+ let (float_kind, symbol_kind) = match float_kind {
+ LabelledFloatKind::Algorithm => ("Algorithm", InternalSymbolKind::Algorithm),
+ LabelledFloatKind::Figure => ("Figure", InternalSymbolKind::Figure),
+ LabelledFloatKind::Listing => ("Listing", InternalSymbolKind::Listing),
+ LabelledFloatKind::Table => ("Table", InternalSymbolKind::Table),
+ };
+
+ let caption = find_caption_by_parent(environment.syntax())?;
+ let symbol = match find_label_by_parent(context, environment.syntax()) {
+ Some(NumberedLabel {
+ name: label,
+ range: selection_range,
+ number,
+ }) => {
+ let name = match number {
+ Some(number) => format!("{} {}: {}", float_kind, number, caption),
+ None => format!("{}: {}", float_kind, caption),
+ };
+
+ InternalSymbol {
+ name,
+ label: Some(label),
+ kind: symbol_kind,
+ deprecated: false,
+ full_range,
+ selection_range,
+ children: Vec::new(),
+ }
+ }
+ None => InternalSymbol {
+ name: format!("{}: {}", float_kind, caption),
+ label: None,
+ kind: symbol_kind,
+ deprecated: false,
+ full_range,
+ selection_range: full_range,
+ children: Vec::new(),
+ },
+ };
+
+ Some(symbol)
+}
+
+fn visit_theorem(
+ context: &mut Context,
+ node: &latex::SyntaxNode,
+ environment_name: &str,
+) -> Option<InternalSymbol> {
+ let definition = context
+ .subset
+ .documents
+ .iter()
+ .filter_map(|document| document.data.as_latex())
+ .find_map(|data| {
+ data.extras
+ .theorem_environments
+ .iter()
+ .find(|environment| environment.name == environment_name)
+ .cloned()
+ })?;
+
+ let node = latex::Environment::cast(node)?;
+ let theorem_description = node
+ .begin()?
+ .options()
+ .and_then(|option| option.content_text());
+
+ let full_range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(node.small_range());
+
+ let symbol = match find_label_by_parent(context, node.syntax()) {
+ Some(NumberedLabel {
+ name: label,
+ range: selection_range,
+ number,
+ }) => {
+ let name = match (number, theorem_description) {
+ (Some(number), Some(desc)) => {
+ format!("{} {} ({})", definition.description, number, desc)
+ }
+ (Some(number), None) => format!("{} {}", definition.description, number),
+ (None, Some(desc)) => format!("{} ({})", definition.description, desc),
+ (None, None) => definition.description.clone(),
+ };
+
+ InternalSymbol {
+ name,
+ label: Some(label),
+ kind: InternalSymbolKind::Theorem,
+ deprecated: false,
+ full_range,
+ selection_range,
+ children: Vec::new(),
+ }
+ }
+ None => {
+ let name = match theorem_description {
+ Some(desc) => format!("{} ({})", definition.description, desc),
+ None => definition.description.to_string(),
+ };
+ InternalSymbol {
+ name,
+ label: None,
+ kind: InternalSymbolKind::Theorem,
+ deprecated: false,
+ full_range,
+ selection_range: full_range,
+ children: Vec::new(),
+ }
+ }
+ };
+ Some(symbol)
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+struct NumberedLabel {
+ name: String,
+ range: Range,
+ number: Option<SmolStr>,
+}
+
+fn find_label_by_parent(
+ context: &mut Context,
+ parent: &latex::SyntaxNode,
+) -> Option<NumberedLabel> {
+ let node = parent.children().find_map(latex::LabelDefinition::cast)?;
+
+ let name = node.name()?.word()?.text();
+ let range = context
+ .subset
+ .documents
+ .first()?
+ .line_index
+ .line_col_lsp_range(node.small_range());
+
+ let number = find_label_number(&context.subset, name);
+ Some(NumberedLabel {
+ name: name.to_string(),
+ range,
+ number: number.map(Into::into),
+ })
+}
diff --git a/support/texlab/src/features/symbol/project_order.rs b/support/texlab/src/features/symbol/project_order.rs
new file mode 100644
index 0000000000..08b43ad50c
--- /dev/null
+++ b/support/texlab/src/features/symbol/project_order.rs
@@ -0,0 +1,223 @@
+use std::{sync::Arc, usize};
+
+use petgraph::{algo::tarjan_scc, Directed, Graph};
+use rustc_hash::FxHashSet;
+
+use crate::{Uri, Workspace, WorkspaceSubset};
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct ProjectOrdering {
+ ordering: Vec<Arc<Uri>>,
+}
+
+impl ProjectOrdering {
+ pub fn get(&self, uri: &Uri) -> usize {
+ self.ordering
+ .iter()
+ .position(|u| u.as_ref() == uri)
+ .unwrap_or(usize::MAX)
+ }
+}
+
+impl From<&dyn Workspace> for ProjectOrdering {
+ fn from(workspace: &dyn Workspace) -> Self {
+ let mut ordering = Vec::new();
+ let uris: FxHashSet<Arc<Uri>> = workspace
+ .documents()
+ .into_iter()
+ .map(|document| Arc::clone(&document.uri))
+ .collect();
+
+ let comps = connected_components(workspace);
+ for comp in comps {
+ let graph = build_dependency_graph(&comp);
+
+ let mut visited = FxHashSet::default();
+ let root_index = *graph.node_weight(tarjan_scc(&graph)[0][0]).unwrap();
+ let mut stack = vec![Arc::clone(&comp.documents[root_index].uri)];
+
+ while let Some(uri) = stack.pop() {
+ if !visited.insert(Arc::clone(&uri)) {
+ continue;
+ }
+
+ ordering.push(Arc::clone(&uri));
+ if let Some(document) = workspace.get(&uri) {
+ if let Some(data) = document.data.as_latex() {
+ for link in data.extras.explicit_links.iter().rev() {
+ for target in &link.targets {
+ if uris.contains(target.as_ref()) {
+ stack.push(Arc::clone(target));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Self { ordering }
+ }
+}
+
+fn connected_components(workspace: &dyn Workspace) -> Vec<WorkspaceSubset> {
+ let mut components = Vec::new();
+ let mut visited = FxHashSet::default();
+ for root_document in workspace.documents() {
+ if !visited.insert(Arc::clone(&root_document.uri)) {
+ continue;
+ }
+
+ let subset = workspace.subset(Arc::clone(&root_document.uri)).unwrap();
+ for document in &subset.documents {
+ visited.insert(Arc::clone(&document.uri));
+ }
+ components.push(subset);
+ }
+ components
+}
+
+fn build_dependency_graph(subset: &WorkspaceSubset) -> Graph<usize, (), Directed> {
+ let mut graph = Graph::new();
+ let nodes: Vec<_> = (0..subset.documents.len())
+ .map(|i| graph.add_node(i))
+ .collect();
+
+ for (i, document) in subset.documents.iter().enumerate() {
+ if let Some(data) = document.data.as_latex() {
+ for link in &data.extras.explicit_links {
+ for target in &link.targets {
+ if let Some(j) = subset
+ .documents
+ .iter()
+ .position(|document| document.uri.as_ref() == target.as_ref())
+ {
+ graph.add_edge(nodes[j], nodes[i], ());
+ break;
+ }
+ }
+ }
+ }
+ }
+ graph
+}
+
+#[cfg(test)]
+mod tests {
+ use anyhow::Result;
+
+ use crate::{create_workspace_fast, DocumentLanguage, ServerContext, WorkspaceSource};
+
+ use super::*;
+
+ #[test]
+ fn test_no_cycles() -> Result<()> {
+ let workspace: Arc<dyn Workspace> = Arc::new(create_workspace_fast(Arc::new(
+ ServerContext::new(std::env::temp_dir()),
+ ))?);
+
+ let a = workspace.open(
+ Arc::new(Uri::parse("http://example.com/a.tex")?),
+ "".into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let b = workspace.open(
+ Arc::new(Uri::parse("http://example.com/b.tex")?),
+ "".into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let c = workspace.open(
+ Arc::new(Uri::parse("http://example.com/c.tex")?),
+ r#"\include{b}\include{a}"#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let ordering = ProjectOrdering::from(workspace.as_ref());
+
+ assert_eq!(ordering.get(&a.uri), 2);
+ assert_eq!(ordering.get(&b.uri), 1);
+ assert_eq!(ordering.get(&c.uri), 0);
+ Ok(())
+ }
+
+ #[test]
+ fn test_cycles() -> Result<()> {
+ let workspace: Arc<dyn Workspace> = Arc::new(create_workspace_fast(Arc::new(
+ ServerContext::new(std::env::temp_dir()),
+ ))?);
+
+ let a = workspace.open(
+ Arc::new(Uri::parse("http://example.com/a.tex")?),
+ r#"\include{b}"#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let b = workspace.open(
+ Arc::new(Uri::parse("http://example.com/b.tex")?),
+ r#"\include{a}"#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let c = workspace.open(
+ Arc::new(Uri::parse("http://example.com/c.tex")?),
+ r#"\include{a}"#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let ordering = ProjectOrdering::from(workspace.as_ref());
+
+ assert_eq!(ordering.get(&a.uri), 1);
+ assert_eq!(ordering.get(&b.uri), 2);
+ assert_eq!(ordering.get(&c.uri), 0);
+ Ok(())
+ }
+
+ #[test]
+ fn test_multiple_roots() -> Result<()> {
+ let workspace: Arc<dyn Workspace> = Arc::new(create_workspace_fast(Arc::new(
+ ServerContext::new(std::env::temp_dir()),
+ ))?);
+
+ let a = workspace.open(
+ Arc::new(Uri::parse("http://example.com/a.tex")?),
+ r#"\include{b}"#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let b = workspace.open(
+ Arc::new(Uri::parse("http://example.com/b.tex")?),
+ r#""#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let c = workspace.open(
+ Arc::new(Uri::parse("http://example.com/c.tex")?),
+ r#""#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let d = workspace.open(
+ Arc::new(Uri::parse("http://example.com/d.tex")?),
+ r#"\include{c}"#.into(),
+ DocumentLanguage::Latex,
+ WorkspaceSource::Client,
+ );
+
+ let ordering = ProjectOrdering::from(workspace.as_ref());
+
+ assert!(ordering.get(&a.uri) < ordering.get(&b.uri));
+ assert!(ordering.get(&d.uri) < ordering.get(&c.uri));
+ Ok(())
+ }
+}
diff --git a/support/texlab/src/symbol/types.rs b/support/texlab/src/features/symbol/types.rs
index f10f43c637..bb00a932d8 100644
--- a/support/texlab/src/symbol/types.rs
+++ b/support/texlab/src/features/symbol/types.rs
@@ -1,10 +1,9 @@
-use crate::{
- protocol::{DocumentSymbol, Location, Range, SymbolInformation, SymbolKind, Uri},
- syntax::{BibtexEntryTypeCategory, Structure},
-};
+use lsp_types::{DocumentSymbol, Location, Range, SymbolInformation, SymbolKind};
+
+use crate::{features::lsp_kinds::Structure, BibtexEntryTypeCategory, Uri};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum LatexSymbolKind {
+pub enum InternalSymbolKind {
Section,
Figure,
Algorithm,
@@ -19,8 +18,8 @@ pub enum LatexSymbolKind {
String,
}
-impl Into<SymbolKind> for LatexSymbolKind {
- fn into(self) -> SymbolKind {
+impl InternalSymbolKind {
+ pub fn into_symbol_kind(self) -> SymbolKind {
match self {
Self::Section => Structure::Section.symbol_kind(),
Self::Figure | Self::Algorithm | Self::Table | Self::Listing => {
@@ -38,37 +37,37 @@ impl Into<SymbolKind> for LatexSymbolKind {
}
#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct LatexSymbol {
+pub struct InternalSymbol {
pub name: String,
pub label: Option<String>,
- pub kind: LatexSymbolKind,
+ pub kind: InternalSymbolKind,
pub deprecated: bool,
pub full_range: Range,
pub selection_range: Range,
- pub children: Vec<LatexSymbol>,
+ pub children: Vec<InternalSymbol>,
}
-impl LatexSymbol {
+impl InternalSymbol {
pub fn search_text(&self) -> String {
let kind = match self.kind {
- LatexSymbolKind::Section => "latex section",
- LatexSymbolKind::Figure => "latex float figure",
- LatexSymbolKind::Algorithm => "latex float algorithm",
- LatexSymbolKind::Table => "latex float table",
- LatexSymbolKind::Listing => "latex float listing",
- LatexSymbolKind::Enumeration => "latex enumeration",
- LatexSymbolKind::EnumerationItem => "latex enumeration item",
- LatexSymbolKind::Theorem => "latex math",
- LatexSymbolKind::Equation => "latex math equation",
- LatexSymbolKind::Entry(_) => "bibtex entry",
- LatexSymbolKind::Field => "bibtex field",
- LatexSymbolKind::String => "bibtex string",
+ InternalSymbolKind::Section => "latex section",
+ InternalSymbolKind::Figure => "latex float figure",
+ InternalSymbolKind::Algorithm => "latex float algorithm",
+ InternalSymbolKind::Table => "latex float table",
+ InternalSymbolKind::Listing => "latex float listing",
+ InternalSymbolKind::Enumeration => "latex enumeration",
+ InternalSymbolKind::EnumerationItem => "latex enumeration item",
+ InternalSymbolKind::Theorem => "latex math",
+ InternalSymbolKind::Equation => "latex math equation",
+ InternalSymbolKind::Entry(_) => "bibtex entry",
+ InternalSymbolKind::Field => "bibtex field",
+ InternalSymbolKind::String => "bibtex string",
};
format!("{} {}", kind, self.name).to_lowercase()
}
pub fn flatten(mut self, buffer: &mut Vec<Self>) {
- if self.kind == LatexSymbolKind::Field {
+ if self.kind == InternalSymbolKind::Field {
return;
}
for symbol in self.children.drain(..) {
@@ -77,28 +76,34 @@ impl LatexSymbol {
buffer.push(self);
}
- pub fn into_symbol_info(self, uri: Uri) -> SymbolInformation {
- SymbolInformation {
+ pub fn into_document_symbol(self) -> DocumentSymbol {
+ let children = self
+ .children
+ .into_iter()
+ .map(|child| child.into_document_symbol())
+ .collect();
+ #[allow(deprecated)]
+ DocumentSymbol {
name: self.name,
+ detail: self.label,
+ kind: self.kind.into_symbol_kind(),
deprecated: Some(self.deprecated),
- kind: self.kind.into(),
- container_name: None,
- location: Location::new(uri.into(), self.full_range),
+ range: self.full_range,
+ selection_range: self.selection_range,
+ children: Some(children),
+ tags: None,
}
}
-}
-impl Into<DocumentSymbol> for LatexSymbol {
- fn into(self) -> DocumentSymbol {
- let children = self.children.into_iter().map(Into::into).collect();
- DocumentSymbol {
+ pub fn into_symbol_info(self, uri: Uri) -> SymbolInformation {
+ #[allow(deprecated)]
+ SymbolInformation {
name: self.name,
+ kind: self.kind.into_symbol_kind(),
deprecated: Some(self.deprecated),
- detail: self.label,
- kind: self.kind.into(),
- selection_range: self.selection_range,
- range: self.full_range,
- children: Some(children),
+ location: Location::new(uri.into(), self.full_range),
+ container_name: None,
+ tags: None,
}
}
}
diff --git a/support/texlab/src/folding/bibtex_decl.rs b/support/texlab/src/folding/bibtex_decl.rs
deleted file mode 100644
index f0ffa787e1..0000000000
--- a/support/texlab/src/folding/bibtex_decl.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{FoldingRange, FoldingRangeKind, FoldingRangeParams},
- syntax::{bibtex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use petgraph::graph::NodeIndex;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexDeclarationFoldingProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexDeclarationFoldingProvider {
- type Params = FoldingRangeParams;
- type Output = Vec<FoldingRange>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- tree.children(tree.root)
- .filter_map(|decl| Self::fold(tree, decl))
- .collect()
- } else {
- Vec::new()
- }
- }
-}
-
-impl BibtexDeclarationFoldingProvider {
- fn fold(tree: &bibtex::Tree, decl: NodeIndex) -> Option<FoldingRange> {
- let (ty, right) = match &tree.graph[decl] {
- bibtex::Node::Preamble(preamble) => (Some(&preamble.ty), preamble.right.as_ref()),
- bibtex::Node::String(string) => (Some(&string.ty), string.right.as_ref()),
- bibtex::Node::Entry(entry) => (Some(&entry.ty), entry.right.as_ref()),
- bibtex::Node::Root(_)
- | bibtex::Node::Comment(_)
- | bibtex::Node::Field(_)
- | bibtex::Node::Word(_)
- | bibtex::Node::Command(_)
- | bibtex::Node::QuotedContent(_)
- | bibtex::Node::BracedContent(_)
- | bibtex::Node::Concat(_) => (None, None),
- };
-
- Some(FoldingRange {
- start_line: ty?.start().line,
- start_character: Some(ty?.start().character),
- end_line: right?.end().line,
- end_character: Some(right?.end().character),
- kind: Some(FoldingRangeKind::Region),
- })
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn preamble() {
- let actual_foldings = FeatureTester::new()
- .file("main.bib", r#"@preamble{"foo"}"#)
- .main("main.bib")
- .test_folding(BibtexDeclarationFoldingProvider)
- .await;
-
- let expected_foldings = vec![FoldingRange {
- start_line: 0,
- start_character: Some(0),
- end_line: 0,
- end_character: Some(16),
- kind: Some(FoldingRangeKind::Region),
- }];
-
- assert_eq!(actual_foldings, expected_foldings);
- }
-
- #[tokio::test]
- async fn string() {
- let actual_foldings = FeatureTester::new()
- .file("main.bib", r#"@string{foo = "bar"}"#)
- .main("main.bib")
- .test_folding(BibtexDeclarationFoldingProvider)
- .await;
-
- let expected_foldings = vec![FoldingRange {
- start_line: 0,
- start_character: Some(0),
- end_line: 0,
- end_character: Some(20),
- kind: Some(FoldingRangeKind::Region),
- }];
-
- assert_eq!(actual_foldings, expected_foldings);
- }
-
- #[tokio::test]
- async fn entry() {
- let actual_foldings = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo,
- bar = baz
- }
- "#
- ),
- )
- .main("main.bib")
- .test_folding(BibtexDeclarationFoldingProvider)
- .await;
-
- let expected_foldings = vec![FoldingRange {
- start_line: 0,
- start_character: Some(0),
- end_line: 2,
- end_character: Some(1),
- kind: Some(FoldingRangeKind::Region),
- }];
-
- assert_eq!(actual_foldings, expected_foldings);
- }
-
- #[tokio::test]
- async fn comment() {
- let actual_foldings = FeatureTester::new()
- .file("main.bib", "foo")
- .main("main.bib")
- .test_folding(BibtexDeclarationFoldingProvider)
- .await;
-
- assert!(actual_foldings.is_empty());
- }
-
- #[tokio::test]
- async fn entry_invalid() {
- let actual_foldings = FeatureTester::new()
- .file("main.bib", "@article{foo,")
- .main("main.bib")
- .test_folding(BibtexDeclarationFoldingProvider)
- .await;
-
- assert!(actual_foldings.is_empty());
- }
-
- #[tokio::test]
- async fn latex() {
- let actual_foldings = FeatureTester::new()
- .file("main.tex", "foo")
- .main("main.tex")
- .test_folding(BibtexDeclarationFoldingProvider)
- .await;
-
- assert!(actual_foldings.is_empty());
- }
-}
diff --git a/support/texlab/src/folding/latex_env.rs b/support/texlab/src/folding/latex_env.rs
deleted file mode 100644
index ced2567b41..0000000000
--- a/support/texlab/src/folding/latex_env.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{FoldingRange, FoldingRangeKind, FoldingRangeParams},
- syntax::SyntaxNode,
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexEnvironmentFoldingProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexEnvironmentFoldingProvider {
- type Params = FoldingRangeParams;
- type Output = Vec<FoldingRange>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut foldings = Vec::new();
- if let DocumentContent::Latex(table) = &req.current().content {
- for env in &table.environments {
- let left_node = &table[env.left.parent];
- let right_node = &table[env.right.parent];
- let folding = FoldingRange {
- start_line: left_node.end().line,
- start_character: Some(left_node.end().character),
- end_line: right_node.start().line,
- end_character: Some(right_node.start().character),
- kind: Some(FoldingRangeKind::Region),
- };
- foldings.push(folding);
- }
- }
- foldings
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn multiline() {
- let actual_foldings = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{foo}
- \end{foo}
- "#
- ),
- )
- .main("main.tex")
- .test_folding(LatexEnvironmentFoldingProvider)
- .await;
-
- let expected_foldings = vec![FoldingRange {
- start_line: 0,
- start_character: Some(11),
- end_line: 1,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- }];
-
- assert_eq!(actual_foldings, expected_foldings);
- }
-
- #[tokio::test]
- async fn bibtex() {
- let actual_foldings = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_folding(LatexEnvironmentFoldingProvider)
- .await;
-
- assert!(actual_foldings.is_empty());
- }
-}
diff --git a/support/texlab/src/folding/latex_section.rs b/support/texlab/src/folding/latex_section.rs
deleted file mode 100644
index a37efe1a7a..0000000000
--- a/support/texlab/src/folding/latex_section.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{FoldingRange, FoldingRangeKind, FoldingRangeParams},
- syntax::SyntaxNode,
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexSectionFoldingProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexSectionFoldingProvider {
- type Params = FoldingRangeParams;
- type Output = Vec<FoldingRange>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut foldings = Vec::new();
- if let DocumentContent::Latex(table) = &req.current().content {
- let sections = &table.sections;
- for i in 0..sections.len() {
- let current = &sections[i];
- if let Some(next) = sections
- .iter()
- .skip(i + 1)
- .find(|sec| current.level >= sec.level)
- {
- let next_node = &table[next.parent];
- if next_node.start().line > 0 {
- let current_node = &table[current.parent];
- let folding = FoldingRange {
- start_line: current_node.end().line,
- start_character: Some(current_node.end().character),
- end_line: next_node.start().line - 1,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- };
- foldings.push(folding);
- }
- }
- }
- }
- foldings
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn nested() {
- let actual_foldings = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \section{Foo}
- foo
- \subsection{Bar}
- bar
- \section{Baz}
- baz
- \section{Qux}
- "#
- ),
- )
- .main("main.tex")
- .test_folding(LatexSectionFoldingProvider)
- .await;
-
- let expected_foldings = vec![
- FoldingRange {
- start_line: 0,
- start_character: Some(13),
- end_line: 3,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- },
- FoldingRange {
- start_line: 2,
- start_character: Some(16),
- end_line: 3,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- },
- FoldingRange {
- start_line: 4,
- start_character: Some(13),
- end_line: 5,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- },
- ];
-
- assert_eq!(actual_foldings, expected_foldings);
- }
-
- #[tokio::test]
- async fn bibtex() {
- let actual_foldings = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_folding(LatexSectionFoldingProvider)
- .await;
-
- assert!(actual_foldings.is_empty());
- }
-}
diff --git a/support/texlab/src/folding/mod.rs b/support/texlab/src/folding/mod.rs
deleted file mode 100644
index 448e3d26fc..0000000000
--- a/support/texlab/src/folding/mod.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-mod bibtex_decl;
-mod latex_env;
-mod latex_section;
-
-use self::{
- bibtex_decl::BibtexDeclarationFoldingProvider, latex_env::LatexEnvironmentFoldingProvider,
- latex_section::LatexSectionFoldingProvider,
-};
-use crate::{
- feature::{ConcatProvider, FeatureProvider, FeatureRequest},
- protocol::{FoldingRange, FoldingRangeParams},
-};
-use async_trait::async_trait;
-
-pub struct FoldingProvider {
- provider: ConcatProvider<FoldingRangeParams, FoldingRange>,
-}
-
-impl FoldingProvider {
- pub fn new() -> Self {
- Self {
- provider: ConcatProvider::new(vec![
- Box::new(BibtexDeclarationFoldingProvider),
- Box::new(LatexEnvironmentFoldingProvider),
- Box::new(LatexSectionFoldingProvider),
- ]),
- }
- }
-}
-
-impl Default for FoldingProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for FoldingProvider {
- type Params = FoldingRangeParams;
- type Output = Vec<FoldingRange>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
diff --git a/support/texlab/src/forward_search.rs b/support/texlab/src/forward_search.rs
deleted file mode 100644
index a3911ed9f3..0000000000
--- a/support/texlab/src/forward_search.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-use crate::{
- protocol::{ForwardSearchResult, ForwardSearchStatus, Options, Uri},
- workspace::Snapshot,
-};
-use log::error;
-use std::{io, path::Path, process::Stdio};
-use tokio::process::Command;
-
-pub async fn search<'a>(
- snapshot: &'a Snapshot,
- tex_uri: &'a Uri,
- line_number: u64,
- options: &Options,
- current_dir: &'a Path,
-) -> Option<ForwardSearchResult> {
- let pdf_path = snapshot
- .resolve_aux_targets(
- &snapshot.parent_subfile(tex_uri, options, current_dir)?.uri,
- options,
- current_dir,
- "pdf",
- )?
- .into_iter()
- .filter(|uri| uri.scheme() == "file")
- .filter_map(|uri| uri.to_file_path().ok())
- .find(|path| path.exists())?;
-
- if tex_uri.scheme() != "file" {
- return Some(ForwardSearchResult {
- status: ForwardSearchStatus::Failure,
- });
- }
-
- let search_options = options
- .latex
- .as_ref()
- .and_then(|opts| opts.forward_search.as_ref())
- .map(Clone::clone)
- .unwrap_or_default();
-
- if search_options.executable.is_none() || search_options.args.is_none() {
- return Some(ForwardSearchResult {
- status: ForwardSearchStatus::Unconfigured,
- });
- }
-
- let tex_path = tex_uri.to_file_path().ok()?;
- let args: Vec<String> = search_options
- .args
- .unwrap()
- .into_iter()
- .flat_map(|arg| replace_placeholder(&tex_path, &pdf_path, line_number, arg))
- .collect();
-
- let status = match spawn_process(search_options.executable.unwrap(), args).await {
- Ok(()) => ForwardSearchStatus::Success,
- Err(why) => {
- error!("Unable to execute forward search: {}", why);
- ForwardSearchStatus::Failure
- }
- };
- Some(ForwardSearchResult { status })
-}
-
-fn replace_placeholder(
- tex_file: &Path,
- pdf_file: &Path,
- line_number: u64,
- argument: String,
-) -> Option<String> {
- let result = if argument.starts_with('"') || argument.ends_with('"') {
- argument
- } else {
- argument
- .replace("%f", tex_file.to_str()?)
- .replace("%p", pdf_file.to_str()?)
- .replace("%l", &(line_number + 1).to_string())
- };
- Some(result)
-}
-
-async fn spawn_process(executable: String, args: Vec<String>) -> io::Result<()> {
- Command::new(executable)
- .args(args)
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .spawn()?
- .await?;
- Ok(())
-}
diff --git a/support/texlab/src/highlight/latex_label.rs b/support/texlab/src/highlight/latex_label.rs
deleted file mode 100644
index c6d4aab6ee..0000000000
--- a/support/texlab/src/highlight/latex_label.rs
+++ /dev/null
@@ -1,109 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{DocumentHighlight, DocumentHighlightKind, RangeExt, TextDocumentPositionParams},
- syntax::{latex, LatexLabelKind, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexLabelHighlightProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexLabelHighlightProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<DocumentHighlight>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut highlights = Vec::new();
- if let DocumentContent::Latex(table) = &req.current().content {
- if let Some(name) = table
- .labels
- .iter()
- .flat_map(|label| label.names(&table))
- .find(|label| label.range().contains(req.params.position))
- .map(latex::Token::text)
- {
- for label_group in &table.labels {
- for label in label_group.names(&table) {
- if label.text() == name {
- let kind = match label_group.kind {
- LatexLabelKind::Definition => DocumentHighlightKind::Write,
- LatexLabelKind::Reference(_) => DocumentHighlightKind::Read,
- };
-
- let highlight = DocumentHighlight {
- range: label.range(),
- kind: Some(kind),
- };
- highlights.push(highlight);
- }
- }
- }
- }
- }
- highlights
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn has_label() {
- let actual_highlights = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \label{foo}
- \ref{foo}
- "#
- ),
- )
- .main("foo.tex")
- .position(0, 7)
- .test_position(LatexLabelHighlightProvider)
- .await;
-
- let expected_highlights = vec![
- DocumentHighlight {
- range: Range::new_simple(0, 7, 0, 10),
- kind: Some(DocumentHighlightKind::Write),
- },
- DocumentHighlight {
- range: Range::new_simple(1, 5, 1, 8),
- kind: Some(DocumentHighlightKind::Read),
- },
- ];
-
- assert_eq!(actual_highlights, expected_highlights);
- }
-
- #[tokio::test]
- async fn no_label_latex() {
- let actual_highlights = FeatureTester::new()
- .file("foo.tex", "")
- .main("foo.tex")
- .position(0, 0)
- .test_position(LatexLabelHighlightProvider)
- .await;
-
- assert!(actual_highlights.is_empty());
- }
-
- #[tokio::test]
- async fn no_label_bibtex() {
- let actual_highlights = FeatureTester::new()
- .file("foo.bib", "")
- .main("foo.bib")
- .position(0, 0)
- .test_position(LatexLabelHighlightProvider)
- .await;
-
- assert!(actual_highlights.is_empty());
- }
-}
diff --git a/support/texlab/src/highlight/mod.rs b/support/texlab/src/highlight/mod.rs
deleted file mode 100644
index e47a7f99c2..0000000000
--- a/support/texlab/src/highlight/mod.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-mod latex_label;
-
-use self::latex_label::LatexLabelHighlightProvider;
-use crate::{
- feature::{ConcatProvider, FeatureProvider, FeatureRequest},
- protocol::{DocumentHighlight, TextDocumentPositionParams},
-};
-use async_trait::async_trait;
-
-pub struct HighlightProvider {
- provider: ConcatProvider<TextDocumentPositionParams, DocumentHighlight>,
-}
-
-impl HighlightProvider {
- pub fn new() -> Self {
- Self {
- provider: ConcatProvider::new(vec![Box::new(LatexLabelHighlightProvider)]),
- }
- }
-}
-
-impl Default for HighlightProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for HighlightProvider {
- type Params = TextDocumentPositionParams;
- type Output = Vec<DocumentHighlight>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
diff --git a/support/texlab/src/hover/bibtex/entry_type.rs b/support/texlab/src/hover/bibtex/entry_type.rs
deleted file mode 100644
index 1e009565d7..0000000000
--- a/support/texlab/src/hover/bibtex/entry_type.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- Hover, HoverContents, MarkupContent, MarkupKind, RangeExt, TextDocumentPositionParams,
- },
- syntax::{SyntaxNode, LANGUAGE_DATA},
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexEntryTypeHoverProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexEntryTypeHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let tree = req.current().content.as_bibtex()?;
- for entry in tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- {
- if entry.ty.range().contains(req.params.position) {
- let ty = &entry.ty.text()[1..];
- let docs = LANGUAGE_DATA.entry_type_documentation(ty)?;
- return Some(Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: docs.into(),
- }),
- range: Some(entry.ty.range()),
- });
- }
- }
- None
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(BibtexEntryTypeHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(BibtexEntryTypeHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn known_entry_type() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "@article{foo,}")
- .main("main.bib")
- .position(0, 3)
- .test_position(BibtexEntryTypeHoverProvider)
- .await
- .unwrap();
-
- let expected_hover = Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: LANGUAGE_DATA
- .entry_type_documentation("article")
- .unwrap()
- .into(),
- }),
- range: Some(Range::new_simple(0, 0, 0, 8)),
- };
-
- assert_eq!(actual_hover, expected_hover);
- }
-
- #[tokio::test]
- async fn unknown_entry_type() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "@foo{bar,}")
- .main("main.bib")
- .position(0, 3)
- .test_position(BibtexEntryTypeHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn entry_key() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "@article{foo,}")
- .main("main.bib")
- .position(0, 11)
- .test_position(BibtexEntryTypeHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-}
diff --git a/support/texlab/src/hover/bibtex/field.rs b/support/texlab/src/hover/bibtex/field.rs
deleted file mode 100644
index 4b00f3364c..0000000000
--- a/support/texlab/src/hover/bibtex/field.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- Hover, HoverContents, MarkupContent, MarkupKind, RangeExt, TextDocumentPositionParams,
- },
- syntax::{SyntaxNode, LANGUAGE_DATA},
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexFieldHoverProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexFieldHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let tree = req.current().content.as_bibtex()?;
- let name = tree
- .find(req.params.position)
- .into_iter()
- .filter_map(|node| tree.as_field(node))
- .map(|field| &field.name)
- .find(|name| name.range().contains(req.params.position))?;
-
- let docs = LANGUAGE_DATA.field_documentation(name.text())?;
- Some(Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: docs.into(),
- }),
- range: Some(name.range()),
- })
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(BibtexFieldHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(BibtexFieldHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn known_field() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "@article{foo, author = bar}")
- .main("main.bib")
- .position(0, 15)
- .test_position(BibtexFieldHoverProvider)
- .await
- .unwrap();
-
- let expected_hover = Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: LANGUAGE_DATA.field_documentation("author").unwrap().into(),
- }),
- range: Some(Range::new_simple(0, 14, 0, 20)),
- };
-
- assert_eq!(actual_hover, expected_hover);
- }
-
- #[tokio::test]
- async fn unknown_field() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "@article{foo, bar = baz}")
- .main("main.bib")
- .position(0, 15)
- .test_position(BibtexFieldHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn entry_key() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "@article{foo, bar = baz}")
- .main("main.bib")
- .position(0, 11)
- .test_position(BibtexFieldHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-}
diff --git a/support/texlab/src/hover/bibtex/mod.rs b/support/texlab/src/hover/bibtex/mod.rs
deleted file mode 100644
index 59ff356fa0..0000000000
--- a/support/texlab/src/hover/bibtex/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub mod entry_type;
-pub mod field;
-pub mod string_reference;
diff --git a/support/texlab/src/hover/bibtex/string_reference.rs b/support/texlab/src/hover/bibtex/string_reference.rs
deleted file mode 100644
index 46724a4f60..0000000000
--- a/support/texlab/src/hover/bibtex/string_reference.rs
+++ /dev/null
@@ -1,165 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- BibtexFormattingOptions, Hover, HoverContents, MarkupContent, MarkupKind, Position,
- TextDocumentPositionParams,
- },
- syntax::{bibtex, SyntaxNode},
-};
-use async_trait::async_trait;
-use petgraph::graph::NodeIndex;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexStringReferenceHoverProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexStringReferenceHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let tree = req.current().content.as_bibtex()?;
- let reference = Self::find_reference(tree, req.params.position)?;
- for string_node in tree.children(tree.root) {
- let hover = Self::find_definition(tree, string_node, reference);
- if hover.is_some() {
- return hover;
- }
- }
- None
- }
-}
-
-impl BibtexStringReferenceHoverProvider {
- fn find_reference(tree: &bibtex::Tree, pos: Position) -> Option<&bibtex::Token> {
- let mut results = tree.find(pos);
- results.reverse();
- match (
- &tree.graph[results[0]],
- results.get(1).map(|node| &tree.graph[*node]),
- ) {
- (bibtex::Node::Word(reference), Some(bibtex::Node::Concat(_))) => {
- Some(&reference.token)
- }
- (bibtex::Node::Word(reference), Some(bibtex::Node::Field(_))) => Some(&reference.token),
- _ => None,
- }
- }
-
- fn find_definition(
- tree: &bibtex::Tree,
- string_node: NodeIndex,
- reference: &bibtex::Token,
- ) -> Option<Hover> {
- let string = tree.as_string(string_node)?;
- if string.name.as_ref()?.text() != reference.text() {
- return None;
- }
-
- let options = BibtexFormattingOptions {
- line_length: None,
- formatter: None,
- };
- let text = bibtex::format(
- tree,
- tree.children(string_node).next()?,
- bibtex::FormattingParams {
- tab_size: 4,
- insert_spaces: true,
- options: &options,
- },
- );
- Some(Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::PlainText,
- value: text,
- }),
- range: Some(reference.range()),
- })
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(BibtexStringReferenceHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(BibtexStringReferenceHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn inside_reference() {
- let actual_hover = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = "Foo"}
- @string{bar = "Bar"}
- @article{baz, author = bar}
- "#
- ),
- )
- .main("main.bib")
- .position(2, 24)
- .test_position(BibtexStringReferenceHoverProvider)
- .await
- .unwrap();
-
- let expected_hover = Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::PlainText,
- value: "\"Bar\"".into(),
- }),
- range: Some(Range::new_simple(2, 23, 2, 26)),
- };
-
- assert_eq!(actual_hover, expected_hover);
- }
-
- #[tokio::test]
- async fn outside_reference() {
- let actual_hover = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = "Foo"}
- @string{bar = "Bar"}
- @article{baz, author = bar}
- "#
- ),
- )
- .main("main.bib")
- .position(2, 20)
- .test_position(BibtexStringReferenceHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-}
diff --git a/support/texlab/src/hover/latex/citation.rs b/support/texlab/src/hover/latex/citation.rs
deleted file mode 100644
index 8b5468e52e..0000000000
--- a/support/texlab/src/hover/latex/citation.rs
+++ /dev/null
@@ -1,179 +0,0 @@
-use crate::{
- citeproc::render_citation,
- feature::{FeatureProvider, FeatureRequest},
- protocol::{Hover, HoverContents, RangeExt, TextDocumentPositionParams},
- syntax::{bibtex, Span, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use log::warn;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexCitationHoverProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexCitationHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let (tree, src_key, entry) = Self::get_entry(req)?;
- if entry.is_comment() {
- None
- } else {
- let key = entry.key.as_ref()?;
- match render_citation(&tree, key.text()) {
- Some(markdown) => Some(Hover {
- contents: HoverContents::Markup(markdown),
- range: Some(src_key.range()),
- }),
- None => {
- warn!("Failed to render entry: {}", key.text());
- None
- }
- }
- }
- }
-}
-
-impl LatexCitationHoverProvider {
- fn get_entry(
- req: &FeatureRequest<TextDocumentPositionParams>,
- ) -> Option<(&bibtex::Tree, &Span, &bibtex::Entry)> {
- let key = Self::get_key(req)?;
- for tree in req
- .related()
- .iter()
- .filter_map(|doc| doc.content.as_bibtex())
- {
- for entry in tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- {
- if let Some(current_key) = &entry.key {
- if current_key.text() == key.text {
- return Some((tree, key, entry));
- }
- }
- }
- }
- None
- }
-
- fn get_key(req: &FeatureRequest<TextDocumentPositionParams>) -> Option<&Span> {
- match &req.current().content {
- DocumentContent::Latex(table) => table
- .citations
- .iter()
- .flat_map(|citation| citation.keys(&table))
- .find(|key| key.range().contains(req.params.position))
- .map(|token| &token.span),
- DocumentContent::Bibtex(tree) => tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- .filter_map(|entry| entry.key.as_ref())
- .find(|key| key.range().contains(req.params.position))
- .map(|token| &token.span),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{MarkupContent, MarkupKind, Range, RangeExt},
- };
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(LatexCitationHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(LatexCitationHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn inside_label() {
- let actual_hover = FeatureTester::new()
- .file(
- "main.bib",
- "@article{foo, author = {Foo Bar}, title = {Baz Qux}, year = 1337}",
- )
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{foo}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 7)
- .test_position(LatexCitationHoverProvider)
- .await
- .unwrap();
-
- let expected_hover = Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Bar, F. (1337). *Baz Qux*.".into(),
- }),
- range: Some(Range::new_simple(1, 6, 1, 9)),
- };
-
- assert_eq!(actual_hover, expected_hover);
- }
-
- #[tokio::test]
- async fn inside_entry() {
- let actual_hover = FeatureTester::new()
- .file(
- "main.bib",
- "@article{foo, author = {Foo Bar}, title = {Baz Qux}, year = 1337}",
- )
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{foo}
- "#
- ),
- )
- .main("main.bib")
- .position(0, 11)
- .test_position(LatexCitationHoverProvider)
- .await
- .unwrap();
-
- let expected_hover = Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Bar, F. (1337). *Baz Qux*.".into(),
- }),
- range: Some(Range::new_simple(0, 9, 0, 12)),
- };
-
- assert_eq!(actual_hover, expected_hover);
- }
-}
diff --git a/support/texlab/src/hover/latex/component.rs b/support/texlab/src/hover/latex/component.rs
deleted file mode 100644
index 5285ec795a..0000000000
--- a/support/texlab/src/hover/latex/component.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-use crate::{
- components::COMPONENT_DATABASE,
- feature::{FeatureProvider, FeatureRequest},
- protocol::{Hover, HoverContents, RangeExt, TextDocumentPositionParams},
- syntax::{LatexIncludeKind, SyntaxNode},
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexComponentHoverProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexComponentHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let table = req.current().content.as_latex()?;
- for include in &table.includes {
- match include.kind {
- LatexIncludeKind::Package | LatexIncludeKind::Class => {
- for path in include.paths(&table) {
- if path.range().contains(req.params.position) {
- let docs = COMPONENT_DATABASE.documentation(path.text())?;
- return Some(Hover {
- contents: HoverContents::Markup(docs),
- range: Some(path.range()),
- });
- }
- }
- }
- _ => {}
- }
- }
- None
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(LatexComponentHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(LatexComponentHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn known_package() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", r#"\usepackage{amsmath}"#)
- .main("main.tex")
- .position(0, 15)
- .test_position(LatexComponentHoverProvider)
- .await
- .unwrap();
-
- assert_eq!(actual_hover.range.unwrap(), Range::new_simple(0, 12, 0, 19));
- }
-
- #[tokio::test]
- async fn unknown_class() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", r#"\documentclass{abcdefghijklmnop}"#)
- .main("main.tex")
- .position(0, 20)
- .test_position(LatexComponentHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-}
diff --git a/support/texlab/src/hover/latex/label.rs b/support/texlab/src/hover/latex/label.rs
deleted file mode 100644
index 66724d442b..0000000000
--- a/support/texlab/src/hover/latex/label.rs
+++ /dev/null
@@ -1,118 +0,0 @@
-use crate::{
- feature::{DocumentView, FeatureProvider, FeatureRequest},
- outline::{Outline, OutlineContext},
- protocol::{Hover, HoverContents, Position, RangeExt, TextDocumentPositionParams},
- syntax::{latex, LatexLabelKind, SyntaxNode},
- workspace::{Document, DocumentContent},
-};
-use async_trait::async_trait;
-use std::sync::Arc;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexLabelHoverProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexLabelHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let table = req.current().content.as_latex()?;
- let reference = Self::find_reference(table, req.params.position)?;
- let (doc, def) = Self::find_definition(&req.view, reference)?;
-
- let snapshot = Arc::clone(&req.view.snapshot);
- let view = DocumentView::analyze(snapshot, doc, &req.options, &req.current_dir);
- let outline = Outline::analyze(&view, &req.options, &req.current_dir);
- let outline_ctx = OutlineContext::parse(&view, &outline, def)?;
- let markup = outline_ctx.documentation();
- Some(Hover {
- contents: HoverContents::Markup(markup),
- range: Some(reference.range()),
- })
- }
-}
-
-impl LatexLabelHoverProvider {
- fn find_reference(table: &latex::SymbolTable, pos: Position) -> Option<&latex::Token> {
- for label in &table.labels {
- let names = label.names(&table);
- if names.len() == 1 && table[label.parent].range().contains(pos) {
- return Some(&label.names(&table)[0]);
- }
-
- for name in &names {
- if name.range().contains(pos) {
- return Some(name);
- }
- }
- }
- None
- }
-
- fn find_definition(
- view: &DocumentView,
- reference: &latex::Token,
- ) -> Option<(Arc<Document>, latex::Label)> {
- for doc in &view.related {
- if let DocumentContent::Latex(table) = &doc.content {
- for label in &table.labels {
- if label.kind == LatexLabelKind::Definition {
- for name in label.names(&table) {
- if name.text() == reference.text() {
- return Some((Arc::clone(&doc), *label));
- }
- }
- }
- }
- }
- }
- None
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_position(LatexLabelHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_hover = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_position(LatexLabelHoverProvider)
- .await;
-
- assert_eq!(actual_hover, None);
- }
-
- #[tokio::test]
- async fn section() {
- let actual_hover = FeatureTester::new()
- .file("main.tex", r#"\section{Foo}\label{sec:foo}"#)
- .main("main.tex")
- .position(0, 23)
- .test_position(LatexLabelHoverProvider)
- .await
- .unwrap();
-
- assert_eq!(actual_hover.range.unwrap(), Range::new_simple(0, 20, 0, 27));
- }
-}
diff --git a/support/texlab/src/hover/latex/mod.rs b/support/texlab/src/hover/latex/mod.rs
deleted file mode 100644
index c119bfc832..0000000000
--- a/support/texlab/src/hover/latex/mod.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[cfg(feature = "citation")]
-pub mod citation;
-
-pub mod component;
-pub mod label;
-pub mod preview;
diff --git a/support/texlab/src/hover/latex/preview.rs b/support/texlab/src/hover/latex/preview.rs
deleted file mode 100644
index 8d2ca00cb5..0000000000
--- a/support/texlab/src/hover/latex/preview.rs
+++ /dev/null
@@ -1,338 +0,0 @@
-use crate::{
- components::COMPONENT_DATABASE,
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- ClientCapabilitiesExt, Hover, HoverContents, MarkupContent, MarkupKind, Range, RangeExt,
- TextDocumentPositionParams,
- },
- syntax::{latex, CharStream, LatexIncludeKind, SyntaxNode},
- tex::{CompileError, CompileParams, DistributionKind, Format},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use image::{png::PNGEncoder, ColorType, DynamicImage, GenericImageView, ImageBuffer, RgbaImage};
-use io::Cursor;
-use log::warn;
-use std::{io, process::Stdio, time::Duration};
-use tempfile::TempDir;
-use thiserror::Error;
-use tokio::process::Command;
-
-const PREVIEW_ENVIRONMENTS: &[&str] = &[
- "align",
- "alignat",
- "aligned",
- "alignedat",
- "algorithmic",
- "array",
- "Bmatrix",
- "bmatrix",
- "cases",
- "CD",
- "eqnarray",
- "equation",
- "gather",
- "gathered",
- "matrix",
- "multline",
- "pmatrix",
- "smallmatrix",
- "split",
- "subarray",
- "Vmatrix",
- "vmatrix",
-];
-
-const IGNORED_PACKAGES: &[&str] = &["biblatex", "pgf", "tikz"];
-
-#[derive(Debug, Clone, Copy)]
-enum MathElement {
- Environment(latex::Environment),
- Equation(latex::Equation),
- Inline(latex::Inline),
-}
-
-impl MathElement {
- fn range(&self, tree: &latex::Tree) -> Range {
- match self {
- Self::Environment(env) => env.range(tree),
- Self::Equation(eq) => eq.range(tree),
- Self::Inline(inline) => inline.range(tree),
- }
- }
-}
-
-#[derive(Debug, Error)]
-enum RenderError {
- #[error("an I/O error occurred: `{0}`")]
- IO(#[from] io::Error),
- #[error("a compile error occurred: `{0}`")]
- Compile(#[from] CompileError),
- #[error("compilation failed")]
- DviNotFound,
- #[error("dvipng is not installed")]
- DviPngNotInstalled,
- #[error("calling dvipng failed")]
- DviPngFaulty,
- #[error("failed to decode image")]
- DecodeImage,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexPreviewHoverProvider;
-
-impl LatexPreviewHoverProvider {
- fn is_preview_environment(
- req: &FeatureRequest<TextDocumentPositionParams>,
- table: &latex::SymbolTable,
- environment: latex::Environment,
- ) -> bool {
- let canonical_name = environment
- .left
- .name(&table)
- .map(latex::Token::text)
- .unwrap_or_default()
- .replace('*', "");
-
- PREVIEW_ENVIRONMENTS.contains(&canonical_name.as_ref())
- || Self::theorem_environments(req).contains(&canonical_name.as_ref())
- }
-
- fn theorem_environments(req: &FeatureRequest<TextDocumentPositionParams>) -> Vec<&str> {
- let mut names = Vec::new();
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .theorem_definitions
- .iter()
- .map(|thm| thm.name(&table).text())
- .for_each(|thm| names.push(thm));
- }
- }
- names
- }
-
- async fn render(
- req: &FeatureRequest<TextDocumentPositionParams>,
- range: Range,
- ) -> Result<Hover, RenderError> {
- let code = Self::generate_code(req, range);
- let params = CompileParams {
- file_name: "preview.tex",
- code: &code,
- format: Format::Latex,
- timeout: Duration::from_secs(10),
- };
- let dir = req.distro.compile(params).await?.dir;
- if !dir.path().join("preview.dvi").exists() {
- return Err(RenderError::DviNotFound);
- }
-
- let img = Self::add_margin(Self::dvipng(&dir).await?);
- let base64 = Self::encode_image(img);
- let markdown = format!("![preview](data:image/png;base64,{})", base64);
- dir.close()?;
- Ok(Hover {
- contents: HoverContents::Markup(MarkupContent {
- kind: MarkupKind::Markdown,
- value: markdown,
- }),
- range: Some(range),
- })
- }
-
- fn generate_code(req: &FeatureRequest<TextDocumentPositionParams>, range: Range) -> String {
- let mut code = String::new();
- code.push_str("\\documentclass{article}\n");
- code.push_str("\\thispagestyle{empty}\n");
- Self::generate_includes(req, &mut code);
- Self::generate_command_definitions(req, &mut code);
- Self::generate_math_operators(req, &mut code);
- Self::generate_theorem_definitions(req, &mut code);
- code.push_str("\\begin{document}\n");
- code.push_str(&CharStream::extract(&req.current().text, range));
- code.push('\n');
- code.push_str("\\end{document}\n");
- code
- }
-
- fn generate_includes(req: &FeatureRequest<TextDocumentPositionParams>, code: &mut String) {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- let text = &doc.text;
- for include in &table.includes {
- if include.kind == LatexIncludeKind::Package {
- if include
- .paths(&table)
- .iter()
- .all(|path| IGNORED_PACKAGES.contains(&path.text()))
- {
- continue;
- }
-
- if include
- .paths(&table)
- .iter()
- .map(|path| format!("{}.sty", path.text()))
- .any(|name| !COMPONENT_DATABASE.exists(&name))
- {
- continue;
- }
-
- code.push_str(&CharStream::extract(&text, table[include.parent].range()));
- code.push('\n');
- }
- }
- }
- }
- }
-
- fn generate_command_definitions(
- req: &FeatureRequest<TextDocumentPositionParams>,
- code: &mut String,
- ) {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .command_definitions
- .iter()
- .filter(|def| !def.definition_name(&table).contains("@"))
- .map(|def| CharStream::extract(&doc.text, table[def.parent].range()))
- .for_each(|def| {
- code.push_str(&def);
- code.push('\n');
- });
- }
- }
- }
-
- fn generate_math_operators(
- req: &FeatureRequest<TextDocumentPositionParams>,
- code: &mut String,
- ) {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .math_operators
- .iter()
- .filter(|op| !op.definition_name(&table).contains("@"))
- .map(|op| CharStream::extract(&doc.text, table[op.parent].range()))
- .for_each(|op| {
- code.push_str(&op);
- code.push('\n');
- });
- }
- }
- }
-
- fn generate_theorem_definitions(
- req: &FeatureRequest<TextDocumentPositionParams>,
- code: &mut String,
- ) {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .theorem_definitions
- .iter()
- .map(|thm| CharStream::extract(&doc.text, table[thm.parent].range()))
- .for_each(|thm| {
- code.push_str(&thm);
- code.push('\n');
- })
- }
- }
- }
-
- async fn dvipng(dir: &TempDir) -> Result<DynamicImage, RenderError> {
- let process = Command::new("dvipng")
- .args(&["-D", "175", "-T", "tight", "preview.dvi"])
- .current_dir(dir.path())
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .spawn()
- .map_err(|_| RenderError::DviPngNotInstalled)?;
-
- process.await.map_err(|_| RenderError::DviPngFaulty)?;
-
- let png_file = dir.path().join("preview1.png");
- let png = image::open(png_file).map_err(|_| RenderError::DecodeImage)?;
- Ok(png)
- }
-
- fn add_margin(image: DynamicImage) -> RgbaImage {
- let margin = 5;
- let width = image.width() + 2 * margin;
- let height = image.height() + 2 * margin;
- let mut result =
- ImageBuffer::from_pixel(width, height, image::Rgba([0xFF, 0xFF, 0xFF, 0xFF]));
-
- for x in 0..image.width() {
- for y in 0..image.height() {
- let pixel = image.get_pixel(x, y);
- result.put_pixel(x + margin, y + margin, pixel);
- }
- }
- result
- }
-
- fn encode_image(image: RgbaImage) -> String {
- let mut image_buf = Cursor::new(Vec::new());
- let png_encoder = PNGEncoder::new(&mut image_buf);
- let width = image.width();
- let height = image.height();
- png_encoder
- .encode(&image.into_raw(), width, height, ColorType::Rgba8)
- .unwrap();
- base64::encode(&image_buf.into_inner())
- }
-}
-
-#[async_trait]
-impl FeatureProvider for LatexPreviewHoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- if !req.client_capabilities.has_hover_markdown_support()
- || req.distro.kind() == DistributionKind::Tectonic
- {
- return None;
- }
-
- if let DocumentContent::Latex(table) = &req.current().content {
- let mut elements = Vec::new();
- table
- .inlines
- .iter()
- .map(|inline| MathElement::Inline(*inline))
- .for_each(|inline| elements.push(inline));
-
- table
- .equations
- .iter()
- .map(|eq| MathElement::Equation(*eq))
- .for_each(|eq| elements.push(eq));
-
- table
- .environments
- .iter()
- .filter(|env| Self::is_preview_environment(req, table, **env))
- .map(|env| MathElement::Environment(*env))
- .for_each(|env| elements.push(env));
-
- let range = elements
- .iter()
- .map(|elem| elem.range(&table))
- .find(|range| range.contains(req.params.position))?;
-
- return match Self::render(req, range).await {
- Ok(hover) => Some(hover),
- Err(why) => {
- warn!("Preview failed: {}", why);
- None
- }
- };
- }
- None
- }
-}
diff --git a/support/texlab/src/hover/mod.rs b/support/texlab/src/hover/mod.rs
deleted file mode 100644
index e740657add..0000000000
--- a/support/texlab/src/hover/mod.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-mod bibtex;
-mod latex;
-
-#[cfg(feature = "citation")]
-use self::latex::citation::LatexCitationHoverProvider;
-
-use self::{
- bibtex::{
- entry_type::BibtexEntryTypeHoverProvider, field::BibtexFieldHoverProvider,
- string_reference::BibtexStringReferenceHoverProvider,
- },
- latex::{
- component::LatexComponentHoverProvider, label::LatexLabelHoverProvider,
- preview::LatexPreviewHoverProvider,
- },
-};
-use crate::{
- feature::{ChoiceProvider, FeatureProvider, FeatureRequest},
- protocol::{Hover, TextDocumentPositionParams},
-};
-use async_trait::async_trait;
-
-pub struct HoverProvider {
- provider: ChoiceProvider<TextDocumentPositionParams, Hover>,
-}
-
-impl HoverProvider {
- pub fn new() -> Self {
- Self {
- provider: ChoiceProvider::new(vec![
- Box::new(BibtexEntryTypeHoverProvider),
- Box::new(BibtexStringReferenceHoverProvider),
- Box::new(BibtexFieldHoverProvider),
- #[cfg(feature = "citation")]
- Box::new(LatexCitationHoverProvider),
- Box::new(LatexComponentHoverProvider),
- Box::new(LatexLabelHoverProvider),
- Box::new(LatexPreviewHoverProvider),
- ]),
- }
- }
-}
-
-impl Default for HoverProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for HoverProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Hover>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
diff --git a/support/texlab/src/label.rs b/support/texlab/src/label.rs
new file mode 100644
index 0000000000..eead07814e
--- /dev/null
+++ b/support/texlab/src/label.rs
@@ -0,0 +1,291 @@
+use std::str::FromStr;
+
+use cstree::TextRange;
+use lsp_types::{MarkupContent, MarkupKind};
+
+use crate::{
+ syntax::{
+ latex::{self, HasBrack, HasCurly},
+ CstNode,
+ },
+ WorkspaceSubset, LANGUAGE_DATA,
+};
+
+use self::LabelledObject::*;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum LabelledFloatKind {
+ Figure,
+ Table,
+ Listing,
+ Algorithm,
+}
+
+impl LabelledFloatKind {
+ pub fn as_str(self) -> &'static str {
+ match self {
+ Self::Figure => "Figure",
+ Self::Table => "Table",
+ Self::Listing => "Listing",
+ Self::Algorithm => "Algorithm",
+ }
+ }
+}
+
+impl FromStr for LabelledFloatKind {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "figure" | "subfigure" => Ok(Self::Figure),
+ "table" | "subtable" => Ok(Self::Table),
+ "listing" | "lstlisting" => Ok(Self::Listing),
+ "algorithm" => Ok(Self::Algorithm),
+ _ => Err(()),
+ }
+ }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum LabelledObject {
+ Section {
+ prefix: &'static str,
+ text: String,
+ },
+ Float {
+ kind: LabelledFloatKind,
+ caption: String,
+ },
+ Theorem {
+ kind: String,
+ description: Option<String>,
+ },
+ Equation,
+ EnumItem,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct RenderedLabel {
+ pub range: TextRange,
+ pub number: Option<String>,
+ pub object: LabelledObject,
+}
+
+impl RenderedLabel {
+ pub fn reference(&self) -> String {
+ match &self.number {
+ Some(number) => match &self.object {
+ Section { prefix, text } => format!("{} {} ({})", prefix, number, text),
+ Float { kind, caption } => format!("{} {}: {}", kind.as_str(), number, caption),
+ Theorem {
+ kind,
+ description: None,
+ } => format!("{} {}", kind, number),
+ Theorem {
+ kind,
+ description: Some(description),
+ } => format!("{} {} ({})", kind, number, description),
+ Equation => format!("Equation ({})", number),
+ EnumItem => format!("Item {}", number),
+ },
+ None => match &self.object {
+ Section { prefix, text } => format!("{} ({})", prefix, text),
+ Float { kind, caption } => format!("{}: {}", kind.as_str(), caption),
+ Theorem {
+ kind,
+ description: None,
+ } => kind.into(),
+ Theorem {
+ kind,
+ description: Some(description),
+ } => format!("{} ({})", kind, description),
+ Equation => "Equation".into(),
+ EnumItem => "Item".into(),
+ },
+ }
+ }
+
+ pub fn detail(&self) -> Option<String> {
+ match &self.object {
+ Section { .. } | Theorem { .. } | Equation | EnumItem => Some(self.reference()),
+ Float { kind, .. } => {
+ let result = match &self.number {
+ Some(number) => format!("{} {}", kind.as_str(), number),
+ None => kind.as_str().to_owned(),
+ };
+ Some(result)
+ }
+ }
+ }
+
+ pub fn documentation(&self) -> MarkupContent {
+ MarkupContent {
+ kind: MarkupKind::PlainText,
+ value: self.reference(),
+ }
+ }
+}
+
+pub fn render_label<'a>(
+ subset: &'a WorkspaceSubset,
+ label_name: &str,
+ mut label: Option<latex::LabelDefinition<'a>>,
+) -> Option<RenderedLabel> {
+ let mut number = find_label_number(subset, label_name).map(ToString::to_string);
+
+ for document in &subset.documents {
+ if let Some(data) = document.data.as_latex() {
+ label = label.or_else(|| find_label_definition(&data.root, label_name));
+ }
+ }
+
+ label?.syntax().ancestors().find_map(|parent| {
+ render_label_float(parent, &mut number)
+ .or_else(|| render_label_section(parent, &mut number))
+ .or_else(|| render_label_enum_item(parent, &mut number))
+ .or_else(|| render_label_equation(parent, &mut number))
+ .or_else(|| render_label_theorem(subset, parent, &mut number))
+ })
+}
+
+pub fn find_label_definition<'a>(
+ root: &'a latex::SyntaxNode,
+ label_name: &str,
+) -> Option<latex::LabelDefinition<'a>> {
+ root.descendants()
+ .filter_map(latex::LabelDefinition::cast)
+ .find(|label| {
+ label
+ .name()
+ .and_then(|name| name.word())
+ .map(|name| name.text())
+ == Some(label_name)
+ })
+}
+
+pub fn find_label_number<'a>(subset: &'a WorkspaceSubset, label_name: &str) -> Option<&'a str> {
+ subset.documents.iter().find_map(|document| {
+ document
+ .data
+ .as_latex()
+ .and_then(|data| data.extras.label_numbers_by_name.get(label_name))
+ .map(|number| number.as_str())
+ })
+}
+
+fn render_label_float(
+ parent: &latex::SyntaxNode,
+ number: &mut Option<String>,
+) -> Option<RenderedLabel> {
+ let environment = latex::Environment::cast(parent)?;
+ let environment_name = environment.begin()?.name()?.word()?.text();
+ let kind = LabelledFloatKind::from_str(&environment_name).ok()?;
+ let caption = find_caption_by_parent(&parent)?;
+ Some(RenderedLabel {
+ range: environment.small_range(),
+ number: number.take(),
+ object: LabelledObject::Float { caption, kind },
+ })
+}
+
+fn render_label_section(
+ parent: &latex::SyntaxNode,
+ number: &mut Option<String>,
+) -> Option<RenderedLabel> {
+ let section = latex::Section::cast(parent)?;
+ let text_group = section.name()?;
+ let text = text_group.content_text()?;
+
+ Some(RenderedLabel {
+ range: section.small_range(),
+ number: number.take(),
+ object: LabelledObject::Section {
+ prefix: match section.syntax().kind() {
+ latex::PART => "Part",
+ latex::CHAPTER => "Chapter",
+ latex::SECTION => "Section",
+ latex::SUBSECTION => "Subsection",
+ latex::SUBSUBSECTION => "Subsubsection",
+ latex::PARAGRAPH => "Paragraph",
+ latex::SUBPARAGRAPH => "Subparagraph",
+ _ => unreachable!(),
+ },
+ text,
+ },
+ })
+}
+
+fn render_label_enum_item(
+ parent: &latex::SyntaxNode,
+ number: &mut Option<String>,
+) -> Option<RenderedLabel> {
+ let enum_item = latex::EnumItem::cast(parent)?;
+ Some(RenderedLabel {
+ range: enum_item.small_range(),
+ number: enum_item
+ .label()
+ .and_then(|number| number.content_text())
+ .or_else(|| number.take()),
+ object: LabelledObject::EnumItem,
+ })
+}
+
+fn render_label_equation(
+ parent: &latex::SyntaxNode,
+ number: &mut Option<String>,
+) -> Option<RenderedLabel> {
+ let environment = latex::Environment::cast(parent)?;
+ let environment_name = environment.begin()?.name()?.word()?.text();
+
+ if !LANGUAGE_DATA
+ .math_environments
+ .iter()
+ .any(|name| name == environment_name)
+ {
+ return None;
+ }
+
+ Some(RenderedLabel {
+ range: environment.small_range(),
+ number: number.take(),
+ object: LabelledObject::Equation,
+ })
+}
+
+fn render_label_theorem(
+ subset: &WorkspaceSubset,
+ parent: &latex::SyntaxNode,
+ number: &mut Option<String>,
+) -> Option<RenderedLabel> {
+ let environment = latex::Environment::cast(parent)?;
+ let begin = environment.begin()?;
+ let description = begin.options().and_then(|options| options.content_text());
+
+ let environment_name = begin.name()?.word()?.text();
+
+ let theorem = subset.documents.iter().find_map(|document| {
+ document.data.as_latex().and_then(|data| {
+ data.extras
+ .theorem_environments
+ .iter()
+ .find(|theorem| theorem.name.as_str() == environment_name)
+ })
+ })?;
+
+ Some(RenderedLabel {
+ range: environment.small_range(),
+ number: number.take(),
+ object: LabelledObject::Theorem {
+ kind: theorem.description.clone(),
+ description,
+ },
+ })
+}
+
+pub fn find_caption_by_parent(parent: &latex::SyntaxNode) -> Option<String> {
+ parent
+ .children()
+ .filter_map(latex::Caption::cast)
+ .find_map(|node| node.long())
+ .and_then(|node| node.content_text())
+}
diff --git a/support/texlab/src/lang_data.rs b/support/texlab/src/lang_data.rs
new file mode 100644
index 0000000000..9aa939c483
--- /dev/null
+++ b/support/texlab/src/lang_data.rs
@@ -0,0 +1,67 @@
+use once_cell::sync::Lazy;
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub enum BibtexEntryTypeCategory {
+ Misc,
+ String,
+ Article,
+ Book,
+ Collection,
+ Part,
+ Thesis,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct BibtexEntryTypeDoc {
+ pub name: String,
+ pub category: BibtexEntryTypeCategory,
+ pub documentation: Option<String>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct BibtexFieldDoc {
+ pub name: String,
+ pub documentation: String,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct LanguageData {
+ pub colors: Vec<String>,
+ pub entry_types: Vec<BibtexEntryTypeDoc>,
+ pub fields: Vec<BibtexFieldDoc>,
+ pub pgf_libraries: Vec<String>,
+ pub tikz_libraries: Vec<String>,
+ pub math_environments: Vec<String>,
+ pub enum_environments: Vec<String>,
+}
+
+impl LanguageData {
+ pub fn find_entry_type(&self, name: &str) -> Option<&BibtexEntryTypeDoc> {
+ let name = name.to_lowercase();
+ self.entry_types
+ .iter()
+ .find(|ty| ty.name.to_lowercase() == name)
+ }
+
+ pub fn entry_type_documentation(&self, name: &str) -> Option<&str> {
+ self.find_entry_type(name)
+ .and_then(|ty| ty.documentation.as_ref().map(AsRef::as_ref))
+ }
+
+ pub fn field_documentation(&self, name: &str) -> Option<&str> {
+ self.fields
+ .iter()
+ .find(|field| field.name.to_lowercase() == name.to_lowercase())
+ .map(|field| field.documentation.as_ref())
+ }
+}
+
+pub static LANGUAGE_DATA: Lazy<LanguageData> = Lazy::new(|| {
+ const JSON: &str = include_str!("../data/lang_data.json");
+ serde_json::from_str(JSON).expect("Failed to deserialize language.json")
+});
diff --git a/support/texlab/src/language.rs b/support/texlab/src/language.rs
new file mode 100644
index 0000000000..45ef22daba
--- /dev/null
+++ b/support/texlab/src/language.rs
@@ -0,0 +1,33 @@
+use std::{ffi::OsStr, path::Path};
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
+pub enum DocumentLanguage {
+ Latex,
+ Bibtex,
+ BuildLog,
+}
+
+impl DocumentLanguage {
+ pub fn by_path(path: &Path) -> Option<Self> {
+ path.extension()
+ .and_then(OsStr::to_str)
+ .and_then(Self::by_extension)
+ }
+
+ pub fn by_extension(extension: &str) -> Option<Self> {
+ match extension.to_lowercase().as_str() {
+ "tex" | "sty" | "cls" | "def" | "lco" | "aux" | "rnw" => Some(Self::Latex),
+ "bib" | "bibtex" => Some(Self::Bibtex),
+ "log" => Some(Self::BuildLog),
+ _ => None,
+ }
+ }
+
+ pub fn by_language_id(language_id: &str) -> Option<Self> {
+ match language_id {
+ "latex" | "tex" => Some(Self::Latex),
+ "bibtex" | "bib" => Some(Self::Bibtex),
+ _ => None,
+ }
+ }
+}
diff --git a/support/texlab/src/lib.rs b/support/texlab/src/lib.rs
index 8644a40f10..0441c1a1d7 100644
--- a/support/texlab/src/lib.rs
+++ b/support/texlab/src/lib.rs
@@ -1,33 +1,38 @@
+mod capabilities;
#[cfg(feature = "citation")]
-pub mod citeproc;
-
-#[cfg(feature = "test")]
-pub mod test;
-
-cfg_if::cfg_if! {
- if #[cfg(feature = "server")] {
- mod config;
- mod build;
-
- pub mod server;
- }
-}
-
-pub mod completion;
-pub mod components;
-pub mod definition;
+pub mod citation;
+mod client;
+pub mod component_db;
+mod config;
+mod context;
pub mod diagnostics;
-pub mod feature;
-pub mod folding;
-pub mod forward_search;
-pub mod highlight;
-pub mod hover;
-pub mod link;
-pub mod outline;
-pub mod protocol;
-pub mod reference;
-pub mod rename;
-pub mod symbol;
+mod dispatch;
+pub mod distro;
+pub mod features;
+mod label;
+mod lang_data;
+mod language;
+mod line_index;
+mod line_index_ext;
+mod options;
+mod range;
+mod req_queue;
+mod server;
pub mod syntax;
-pub mod tex;
-pub mod workspace;
+mod uri;
+mod workspace;
+
+pub use self::{
+ capabilities::ClientCapabilitiesExt,
+ context::ServerContext,
+ label::*,
+ lang_data::*,
+ language::DocumentLanguage,
+ line_index::{LineCol, LineColUtf16, LineIndex},
+ line_index_ext::LineIndexExt,
+ options::*,
+ range::RangeExt,
+ server::Server,
+ uri::Uri,
+ workspace::*,
+};
diff --git a/support/texlab/src/line_index.rs b/support/texlab/src/line_index.rs
new file mode 100644
index 0000000000..868fe41232
--- /dev/null
+++ b/support/texlab/src/line_index.rs
@@ -0,0 +1,217 @@
+// The following code has been copied from rust-analyzer.
+
+//! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)`
+//! representation.
+use std::iter;
+
+use cstree::{TextRange, TextSize};
+use rustc_hash::FxHashMap;
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct LineIndex {
+ /// Offset the the beginning of each line, zero-based
+ pub(crate) newlines: Vec<TextSize>,
+ /// List of non-ASCII characters on each line
+ pub(crate) utf16_lines: FxHashMap<u32, Vec<Utf16Char>>,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct LineColUtf16 {
+ /// Zero-based
+ pub line: u32,
+ /// Zero-based
+ pub col: u32,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct LineCol {
+ /// Zero-based
+ pub line: u32,
+ /// Zero-based utf8 offset
+ pub col: u32,
+}
+
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+pub(crate) struct Utf16Char {
+ /// Start offset of a character inside a line, zero-based
+ pub(crate) start: TextSize,
+ /// End offset of a character inside a line, zero-based
+ pub(crate) end: TextSize,
+}
+
+impl Utf16Char {
+ /// Returns the length in 8-bit UTF-8 code units.
+ fn len(&self) -> TextSize {
+ self.end - self.start
+ }
+
+ /// Returns the length in 16-bit UTF-16 code units.
+ fn len_utf16(&self) -> usize {
+ if self.len() == TextSize::from(4) {
+ 2
+ } else {
+ 1
+ }
+ }
+}
+
+impl LineIndex {
+ pub fn new(text: &str) -> LineIndex {
+ let mut utf16_lines = FxHashMap::default();
+ let mut utf16_chars = Vec::new();
+
+ let mut newlines = vec![0.into()];
+ let mut curr_row = 0.into();
+ let mut curr_col = 0.into();
+ let mut line = 0;
+ for c in text.chars() {
+ let c_len = TextSize::of(c);
+ curr_row += c_len;
+ if c == '\n' {
+ newlines.push(curr_row);
+
+ // Save any utf-16 characters seen in the previous line
+ if !utf16_chars.is_empty() {
+ utf16_lines.insert(line, utf16_chars);
+ utf16_chars = Vec::new();
+ }
+
+ // Prepare for processing the next line
+ curr_col = 0.into();
+ line += 1;
+ continue;
+ }
+
+ if !c.is_ascii() {
+ utf16_chars.push(Utf16Char {
+ start: curr_col,
+ end: curr_col + c_len,
+ });
+ }
+
+ curr_col += c_len;
+ }
+
+ // Save any utf-16 characters seen in the last line
+ if !utf16_chars.is_empty() {
+ utf16_lines.insert(line, utf16_chars);
+ }
+
+ LineIndex {
+ newlines,
+ utf16_lines,
+ }
+ }
+
+ pub fn line_col(&self, offset: TextSize) -> LineCol {
+ let line = partition_point(&self.newlines, |&it| it <= offset) - 1;
+ let line_start_offset = self.newlines[line];
+ let col = offset - line_start_offset;
+ LineCol {
+ line: line as u32,
+ col: col.into(),
+ }
+ }
+
+ pub fn offset(&self, line_col: LineCol) -> TextSize {
+ self.newlines[line_col.line as usize] + TextSize::from(line_col.col)
+ }
+
+ pub fn to_utf16(&self, line_col: LineCol) -> LineColUtf16 {
+ let col = self.utf8_to_utf16_col(line_col.line, line_col.col.into());
+ LineColUtf16 {
+ line: line_col.line,
+ col: col as u32,
+ }
+ }
+
+ pub fn to_utf8(&self, line_col: LineColUtf16) -> LineCol {
+ let col = self.utf16_to_utf8_col(line_col.line, line_col.col);
+ LineCol {
+ line: line_col.line,
+ col: col.into(),
+ }
+ }
+
+ pub fn lines(&self, range: TextRange) -> impl Iterator<Item = TextRange> + '_ {
+ let lo = partition_point(&self.newlines, |&it| it < range.start());
+ let hi = partition_point(&self.newlines, |&it| it <= range.end());
+ let all = iter::once(range.start())
+ .chain(self.newlines[lo..hi].iter().copied())
+ .chain(iter::once(range.end()));
+
+ all.clone()
+ .zip(all.skip(1))
+ .map(|(lo, hi)| TextRange::new(lo, hi))
+ .filter(|it| !it.is_empty())
+ }
+
+ fn utf8_to_utf16_col(&self, line: u32, col: TextSize) -> usize {
+ let mut res: usize = col.into();
+ if let Some(utf16_chars) = self.utf16_lines.get(&line) {
+ for c in utf16_chars {
+ if c.end <= col {
+ res -= usize::from(c.len()) - c.len_utf16();
+ } else {
+ // From here on, all utf16 characters come *after* the character we are mapping,
+ // so we don't need to take them into account
+ break;
+ }
+ }
+ }
+ res
+ }
+
+ fn utf16_to_utf8_col(&self, line: u32, mut col: u32) -> TextSize {
+ if let Some(utf16_chars) = self.utf16_lines.get(&line) {
+ for c in utf16_chars {
+ if col > u32::from(c.start) {
+ col += u32::from(c.len()) - c.len_utf16() as u32;
+ } else {
+ // From here on, all utf16 characters come *after* the character we are mapping,
+ // so we don't need to take them into account
+ break;
+ }
+ }
+ }
+
+ col.into()
+ }
+}
+
+/// Returns `idx` such that:
+///
+/// ```text
+/// ∀ x in slice[..idx]: pred(x)
+/// && ∀ x in slice[idx..]: !pred(x)
+/// ```
+///
+/// https://github.com/rust-lang/rust/issues/73831
+fn partition_point<T, P>(slice: &[T], mut pred: P) -> usize
+where
+ P: FnMut(&T) -> bool,
+{
+ let mut left = 0;
+ let mut right = slice.len();
+
+ while left != right {
+ let mid = left + (right - left) / 2;
+ // SAFETY:
+ // When left < right, left <= mid < right.
+ // Therefore left always increases and right always decreases,
+ // and either of them is selected.
+ // In both cases left <= right is satisfied.
+ // Therefore if left < right in a step,
+ // left <= right is satisfied in the next step.
+ // Therefore as long as left != right, 0 <= left < right <= len is satisfied
+ // and if this case 0 <= mid < len is satisfied too.
+ let value = unsafe { slice.get_unchecked(mid) };
+ if pred(value) {
+ left = mid + 1;
+ } else {
+ right = mid;
+ }
+ }
+
+ left
+} \ No newline at end of file
diff --git a/support/texlab/src/line_index_ext.rs b/support/texlab/src/line_index_ext.rs
new file mode 100644
index 0000000000..8e28207edd
--- /dev/null
+++ b/support/texlab/src/line_index_ext.rs
@@ -0,0 +1,42 @@
+use cstree::{TextRange, TextSize};
+use lsp_types::{Position, Range};
+
+use crate::{LineColUtf16, LineIndex};
+
+pub trait LineIndexExt {
+ fn offset_lsp(&self, line_col: Position) -> TextSize;
+
+ fn offset_lsp_range(&self, line_col: Range) -> TextRange;
+
+ fn line_col_lsp(&self, offset: TextSize) -> Position;
+
+ fn line_col_lsp_range(&self, offset: TextRange) -> Range;
+}
+
+impl LineIndexExt for LineIndex {
+ fn offset_lsp(&self, line_col: Position) -> TextSize {
+ let line_col = LineColUtf16 {
+ line: line_col.line,
+ col: line_col.character,
+ };
+ self.offset(self.to_utf8(line_col))
+ }
+
+ fn offset_lsp_range(&self, line_col: Range) -> TextRange {
+ let start = self.offset_lsp(line_col.start);
+ let end = self.offset_lsp(line_col.end);
+ TextRange::new(start, end)
+ }
+
+ fn line_col_lsp(&self, offset: TextSize) -> Position {
+ let position = self.line_col(offset);
+ let LineColUtf16 { line , col } = self.to_utf16(position);
+ Position::new(line, col)
+ }
+
+ fn line_col_lsp_range(&self, offset: TextRange) -> Range {
+ let start = self.line_col_lsp(offset.start());
+ let end = self.line_col_lsp(offset.end());
+ Range::new(start, end)
+ }
+}
diff --git a/support/texlab/src/link/latex_import.rs b/support/texlab/src/link/latex_import.rs
deleted file mode 100644
index 494a72b481..0000000000
--- a/support/texlab/src/link/latex_import.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{DocumentLink, DocumentLinkParams},
- syntax::{latex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexImportLinkProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexImportLinkProvider {
- type Params = DocumentLinkParams;
- type Output = Vec<DocumentLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- if let DocumentContent::Latex(table) = &req.current().content {
- table
- .imports
- .iter()
- .flat_map(|import| Self::resolve(req, table, import))
- .collect()
- } else {
- Vec::new()
- }
- }
-}
-
-impl LatexImportLinkProvider {
- fn resolve(
- req: &FeatureRequest<DocumentLinkParams>,
- table: &latex::SymbolTable,
- import: &latex::Import,
- ) -> Vec<DocumentLink> {
- let mut links = Vec::new();
- let file = import.file(&table);
- for target in &import.targets {
- if let Some(link) = req.snapshot().find(target).map(|doc| DocumentLink {
- range: file.range(),
- target: doc.uri.clone().into(),
- tooltip: None,
- }) {
- links.push(link);
- break;
- }
- }
- links
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document_command() {
- let actual_links = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .test_link(LatexImportLinkProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_command() {
- let actual_links = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_link(LatexImportLinkProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn has_links() {
- let actual_links = FeatureTester::new()
- .file("foo.tex", r#"\import{bar/}{baz}"#)
- .file("bar/baz.tex", r#""#)
- .main("foo.tex")
- .test_link(LatexImportLinkProvider)
- .await;
-
- let expected_links = vec![DocumentLink {
- range: Range::new_simple(0, 14, 0, 17),
- target: FeatureTester::uri("bar/baz.tex").into(),
- tooltip: None,
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-}
diff --git a/support/texlab/src/link/latex_include.rs b/support/texlab/src/link/latex_include.rs
deleted file mode 100644
index 5f4f592f14..0000000000
--- a/support/texlab/src/link/latex_include.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{DocumentLink, DocumentLinkParams},
- syntax::{latex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexIncludeLinkProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexIncludeLinkProvider {
- type Params = DocumentLinkParams;
- type Output = Vec<DocumentLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- if let DocumentContent::Latex(table) = &req.current().content {
- table
- .includes
- .iter()
- .flat_map(|include| Self::resolve(req, table, include))
- .collect()
- } else {
- Vec::new()
- }
- }
-}
-
-impl LatexIncludeLinkProvider {
- fn resolve(
- req: &FeatureRequest<DocumentLinkParams>,
- table: &latex::SymbolTable,
- include: &latex::Include,
- ) -> Vec<DocumentLink> {
- let mut links = Vec::new();
- let paths = include.paths(&table);
- for (i, targets) in include.all_targets.iter().enumerate() {
- for target in targets {
- if let Some(link) = req.snapshot().find(target).map(|doc| DocumentLink {
- range: paths[i].range(),
- target: doc.uri.clone().into(),
- tooltip: None,
- }) {
- links.push(link);
- break;
- }
- }
- }
- links
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document_command() {
- let actual_links = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .test_link(LatexIncludeLinkProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document_command() {
- let actual_links = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_link(LatexIncludeLinkProvider)
- .await;
-
- assert!(actual_links.is_empty());
- }
-
- #[tokio::test]
- async fn has_links() {
- let actual_links = FeatureTester::new()
- .file("foo.tex", r#"\input{bar.tex}"#)
- .file("bar.tex", r#""#)
- .main("foo.tex")
- .test_link(LatexIncludeLinkProvider)
- .await;
-
- let expected_links = vec![DocumentLink {
- range: Range::new_simple(0, 7, 0, 14),
- target: FeatureTester::uri("bar.tex").into(),
- tooltip: None,
- }];
-
- assert_eq!(actual_links, expected_links);
- }
-}
diff --git a/support/texlab/src/link/mod.rs b/support/texlab/src/link/mod.rs
deleted file mode 100644
index 934975f060..0000000000
--- a/support/texlab/src/link/mod.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-mod latex_import;
-mod latex_include;
-
-use self::{latex_import::LatexImportLinkProvider, latex_include::LatexIncludeLinkProvider};
-use crate::{
- feature::{ConcatProvider, FeatureProvider, FeatureRequest},
- protocol::{DocumentLink, DocumentLinkParams},
-};
-use async_trait::async_trait;
-
-pub struct LinkProvider {
- provider: ConcatProvider<DocumentLinkParams, DocumentLink>,
-}
-
-impl LinkProvider {
- pub fn new() -> Self {
- Self {
- provider: ConcatProvider::new(vec![
- Box::new(LatexImportLinkProvider),
- Box::new(LatexIncludeLinkProvider),
- ]),
- }
- }
-}
-
-impl Default for LinkProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for LinkProvider {
- type Params = DocumentLinkParams;
- type Output = Vec<DocumentLink>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
diff --git a/support/texlab/src/main.rs b/support/texlab/src/main.rs
index 16c5be8f26..415de3b804 100644
--- a/support/texlab/src/main.rs
+++ b/support/texlab/src/main.rs
@@ -1,15 +1,10 @@
-use futures::{channel::mpsc, prelude::*};
-use jsonrpc::MessageHandler;
+use std::{env, fs::OpenOptions, io, path::PathBuf};
+
+use anyhow::Result;
use log::LevelFilter;
-use std::path::PathBuf;
-use std::{env, error, fs::OpenOptions, sync::Arc};
+use lsp_server::Connection;
use structopt::StructOpt;
-use texlab::{
- protocol::{LatexLspClient, LspCodec},
- server::LatexLspServer,
- tex::Distribution,
-};
-use tokio_util::codec::{FramedRead, FramedWrite};
+use texlab::Server;
/// An implementation of the Language Server Protocol for LaTeX
#[derive(Debug, StructOpt)]
@@ -27,37 +22,13 @@ struct Opts {
log_file: Option<PathBuf>,
}
-#[tokio::main]
-async fn main() -> Result<(), Box<dyn error::Error>> {
+fn main() -> Result<()> {
let opts = Opts::from_args();
setup_logger(opts);
- let mut stdin = FramedRead::new(tokio::io::stdin(), LspCodec);
- let (stdout_tx, mut stdout_rx) = mpsc::channel(0);
-
- let client = Arc::new(LatexLspClient::new(stdout_tx.clone()));
- let server = Arc::new(LatexLspServer::new(
- Distribution::detect().await,
- Arc::clone(&client),
- Arc::new(env::current_dir().expect("failed to get working directory")),
- ));
- let mut handler = MessageHandler {
- server,
- client,
- output: stdout_tx,
- };
-
- tokio::spawn(async move {
- let mut stdout = FramedWrite::new(tokio::io::stdout(), LspCodec);
- loop {
- let message = stdout_rx.next().await.unwrap();
- stdout.send(message).await.unwrap();
- }
- });
-
- while let Some(json) = stdin.next().await {
- handler.handle(&json.unwrap()).await;
- }
+ let (connection, threads) = Connection::stdio();
+ Server::with_connection(connection, env::current_dir()?, true)?.run()?;
+ threads.join()?;
Ok(())
}
@@ -78,8 +49,10 @@ fn setup_logger(opts: Opts) {
let logger = fern::Dispatch::new()
.format(|out, message, record| out.finish(format_args!("{} - {}", record.level(), message)))
.level(verbosity_level)
- .filter(|metadata| metadata.target() == "jsonrpc" || metadata.target().contains("texlab"))
- .chain(std::io::stderr());
+ .filter(|metadata| {
+ metadata.target().contains("texlab") || metadata.target().contains("lsp_server")
+ })
+ .chain(io::stderr());
let logger = match opts.log_file {
Some(log_file) => logger.chain(
diff --git a/support/texlab/src/options.rs b/support/texlab/src/options.rs
new file mode 100644
index 0000000000..09eea1110f
--- /dev/null
+++ b/support/texlab/src/options.rs
@@ -0,0 +1,86 @@
+use std::path::PathBuf;
+
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct Options {
+ pub root_directory: Option<PathBuf>,
+
+ pub aux_directory: Option<PathBuf>,
+
+ #[serde(default)]
+ pub bibtex_formatter: BibtexFormatter,
+
+ pub formatter_line_length: Option<i32>,
+
+ pub diagnostics_delay: Option<u64>,
+
+ #[serde(default)]
+ pub build: BuildOptions,
+
+ #[serde(default)]
+ pub chktex: ChktexOptions,
+
+ pub forward_search: Option<ForwardSearchOptions>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum BibtexFormatter {
+ Texlab,
+ Latexindent,
+}
+
+impl Default for BibtexFormatter {
+ fn default() -> Self {
+ Self::Texlab
+ }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct BuildOptions {
+ pub executable: Option<String>,
+
+ pub args: Option<Vec<String>>,
+
+ #[serde(default)]
+ pub is_continuous: bool,
+}
+
+impl BuildOptions {
+ pub fn executable(&self) -> String {
+ self.executable
+ .as_ref()
+ .map(Clone::clone)
+ .unwrap_or_else(|| "latexmk".to_string())
+ }
+
+ pub fn args(&self) -> Vec<String> {
+ self.args.as_ref().map(Clone::clone).unwrap_or_else(|| {
+ vec![
+ "-pdf".to_string(),
+ "-interaction=nonstopmode".to_string(),
+ "-synctex=1".to_string(),
+ "%f".to_string(),
+ ]
+ })
+ }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ChktexOptions {
+ #[serde(default)]
+ pub on_open_and_save: bool,
+
+ #[serde(default)]
+ pub on_edit: bool,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
+pub struct ForwardSearchOptions {
+ pub executable: Option<String>,
+ pub args: Option<Vec<String>>,
+}
diff --git a/support/texlab/src/outline.rs b/support/texlab/src/outline.rs
deleted file mode 100644
index 07ffaee09f..0000000000
--- a/support/texlab/src/outline.rs
+++ /dev/null
@@ -1,437 +0,0 @@
-use crate::{
- feature::DocumentView,
- protocol::{MarkupContent, MarkupKind, Options, Position, Range, RangeExt, Uri},
- syntax::{latex, SyntaxNode},
- workspace::{Document, DocumentContent},
-};
-use std::{borrow::Cow, collections::HashSet, path::Path};
-use titlecase::titlecase;
-use OutlineContextItem::*;
-
-#[derive(Debug, Clone, Copy)]
-pub struct OutlineSection<'a> {
- pub document: &'a Document,
- pub item: &'a latex::Section,
-}
-
-pub struct Outline<'a> {
- sections: Vec<OutlineSection<'a>>,
-}
-
-impl<'a> Outline<'a> {
- pub fn find(&'a self, uri: &Uri, pos: Position) -> Option<&'a latex::Section> {
- self.sections
- .iter()
- .filter(|section| section.document.uri == *uri)
- .rev()
- .find(|section| {
- let table = section.document.content.as_latex().unwrap();
- table[section.item.parent].end() <= pos
- })
- .map(|sec| sec.item)
- }
-
- pub fn analyze(view: &'a DocumentView, options: &Options, current_dir: &Path) -> Self {
- let mut finder = OutlineSectionFinder::default();
- let doc = view
- .snapshot
- .parent(&view.current.uri, options, current_dir)
- .map(|parent| {
- view.related
- .iter()
- .find(|doc| doc.uri == parent.uri)
- .unwrap()
- })
- .unwrap_or(&view.current);
-
- finder.analyze(view, doc);
- Self {
- sections: finder.sections,
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-enum OutlineItem<'a> {
- Section(&'a latex::Section),
- Include(&'a latex::Include),
-}
-
-#[derive(Debug, Default)]
-struct OutlineSectionFinder<'a> {
- visited: HashSet<&'a Uri>,
- sections: Vec<OutlineSection<'a>>,
-}
-
-impl<'a> OutlineSectionFinder<'a> {
- fn analyze(&mut self, view: &'a DocumentView, doc: &'a Document) {
- if !self.visited.insert(&doc.uri) {
- return;
- }
-
- if let DocumentContent::Latex(table) = &doc.content {
- let mut items = Vec::new();
- for section in &table.sections {
- items.push(OutlineItem::Section(section));
- }
- for include in &table.includes {
- items.push(OutlineItem::Include(include));
- }
- items.sort_by_key(|item| match item {
- OutlineItem::Include(include) => table[include.parent].start(),
- OutlineItem::Section(section) => table[section.parent].start(),
- });
-
- for item in items {
- match item {
- OutlineItem::Section(item) => {
- let section = OutlineSection {
- document: doc,
- item,
- };
- self.sections.push(section);
- }
- OutlineItem::Include(item) => {
- for doc in &view.related {
- for targets in &item.all_targets {
- if targets.contains(&doc.uri) {
- self.analyze(view, doc);
- break;
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum OutlineCaptionKind {
- Figure,
- Table,
- Listing,
- Algorithm,
-}
-
-impl OutlineCaptionKind {
- pub fn as_str(self) -> &'static str {
- match self {
- Self::Figure => "Figure",
- Self::Table => "Table",
- Self::Listing => "Listing",
- Self::Algorithm => "Algorithm",
- }
- }
-
- pub fn parse(env_name: &str) -> Option<Self> {
- match env_name {
- "figure" | "subfigure" => Some(Self::Figure),
- "table" | "subtable" => Some(Self::Table),
- "listing" | "lstlisting" => Some(Self::Listing),
- "algorithm" => Some(Self::Algorithm),
- _ => None,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub enum OutlineContextItem {
- Section {
- prefix: Cow<'static, str>,
- text: String,
- },
- Caption {
- kind: Option<OutlineCaptionKind>,
- text: String,
- },
- Theorem {
- kind: String,
- description: Option<String>,
- },
- Equation,
- Item,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct OutlineContext {
- pub range: Range,
- pub number: Option<String>,
- pub item: OutlineContextItem,
-}
-
-impl OutlineContext {
- pub fn reference(&self) -> String {
- match &self.number {
- Some(number) => match &self.item {
- Section { prefix, text } => format!("{} {} ({})", prefix, number, text),
- Caption { kind: None, text } => format!("{} {}", number, text),
- Caption {
- kind: Some(kind),
- text,
- } => format!("{} {}: {}", kind.as_str(), number, text),
- Theorem {
- kind,
- description: None,
- } => format!("{} {}", kind, number),
- Theorem {
- kind,
- description: Some(description),
- } => format!("{} {} ({})", kind, number, description),
- Equation => format!("Equation ({})", number),
- Item => format!("Item {}", number),
- },
- None => match &self.item {
- Section { prefix, text } => format!("{} ({})", prefix, text),
- Caption { kind: None, text } => text.clone(),
- Caption {
- kind: Some(kind),
- text,
- } => format!("{}: {}", kind.as_str(), text),
- Theorem {
- kind,
- description: None,
- } => kind.into(),
- Theorem {
- kind,
- description: Some(description),
- } => format!("{} ({})", kind, description),
- Equation => "Equation".into(),
- Item => "Item".into(),
- },
- }
- }
-
- pub fn detail(&self) -> Option<String> {
- match &self.item {
- Section { .. } | Theorem { .. } | Equation | Item => Some(self.reference()),
- Caption {
- kind: Some(kind), ..
- } => {
- let result = match &self.number {
- Some(number) => format!("{} {}", kind.as_str(), number),
- None => kind.as_str().to_owned(),
- };
- Some(result)
- }
- Caption { .. } => None,
- }
- }
-
- pub fn documentation(&self) -> MarkupContent {
- MarkupContent {
- kind: MarkupKind::PlainText,
- value: self.reference(),
- }
- }
-
- pub fn parse(view: &DocumentView, outline: &Outline, label: latex::Label) -> Option<Self> {
- if let DocumentContent::Latex(table) = &view.current.content {
- Self::find_caption(view, table, label)
- .or_else(|| Self::find_theorem(view, table, label))
- .or_else(|| Self::find_equation(view, table, label))
- .or_else(|| Self::find_item(view, table, label))
- .or_else(|| Self::find_section(view, outline, table, label))
- } else {
- None
- }
- }
-
- fn find_caption(
- view: &DocumentView,
- table: &latex::SymbolTable,
- label: latex::Label,
- ) -> Option<Self> {
- let label_range = table[label.parent].range();
- let caption_env = table
- .environments
- .iter()
- .filter(|env| !env.is_root(&table))
- .find(|env| env.range(&table).contains(label_range.start))?;
-
- let caption = table
- .captions
- .iter()
- .find(|cap| table.is_direct_child(*caption_env, table[cap.parent].start()))?;
-
- let caption_text = table.print_group_content(
- caption.parent,
- latex::GroupKind::Group,
- caption.arg_index,
- )?;
-
- let caption_kind = caption_env
- .left
- .name(&table)
- .map(latex::Token::text)
- .and_then(OutlineCaptionKind::parse);
-
- Some(Self {
- range: caption_env.range(&table),
- number: Self::find_number(view, table, label),
- item: Caption {
- kind: caption_kind,
- text: caption_text,
- },
- })
- }
-
- fn find_theorem(
- view: &DocumentView,
- main_table: &latex::SymbolTable,
- label: latex::Label,
- ) -> Option<Self> {
- let label_range = main_table[label.parent].range();
- let env = main_table
- .environments
- .iter()
- .find(|env| env.range(&main_table).contains(label_range.start))?;
-
- let env_name = env.left.name(&main_table).map(latex::Token::text)?;
-
- for doc in &view.related {
- if let DocumentContent::Latex(table) = &doc.content {
- for def in &table.theorem_definitions {
- if env_name == def.name(&table).text() {
- let kind = table
- .print_group_content(
- def.parent,
- latex::GroupKind::Group,
- def.arg_index + 1,
- )
- .unwrap_or_else(|| titlecase(&env_name));
-
- let description = main_table.print_group_content(
- env.left.parent,
- latex::GroupKind::Options,
- 0,
- );
-
- return Some(Self {
- range: env.range(&main_table),
- number: Self::find_number(view, main_table, label),
- item: Theorem { kind, description },
- });
- }
- }
- }
- }
- None
- }
-
- fn find_equation(
- view: &DocumentView,
- table: &latex::SymbolTable,
- label: latex::Label,
- ) -> Option<Self> {
- let label_range = table[label.parent].range();
- table
- .environments
- .iter()
- .filter(|env| env.left.is_math(&table))
- .map(|env| env.range(&table))
- .find(|range| range.contains(label_range.start))
- .map(|range| Self {
- range,
- number: Self::find_number(view, table, label),
- item: Equation,
- })
- }
-
- fn find_item(
- view: &DocumentView,
- table: &latex::SymbolTable,
- label: latex::Label,
- ) -> Option<Self> {
- let label_range = table[label.parent].range();
- struct LatexItemNode {
- item: latex::Item,
- range: Range,
- }
-
- let enumeration = table
- .environments
- .iter()
- .filter(|env| env.left.is_enum(&table))
- .find(|env| env.range(&table).contains(label_range.start))?;
-
- let mut item_nodes: Vec<_> = table
- .items
- .iter()
- .filter(|item| table.is_enum_item(*enumeration, **item))
- .map(|item| LatexItemNode {
- item: *item,
- range: Range::default(),
- })
- .collect();
-
- for i in 0..item_nodes.len() {
- let start = table[item_nodes[i].item.parent].start();
- let end = item_nodes
- .get(i + 1)
- .map(|node| table[node.item.parent].start())
- .unwrap_or_else(|| table[enumeration.right.parent].start());
- item_nodes[i].range = Range::new(start, end);
- }
-
- let node = item_nodes
- .iter()
- .find(|node| node.range.contains(label_range.start))?;
-
- let number = node
- .item
- .name(&table)
- .or_else(|| Self::find_number(view, table, label));
-
- Some(Self {
- range: enumeration.range(&table),
- number,
- item: Item,
- })
- }
-
- fn find_section(
- view: &DocumentView,
- outline: &Outline,
- table: &latex::SymbolTable,
- label: latex::Label,
- ) -> Option<Self> {
- let label_range = table[label.parent].range();
- let section = outline.find(&view.current.uri, label_range.start)?;
- Some(Self {
- range: table[section.parent].range(),
- number: Self::find_number(view, table, label),
- item: Section {
- prefix: section.prefix.clone(),
- text: table.print_group_content(
- section.parent,
- latex::GroupKind::Group,
- section.arg_index,
- )?,
- },
- })
- }
-
- pub fn find_number(
- view: &DocumentView,
- table: &latex::SymbolTable,
- label: latex::Label,
- ) -> Option<String> {
- let label_names = label.names(&table);
- if label_names.len() != 1 {
- return None;
- }
-
- for doc in &view.related {
- if let DocumentContent::Latex(table) = &doc.content {
- for numbering in &table.label_numberings {
- if numbering.name(&table).text() == label_names[0].text() {
- return Some(numbering.number.clone());
- }
- }
- }
- }
- None
- }
-}
diff --git a/support/texlab/src/protocol/client.rs b/support/texlab/src/protocol/client.rs
deleted file mode 100644
index 471f1fa41d..0000000000
--- a/support/texlab/src/protocol/client.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use jsonrpc::client::Result;
-use jsonrpc_derive::{jsonrpc_client, jsonrpc_method};
-use lsp_types::*;
-
-#[jsonrpc_client(LatexLspClient)]
-pub trait LspClient {
- #[jsonrpc_method("workspace/configuration", kind = "request")]
- async fn configuration(&self, params: ConfigurationParams) -> Result<serde_json::Value>;
-
- #[jsonrpc_method("window/showMessage", kind = "notification")]
- async fn show_message(&self, params: ShowMessageParams);
-
- #[jsonrpc_method("client/registerCapability", kind = "request")]
- async fn register_capability(&self, params: RegistrationParams) -> Result<()>;
-
- #[jsonrpc_method("textDocument/publishDiagnostics", kind = "notification")]
- async fn publish_diagnostics(&self, params: PublishDiagnosticsParams);
-
- #[jsonrpc_method("$/progress", kind = "notification")]
- async fn progress(&self, params: ProgressParams);
-
- #[jsonrpc_method("window/workDoneProgress/create", kind = "request")]
- async fn work_done_progress_create(&self, params: WorkDoneProgressCreateParams) -> Result<()>;
-
- #[jsonrpc_method("window/logMessage", kind = "notification")]
- async fn log_message(&self, params: LogMessageParams);
-}
diff --git a/support/texlab/src/protocol/codec.rs b/support/texlab/src/protocol/codec.rs
deleted file mode 100644
index 980ae1307e..0000000000
--- a/support/texlab/src/protocol/codec.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-use bytes::{BufMut, BytesMut};
-use log::trace;
-use std::io::{Error, ErrorKind};
-use tokio_util::codec::{Decoder, Encoder};
-
-pub struct LspCodec;
-
-impl Decoder for LspCodec {
- type Item = String;
- type Error = Error;
-
- fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
- match parser::parse(src) {
- Ok((remaining, content)) => {
- trace!("Received message:\n{}\n", content);
-
- let offset = src.len() - remaining.len();
- let _ = src.split_to(offset);
- Ok(Some(content))
- }
- Err(error) => {
- if error.is_incomplete() {
- Ok(None)
- } else {
- Err(ErrorKind::InvalidData.into())
- }
- }
- }
- }
-}
-
-impl Encoder<String> for LspCodec {
- type Error = Error;
-
- fn encode(&mut self, item: String, dst: &mut BytesMut) -> Result<(), Self::Error> {
- let message = format!("Content-Length: {}\r\n\r\n{}", item.len(), item);
- trace!("Sent message:\n{}\n", message);
-
- dst.reserve(message.len());
- dst.put(message.as_bytes());
- Ok(())
- }
-}
-
-mod parser {
- use nom::{
- bytes::streaming::{tag, take, take_while},
- character::{is_digit, streaming::line_ending},
- combinator::{map_res, opt},
- IResult,
- };
- use std::str;
-
- pub fn parse(input: &[u8]) -> IResult<&[u8], String> {
- let (input, _) = opt(content_type)(input)?;
- let (input, length) = content_length(input)?;
- let (input, _) = opt(content_type)(input)?;
- let (input, _) = line_ending(input)?;
- let (input, content) = map_res(take(length), str::from_utf8)(input)?;
- Ok((input, content.to_owned()))
- }
-
- fn content_type(input: &[u8]) -> IResult<&[u8], &[u8]> {
- let (input, _) = tag("Content-Type: application/vscode-jsonrpc;charset=utf")(input)?;
- let (input, _) = opt(tag("-"))(input)?;
- let (input, _) = tag("8")(input)?;
- line_ending(input)
- }
-
- fn content_length(input: &[u8]) -> IResult<&[u8], usize> {
- let (input, _) = tag("Content-Length: ")(input)?;
- let (input, length) = map_res(take_while(is_digit), from_bytes)(input)?;
- let (input, _) = line_ending(input)?;
- Ok((input, length))
- }
-
- fn from_bytes(input: &[u8]) -> Result<usize, std::num::ParseIntError> {
- usize::from_str_radix(str::from_utf8(input).unwrap(), 10)
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn parse_content_type() {
- let result =
- content_type(b"Content-Type: application/vscode-jsonrpc;charset=utf-8\r\n");
- assert!(result.is_ok());
- }
-
- #[test]
- fn parse_content_type_utf8() {
- let result = content_type(b"Content-Type: application/vscode-jsonrpc;charset=utf8\r\n");
- assert!(result.is_ok());
- }
-
- #[test]
- fn parse_content_length() {
- let result = content_length(b"Content-Length: 42\r\n");
- assert_eq!(result.unwrap().1, 42usize);
- }
-
- #[test]
- fn parse_message_full() {
- let result = parse(
- b"Content-Length: 2\r\nContent-Type: application/vscode-jsonrpc;charset=utf8\r\n\r\n{}",
- );
- assert_eq!(result.unwrap().1, "{}");
- }
-
- #[test]
- fn parse_message_type_first() {
- let result = parse(
- b"Content-Type: application/vscode-jsonrpc;charset=utf8\r\nContent-Length: 2\r\n\r\n{}",
- );
- assert_eq!(result.unwrap().1, "{}");
- }
-
- #[test]
- fn parse_message_without_type() {
- let result = parse(b"Content-Length: 2\r\n\r\n{}");
- assert_eq!(result.unwrap().1, "{}");
- }
-
- #[test]
- fn parse_message_incomplete() {
- let result = parse(b"Content-Length:");
- assert!(result.unwrap_err().is_incomplete());
- }
-
- #[test]
- fn parse_message_invalid() {
- let error = parse(b"foo").unwrap_err();
- assert!(!error.is_incomplete());
- }
-
- #[test]
- fn parse_message_overflow() {
- let result = parse(b"Content-Length: 4\r\n\r\n{}");
- assert!(result.unwrap_err().is_incomplete());
- }
- }
-}
diff --git a/support/texlab/src/protocol/edit.rs b/support/texlab/src/protocol/edit.rs
deleted file mode 100644
index 9091f2d393..0000000000
--- a/support/texlab/src/protocol/edit.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use lsp_types::{CompletionTextEdit, TextEdit};
-
-pub trait CompletionTextEditExt {
- fn text_edit(&self) -> Option<&TextEdit>;
-}
-
-impl CompletionTextEditExt for CompletionTextEdit {
- fn text_edit(&self) -> Option<&TextEdit> {
- let CompletionTextEdit::Edit(edit) = self;
- Some(edit)
- }
-}
diff --git a/support/texlab/src/protocol/mod.rs b/support/texlab/src/protocol/mod.rs
deleted file mode 100644
index c08a7d82f5..0000000000
--- a/support/texlab/src/protocol/mod.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-cfg_if::cfg_if! {
- if #[cfg(feature = "server")] {
- mod client;
- mod codec;
-
- pub use self::{
- client::{LatexLspClient, LspClient},
- codec::LspCodec,
- };
- }
-}
-
-mod capabilities;
-mod edit;
-mod options;
-mod range;
-mod uri;
-
-pub use self::{
- capabilities::ClientCapabilitiesExt,
- edit::*,
- options::*,
- range::RangeExt,
- uri::{AsUri, Uri},
-};
-pub use lsp_types::*;
-
-use serde::{Deserialize, Serialize};
-use serde_repr::*;
-
-#[serde(untagged)]
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub enum DefinitionResponse {
- Locations(Vec<Location>),
- LocationLinks(Vec<LocationLink>),
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize_repr, Deserialize_repr)]
-#[repr(i32)]
-pub enum ForwardSearchStatus {
- Success = 0,
- Error = 1,
- Failure = 2,
- Unconfigured = 3,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct ForwardSearchResult {
- pub status: ForwardSearchStatus,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BuildParams {
- pub text_document: TextDocumentIdentifier,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize_repr, Deserialize_repr)]
-#[repr(i32)]
-pub enum BuildStatus {
- Success = 0,
- Error = 1,
- Failure = 2,
- Cancelled = 3,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BuildResult {
- pub status: BuildStatus,
-}
diff --git a/support/texlab/src/protocol/options.rs b/support/texlab/src/protocol/options.rs
deleted file mode 100644
index 86718d1e72..0000000000
--- a/support/texlab/src/protocol/options.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-use serde::{Deserialize, Serialize};
-use std::path::PathBuf;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum BibtexFormatter {
- Texlab,
- Latexindent,
-}
-
-impl Default for BibtexFormatter {
- fn default() -> Self {
- Self::Texlab
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BibtexFormattingOptions {
- pub line_length: Option<i32>,
- pub formatter: Option<BibtexFormatter>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-pub struct LatexForwardSearchOptions {
- pub executable: Option<String>,
- pub args: Option<Vec<String>>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Default)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexLintOptions {
- pub on_change: Option<bool>,
- pub on_save: Option<bool>,
-}
-
-impl LatexLintOptions {
- pub fn on_change(&self) -> bool {
- self.on_change.unwrap_or(false)
- }
-
- pub fn on_save(&self) -> bool {
- self.on_save.unwrap_or(false)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexBuildOptions {
- pub executable: Option<String>,
- pub args: Option<Vec<String>>,
- pub on_save: Option<bool>,
- pub output_directory: Option<PathBuf>,
- pub forward_search_after: Option<bool>,
-}
-
-impl LatexBuildOptions {
- pub fn executable(&self) -> String {
- self.executable
- .as_ref()
- .map(Clone::clone)
- .unwrap_or_else(|| "latexmk".to_owned())
- }
-
- pub fn args(&self) -> Vec<String> {
- self.args.as_ref().map(Clone::clone).unwrap_or_else(|| {
- vec![
- "-pdf".to_owned(),
- "-interaction=nonstopmode".to_owned(),
- "-synctex=1".to_owned(),
- ]
- })
- }
-
- pub fn on_save(&self) -> bool {
- self.on_save.unwrap_or(false)
- }
-
- pub fn forward_search_after(&self) -> bool {
- self.forward_search_after.unwrap_or(false)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexOptions {
- pub forward_search: Option<LatexForwardSearchOptions>,
- pub lint: Option<LatexLintOptions>,
- pub build: Option<LatexBuildOptions>,
- pub root_directory: Option<PathBuf>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BibtexOptions {
- pub formatting: Option<BibtexFormattingOptions>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct Options {
- pub latex: Option<LatexOptions>,
- pub bibtex: Option<BibtexOptions>,
-}
diff --git a/support/texlab/src/protocol/range.rs b/support/texlab/src/protocol/range.rs
deleted file mode 100644
index 774df1e699..0000000000
--- a/support/texlab/src/protocol/range.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use lsp_types::{Position, Range};
-
-pub trait RangeExt {
- fn new_simple(start_line: u64, start_character: u64, end_line: u64, end_character: u64)
- -> Self;
-
- fn contains(&self, pos: Position) -> bool;
-
- fn contains_exclusive(&self, pos: Position) -> bool;
-}
-
-impl RangeExt for Range {
- fn new_simple(
- start_line: u64,
- start_character: u64,
- end_line: u64,
- end_character: u64,
- ) -> Self {
- Self {
- start: Position::new(start_line, start_character),
- end: Position::new(end_line, end_character),
- }
- }
-
- fn contains(&self, pos: Position) -> bool {
- pos >= self.start && pos <= self.end
- }
-
- fn contains_exclusive(&self, pos: Position) -> bool {
- pos > self.start && pos < self.end
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn contains_inside() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(range.contains(Position::new(2, 5)));
- }
-
- #[test]
- fn contains_begin() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(range.contains(range.start));
- }
-
- #[test]
- fn contains_end() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(range.contains(range.end));
- }
-
- #[test]
- fn contains_outside_left() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(!range.contains(Position::new(0, 5)));
- }
-
- #[test]
- fn contains_outside_right() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(!range.contains(Position::new(5, 1)));
- }
-
- #[test]
- fn contains_exclusive_inside() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(range.contains_exclusive(Position::new(2, 5)));
- }
-
- #[test]
- fn contains_exclusive_begin() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(!range.contains_exclusive(range.start));
- }
-
- #[test]
- fn contains_exclusive_end() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(!range.contains_exclusive(range.end));
- }
-
- #[test]
- fn contains_exclusive_outside_left() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(!range.contains_exclusive(Position::new(0, 5)));
- }
-
- #[test]
- fn contains_exclusive_outside_right() {
- let range = Range::new_simple(1, 2, 3, 4);
- assert!(!range.contains_exclusive(Position::new(5, 1)));
- }
-}
diff --git a/support/texlab/src/range.rs b/support/texlab/src/range.rs
new file mode 100644
index 0000000000..c70a573f39
--- /dev/null
+++ b/support/texlab/src/range.rs
@@ -0,0 +1,20 @@
+use lsp_types::{Position, Range};
+
+pub trait RangeExt {
+ fn new_simple(start_line: u32, start_character: u32, end_line: u32, end_character: u32)
+ -> Self;
+}
+
+impl RangeExt for Range {
+ fn new_simple(
+ start_line: u32,
+ start_character: u32,
+ end_line: u32,
+ end_character: u32,
+ ) -> Self {
+ Self {
+ start: Position::new(start_line, start_character),
+ end: Position::new(end_line, end_character),
+ }
+ }
+}
diff --git a/support/texlab/src/reference/bibtex_entry.rs b/support/texlab/src/reference/bibtex_entry.rs
deleted file mode 100644
index 2acf7bdfef..0000000000
--- a/support/texlab/src/reference/bibtex_entry.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{Location, RangeExt, ReferenceParams, Url},
- syntax::{bibtex, latex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexEntryReferenceProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexEntryReferenceProvider {
- type Params = ReferenceParams;
- type Output = Vec<Location>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut refs = Vec::new();
- if let Some(key) = Self::find_key(req) {
- for doc in req.related() {
- match &doc.content {
- DocumentContent::Latex(table) => table
- .citations
- .iter()
- .flat_map(|citation| citation.keys(&table))
- .filter(|citation| citation.text() == key)
- .map(|citation| Location::new(doc.uri.clone().into(), citation.range()))
- .for_each(|location| refs.push(location)),
- DocumentContent::Bibtex(tree) => {
- if req.params.context.include_declaration {
- let uri: Url = doc.uri.clone().into();
- tree.children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- .filter_map(|entry| entry.key.as_ref())
- .filter(|key_tok| key_tok.text() == key)
- .map(|key_tok| Location::new(uri.clone(), key_tok.range()))
- .for_each(|location| refs.push(location));
- }
- }
- }
- }
- }
- refs
- }
-}
-
-impl BibtexEntryReferenceProvider {
- fn find_key(req: &FeatureRequest<ReferenceParams>) -> Option<&str> {
- let pos = req.params.text_document_position.position;
- match &req.current().content {
- DocumentContent::Latex(table) => table
- .citations
- .iter()
- .flat_map(|citation| citation.keys(&table))
- .find(|key| key.range().contains(pos))
- .map(latex::Token::text),
- DocumentContent::Bibtex(tree) => tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- .filter_map(|entry| entry.key.as_ref())
- .find(|key| key.range().contains(pos))
- .map(bibtex::Token::text),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn entry() {
- let actual_refs = FeatureTester::new()
- .file("foo.bib", r#"@article{foo, bar = {baz}}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \addbibresource{foo.bib}
- \cite{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\cite{foo}"#)
- .main("foo.bib")
- .position(0, 9)
- .test_reference(BibtexEntryReferenceProvider)
- .await;
-
- let expected_refs = vec![Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 6, 1, 9),
- )];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn entry_include_declaration() {
- let actual_refs = FeatureTester::new()
- .file("foo.bib", r#"@article{foo, bar = {baz}}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \addbibresource{foo.bib}
- \cite{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\cite{foo}"#)
- .main("foo.bib")
- .position(0, 9)
- .include_declaration()
- .test_reference(BibtexEntryReferenceProvider)
- .await;
-
- let expected_refs = vec![
- Location::new(
- FeatureTester::uri("foo.bib").into(),
- Range::new_simple(0, 9, 0, 12),
- ),
- Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 6, 1, 9),
- ),
- ];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn citation() {
- let actual_refs = FeatureTester::new()
- .file("foo.bib", r#"@article{foo, bar = {baz}}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \addbibresource{foo.bib}
- \cite{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\cite{foo}"#)
- .main("bar.tex")
- .position(1, 8)
- .test_reference(BibtexEntryReferenceProvider)
- .await;
-
- let expected_refs = vec![Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 6, 1, 9),
- )];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn citation_include_declaration() {
- let actual_refs = FeatureTester::new()
- .file("foo.bib", r#"@article{foo, bar = {baz}}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \addbibresource{foo.bib}
- \cite{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\cite{foo}"#)
- .main("bar.tex")
- .position(1, 8)
- .include_declaration()
- .test_reference(BibtexEntryReferenceProvider)
- .await;
-
- let expected_refs = vec![
- Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 6, 1, 9),
- ),
- Location::new(
- FeatureTester::uri("foo.bib").into(),
- Range::new_simple(0, 9, 0, 12),
- ),
- ];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_refs = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_reference(BibtexEntryReferenceProvider)
- .await;
-
- assert!(actual_refs.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_refs = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_reference(BibtexEntryReferenceProvider)
- .await;
-
- assert!(actual_refs.is_empty());
- }
-}
diff --git a/support/texlab/src/reference/bibtex_string.rs b/support/texlab/src/reference/bibtex_string.rs
deleted file mode 100644
index 5f9804fbd6..0000000000
--- a/support/texlab/src/reference/bibtex_string.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{Location, Position, RangeExt, ReferenceParams, Url},
- syntax::{
- bibtex::{self, Visitor},
- SyntaxNode,
- },
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use petgraph::graph::NodeIndex;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexStringReferenceProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexStringReferenceProvider {
- type Params = ReferenceParams;
- type Output = Vec<Location>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut refs = Vec::new();
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- if let Some(name) = Self::find_name(tree, req.params.text_document_position.position) {
- let uri: Url = req.current().uri.clone().into();
- if req.params.context.include_declaration {
- tree.children(tree.root)
- .filter_map(|node| tree.as_string(node))
- .filter_map(|string| string.name.as_ref())
- .filter(|string| string.text() == name.text())
- .for_each(|string| refs.push(Location::new(uri.clone(), string.range())));
- }
-
- let mut visitor = BibtexStringReferenceVisitor::default();
- visitor.visit(tree, tree.root);
- visitor
- .refs
- .into_iter()
- .filter(|reference| reference.text() == name.text())
- .for_each(|reference| refs.push(Location::new(uri.clone(), reference.range())));
- }
- }
- refs
- }
-}
-
-impl BibtexStringReferenceProvider {
- fn find_name(tree: &bibtex::Tree, pos: Position) -> Option<&bibtex::Token> {
- let mut nodes = tree.find(pos);
- nodes.reverse();
- let node0 = &tree.graph[nodes[0]];
- let node1 = nodes.get(1).map(|node| &tree.graph[*node]);
- match (node0, node1) {
- (bibtex::Node::Word(word), Some(bibtex::Node::Field(_)))
- | (bibtex::Node::Word(word), Some(bibtex::Node::Concat(_))) => Some(&word.token),
- (bibtex::Node::String(string), _) => string
- .name
- .as_ref()
- .filter(|name| name.range().contains(pos)),
- _ => None,
- }
- }
-}
-
-#[derive(Debug, Default)]
-pub struct BibtexStringReferenceVisitor<'a> {
- refs: Vec<&'a bibtex::Token>,
-}
-
-impl<'a> bibtex::Visitor<'a> for BibtexStringReferenceVisitor<'a> {
- fn visit(&mut self, tree: &'a bibtex::Tree, node: NodeIndex) {
- match &tree.graph[node] {
- bibtex::Node::Root(_)
- | bibtex::Node::Comment(_)
- | bibtex::Node::Preamble(_)
- | bibtex::Node::String(_)
- | bibtex::Node::Entry(_)
- | bibtex::Node::Word(_)
- | bibtex::Node::Command(_)
- | bibtex::Node::QuotedContent(_)
- | bibtex::Node::BracedContent(_) => (),
- bibtex::Node::Field(_) => {
- if let Some(word) = tree
- .children(node)
- .next()
- .and_then(|content| tree.as_word(content))
- {
- self.refs.push(&word.token);
- }
- }
- bibtex::Node::Concat(_) => {
- let mut children = tree.children(node);
- if let Some(word) = children.next().and_then(|left| tree.as_word(left)) {
- self.refs.push(&word.token);
- }
-
- if let Some(word) = children.next().and_then(|right| tree.as_word(right)) {
- self.refs.push(&word.token);
- }
- }
- }
- tree.walk(self, node);
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn definition() {
- let actual_refs = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {Foo}}
- @string{bar = {Bar}}
- @article{baz, author = foo}
- "#
- ),
- )
- .main("main.bib")
- .position(2, 24)
- .test_reference(BibtexStringReferenceProvider)
- .await;
-
- let expected_refs = vec![Location::new(
- FeatureTester::uri("main.bib").into(),
- Range::new_simple(2, 23, 2, 26),
- )];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn definition_include_declaration() {
- let actual_refs = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {Foo}}
- @string{bar = {Bar}}
- @article{baz, author = foo}
- "#
- ),
- )
- .main("main.bib")
- .position(2, 24)
- .include_declaration()
- .test_reference(BibtexStringReferenceProvider)
- .await;
-
- let expected_refs = vec![
- Location::new(
- FeatureTester::uri("main.bib").into(),
- Range::new_simple(0, 8, 0, 11),
- ),
- Location::new(
- FeatureTester::uri("main.bib").into(),
- Range::new_simple(2, 23, 2, 26),
- ),
- ];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn reference() {
- let actual_refs = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {Foo}}
- @string{bar = {Bar}}
- @article{baz, author = foo}
- "#
- ),
- )
- .main("main.bib")
- .position(0, 10)
- .test_reference(BibtexStringReferenceProvider)
- .await;
-
- let expected_refs = vec![Location::new(
- FeatureTester::uri("main.bib").into(),
- Range::new_simple(2, 23, 2, 26),
- )];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn reference_include_declaration() {
- let actual_refs = FeatureTester::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = {Foo}}
- @string{bar = {Bar}}
- @article{baz, author = foo}
- "#
- ),
- )
- .main("main.bib")
- .position(0, 10)
- .include_declaration()
- .test_reference(BibtexStringReferenceProvider)
- .await;
-
- let expected_refs = vec![
- Location::new(
- FeatureTester::uri("main.bib").into(),
- Range::new_simple(0, 8, 0, 11),
- ),
- Location::new(
- FeatureTester::uri("main.bib").into(),
- Range::new_simple(2, 23, 2, 26),
- ),
- ];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_refs = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_reference(BibtexStringReferenceProvider)
- .await;
-
- assert!(actual_refs.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_refs = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_reference(BibtexStringReferenceProvider)
- .await;
-
- assert!(actual_refs.is_empty());
- }
-}
diff --git a/support/texlab/src/reference/latex_label.rs b/support/texlab/src/reference/latex_label.rs
deleted file mode 100644
index 16686f6015..0000000000
--- a/support/texlab/src/reference/latex_label.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{Location, RangeExt, ReferenceParams},
- syntax::{latex, LatexLabelKind, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexLabelReferenceProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexLabelReferenceProvider {
- type Params = ReferenceParams;
- type Output = Vec<Location>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut refs = Vec::new();
- if let Some(def) = Self::find_name(req) {
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .labels
- .iter()
- .filter(|label| Self::is_included(req, label))
- .flat_map(|label| label.names(&table))
- .filter(|label| label.text() == def)
- .map(|label| Location::new(doc.uri.clone().into(), label.range()))
- .for_each(|location| refs.push(location));
- }
- }
- }
- refs
- }
-}
-
-impl LatexLabelReferenceProvider {
- fn find_name(req: &FeatureRequest<ReferenceParams>) -> Option<&str> {
- let pos = req.params.text_document_position.position;
- if let DocumentContent::Latex(table) = &req.current().content {
- table
- .labels
- .iter()
- .flat_map(|label| label.names(&table))
- .find(|label| label.range().contains(pos))
- .map(latex::Token::text)
- } else {
- None
- }
- }
-
- fn is_included(req: &FeatureRequest<ReferenceParams>, label: &latex::Label) -> bool {
- match label.kind {
- LatexLabelKind::Reference(_) => true,
- LatexLabelKind::Definition => req.params.context.include_declaration,
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::Range};
- use indoc::indoc;
-
- #[tokio::test]
- async fn definition() {
- let actual_refs = FeatureTester::new()
- .file("foo.tex", r#"\label{foo}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \input{foo.tex}
- \ref{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\ref{foo}"#)
- .main("foo.tex")
- .position(0, 8)
- .test_reference(LatexLabelReferenceProvider)
- .await;
-
- let expected_refs = vec![Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 5, 1, 8),
- )];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn definition_include_declaration() {
- let actual_refs = FeatureTester::new()
- .file("foo.tex", r#"\label{foo}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \input{foo.tex}
- \ref{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\ref{foo}"#)
- .main("foo.tex")
- .position(0, 8)
- .include_declaration()
- .test_reference(LatexLabelReferenceProvider)
- .await;
-
- let expected_refs = vec![
- Location::new(
- FeatureTester::uri("foo.tex").into(),
- Range::new_simple(0, 7, 0, 10),
- ),
- Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 5, 1, 8),
- ),
- ];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn reference() {
- let actual_refs = FeatureTester::new()
- .file("foo.tex", r#"\label{foo}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \input{foo.tex}
- \ref{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\ref{foo}"#)
- .main("bar.tex")
- .position(1, 7)
- .test_reference(LatexLabelReferenceProvider)
- .await;
-
- let expected_refs = vec![Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 5, 1, 8),
- )];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn reference_include_declaration() {
- let actual_refs = FeatureTester::new()
- .file("foo.tex", r#"\label{foo}"#)
- .file(
- "bar.tex",
- indoc!(
- r#"
- \input{foo.tex}
- \ref{foo}
- "#
- ),
- )
- .file("baz.tex", r#"\ref{foo}"#)
- .main("bar.tex")
- .position(1, 7)
- .include_declaration()
- .test_reference(LatexLabelReferenceProvider)
- .await;
-
- let expected_refs = vec![
- Location::new(
- FeatureTester::uri("bar.tex").into(),
- Range::new_simple(1, 5, 1, 8),
- ),
- Location::new(
- FeatureTester::uri("foo.tex").into(),
- Range::new_simple(0, 7, 0, 10),
- ),
- ];
-
- assert_eq!(actual_refs, expected_refs);
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_refs = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .test_reference(LatexLabelReferenceProvider)
- .await;
-
- assert!(actual_refs.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_refs = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .test_reference(LatexLabelReferenceProvider)
- .await;
-
- assert!(actual_refs.is_empty());
- }
-}
diff --git a/support/texlab/src/reference/mod.rs b/support/texlab/src/reference/mod.rs
deleted file mode 100644
index fc4379d394..0000000000
--- a/support/texlab/src/reference/mod.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-mod bibtex_entry;
-mod bibtex_string;
-mod latex_label;
-
-use self::{
- bibtex_entry::BibtexEntryReferenceProvider, bibtex_string::BibtexStringReferenceProvider,
- latex_label::LatexLabelReferenceProvider,
-};
-use crate::{
- feature::{ConcatProvider, FeatureProvider, FeatureRequest},
- protocol::{Location, ReferenceParams},
-};
-use async_trait::async_trait;
-
-pub struct ReferenceProvider {
- provider: ConcatProvider<ReferenceParams, Location>,
-}
-
-impl ReferenceProvider {
- pub fn new() -> Self {
- Self {
- provider: ConcatProvider::new(vec![
- Box::new(BibtexEntryReferenceProvider),
- Box::new(BibtexStringReferenceProvider),
- Box::new(LatexLabelReferenceProvider),
- ]),
- }
- }
-}
-
-impl Default for ReferenceProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for ReferenceProvider {
- type Params = ReferenceParams;
- type Output = Vec<Location>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
diff --git a/support/texlab/src/rename/bibtex_entry.rs b/support/texlab/src/rename/bibtex_entry.rs
deleted file mode 100644
index 97eaa8fd9d..0000000000
--- a/support/texlab/src/rename/bibtex_entry.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- Position, Range, RangeExt, RenameParams, TextDocumentPositionParams, TextEdit,
- WorkspaceEdit,
- },
- syntax::{Span, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use std::collections::HashMap;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexEntryPrepareRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexEntryPrepareRenameProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Range>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- find_key(&req.current().content, req.params.position).map(Span::range)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexEntryRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexEntryRenameProvider {
- type Params = RenameParams;
- type Output = Option<WorkspaceEdit>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let key_name = find_key(
- &req.current().content,
- req.params.text_document_position.position,
- )?;
- let mut changes = HashMap::new();
- for doc in req.related() {
- let edits = match &doc.content {
- DocumentContent::Latex(table) => table
- .citations
- .iter()
- .flat_map(|citation| citation.keys(&table))
- .filter(|citation| citation.text() == key_name.text)
- .map(|citation| TextEdit::new(citation.range(), req.params.new_name.clone()))
- .collect(),
- DocumentContent::Bibtex(tree) => tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- .filter_map(|entry| entry.key.as_ref())
- .filter(|entry_key| entry_key.text() == key_name.text)
- .map(|entry_key| TextEdit::new(entry_key.range(), req.params.new_name.clone()))
- .collect(),
- };
- changes.insert(doc.uri.clone().into(), edits);
- }
- Some(WorkspaceEdit::new(changes))
- }
-}
-
-fn find_key(content: &DocumentContent, pos: Position) -> Option<&Span> {
- match content {
- DocumentContent::Latex(table) => table
- .citations
- .iter()
- .flat_map(|citation| citation.keys(&table))
- .find(|key| key.range().contains(pos))
- .map(|key| &key.span),
- DocumentContent::Bibtex(tree) => tree
- .children(tree.root)
- .filter_map(|node| tree.as_entry(node))
- .filter_map(|entry| entry.key.as_ref())
- .find(|key| key.range().contains(pos))
- .map(|key| &key.span),
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::RangeExt};
- use indoc::indoc;
-
- #[tokio::test]
- async fn entry() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", r#"@article{foo, bar = baz}"#)
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{foo}
- "#
- ),
- )
- .main("main.bib")
- .position(0, 9)
- .new_name("qux")
- .test_rename(BibtexEntryRenameProvider)
- .await
- .unwrap();
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- FeatureTester::uri("main.bib").into(),
- vec![TextEdit::new(Range::new_simple(0, 9, 0, 12), "qux".into())],
- );
- expected_changes.insert(
- FeatureTester::uri("main.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 6, 1, 9), "qux".into())],
- );
- let expected_edit = WorkspaceEdit::new(expected_changes);
-
- assert_eq!(actual_edit, expected_edit);
- }
-
- #[tokio::test]
- async fn citation() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", r#"@article{foo, bar = baz}"#)
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{foo}
- "#
- ),
- )
- .main("main.tex")
- .position(1, 6)
- .new_name("qux")
- .test_rename(BibtexEntryRenameProvider)
- .await
- .unwrap();
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- FeatureTester::uri("main.bib").into(),
- vec![TextEdit::new(Range::new_simple(0, 9, 0, 12), "qux".into())],
- );
- expected_changes.insert(
- FeatureTester::uri("main.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 6, 1, 9), "qux".into())],
- );
- let expected_edit = WorkspaceEdit::new(expected_changes);
-
- assert_eq!(actual_edit, expected_edit);
- }
-
- #[tokio::test]
- async fn field_name() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", r#"@article{foo, bar = baz}"#)
- .main("main.bib")
- .position(0, 14)
- .new_name("qux")
- .test_rename(BibtexEntryRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .new_name("")
- .test_rename(BibtexEntryRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .new_name("")
- .test_rename(BibtexEntryRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-}
diff --git a/support/texlab/src/rename/latex_cmd.rs b/support/texlab/src/rename/latex_cmd.rs
deleted file mode 100644
index 4770c4c485..0000000000
--- a/support/texlab/src/rename/latex_cmd.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- Position, Range, RenameParams, TextDocumentPositionParams, TextEdit, WorkspaceEdit,
- },
- syntax::{latex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use std::collections::HashMap;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexCommandPrepareRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexCommandPrepareRenameProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Range>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let pos = req.params.position;
- find_command(&req.current().content, pos).map(SyntaxNode::range)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexCommandRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexCommandRenameProvider {
- type Params = RenameParams;
- type Output = Option<WorkspaceEdit>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let pos = req.params.text_document_position.position;
- let cmd_name = find_command(&req.current().content, pos)?.name.text();
- let mut changes = HashMap::new();
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- let edits = table
- .commands
- .iter()
- .filter_map(|node| table.as_command(*node))
- .filter(|cmd| cmd.name.text() == cmd_name)
- .map(|cmd| {
- TextEdit::new(cmd.name.range(), format!("\\{}", req.params.new_name))
- })
- .collect();
- changes.insert(doc.uri.clone().into(), edits);
- }
- }
- Some(WorkspaceEdit::new(changes))
- }
-}
-
-fn find_command(content: &DocumentContent, pos: Position) -> Option<&latex::Command> {
- if let DocumentContent::Latex(table) = &content {
- table.as_command(table.find_command_by_short_name_range(pos)?)
- } else {
- None
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{feature::FeatureTester, protocol::RangeExt};
- use indoc::indoc;
-
- #[tokio::test]
- async fn command() {
- let actual_edit = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \include{bar.tex}
- \baz
- "#
- ),
- )
- .file("bar.tex", r#"\baz"#)
- .main("foo.tex")
- .position(1, 2)
- .new_name("qux")
- .test_rename(LatexCommandRenameProvider)
- .await
- .unwrap();
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- FeatureTester::uri("foo.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 0, 1, 4), "\\qux".into())],
- );
- expected_changes.insert(
- FeatureTester::uri("bar.tex").into(),
- vec![TextEdit::new(Range::new_simple(0, 0, 0, 4), "\\qux".into())],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .new_name("")
- .test_rename(LatexCommandRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .new_name("")
- .test_rename(LatexCommandRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-}
diff --git a/support/texlab/src/rename/latex_env.rs b/support/texlab/src/rename/latex_env.rs
deleted file mode 100644
index 6e302ef8b6..0000000000
--- a/support/texlab/src/rename/latex_env.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- Position, Range, RangeExt, RenameParams, TextDocumentPositionParams, TextEdit,
- WorkspaceEdit,
- },
- syntax::{latex, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use std::collections::HashMap;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexEnvironmentPrepareRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexEnvironmentPrepareRenameProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Range>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let pos = req.params.position;
- let (left_name, right_name) = find_environment(&req.current().content, pos)?;
- let range = if left_name.range().contains(pos) {
- left_name.range()
- } else {
- right_name.range()
- };
- Some(range)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexEnvironmentRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexEnvironmentRenameProvider {
- type Params = RenameParams;
- type Output = Option<WorkspaceEdit>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let (left_name, right_name) = find_environment(
- &req.current().content,
- req.params.text_document_position.position,
- )?;
- let edits = vec![
- TextEdit::new(left_name.range(), req.params.new_name.clone()),
- TextEdit::new(right_name.range(), req.params.new_name.clone()),
- ];
- let mut changes = HashMap::new();
- changes.insert(req.current().uri.clone().into(), edits);
- Some(WorkspaceEdit::new(changes))
- }
-}
-
-fn find_environment(
- content: &DocumentContent,
- pos: Position,
-) -> Option<(&latex::Token, &latex::Token)> {
- if let DocumentContent::Latex(table) = content {
- for env in &table.environments {
- if let Some(left_name) = env.left.name(&table) {
- if let Some(right_name) = env.right.name(&table) {
- if left_name.range().contains(pos) || right_name.range().contains(pos) {
- return Some((left_name, right_name));
- }
- }
- }
- }
- }
- None
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn environment() {
- let actual_edit = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{foo}
- \end{bar}
- "#
- ),
- )
- .main("main.tex")
- .position(0, 8)
- .new_name("baz")
- .test_rename(LatexEnvironmentRenameProvider)
- .await
- .unwrap();
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- FeatureTester::uri("main.tex").into(),
- vec![
- TextEdit::new(Range::new_simple(0, 7, 0, 10), "baz".into()),
- TextEdit::new(Range::new_simple(1, 5, 1, 8), "baz".into()),
- ],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
- }
-
- #[tokio::test]
- async fn command() {
- let actual_edit = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{foo}
- \end{bar}
- "#
- ),
- )
- .main("main.tex")
- .position(0, 5)
- .new_name("baz")
- .test_rename(LatexEnvironmentRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .new_name("")
- .test_rename(LatexEnvironmentRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .new_name("")
- .test_rename(LatexEnvironmentRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-}
diff --git a/support/texlab/src/rename/latex_label.rs b/support/texlab/src/rename/latex_label.rs
deleted file mode 100644
index 27e0f9b224..0000000000
--- a/support/texlab/src/rename/latex_label.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::{
- Position, Range, RangeExt, RenameParams, TextDocumentPositionParams, TextEdit,
- WorkspaceEdit,
- },
- syntax::{Span, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use std::collections::HashMap;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexLabelPrepareRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexLabelPrepareRenameProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Range>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let pos = req.params.position;
- find_label(&req.current().content, pos).map(Span::range)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexLabelRenameProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexLabelRenameProvider {
- type Params = RenameParams;
- type Output = Option<WorkspaceEdit>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let pos = req.params.text_document_position.position;
- let name = find_label(&req.current().content, pos)?;
- let mut changes = HashMap::new();
- for doc in req.related() {
- if let DocumentContent::Latex(table) = &doc.content {
- let edits = table
- .labels
- .iter()
- .flat_map(|label| label.names(&table))
- .filter(|label| label.text() == name.text)
- .map(|label| TextEdit::new(label.range(), req.params.new_name.clone()))
- .collect();
- changes.insert(doc.uri.clone().into(), edits);
- }
- }
- Some(WorkspaceEdit::new(changes))
- }
-}
-
-fn find_label(content: &DocumentContent, pos: Position) -> Option<&Span> {
- if let DocumentContent::Latex(table) = content {
- table
- .labels
- .iter()
- .flat_map(|label| label.names(&table))
- .find(|label| label.range().contains(pos))
- .map(|label| &label.span)
- } else {
- None
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn label() {
- let actual_edit = FeatureTester::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \label{foo}
- \include{bar}
- "#
- ),
- )
- .file("bar.tex", r#"\ref{foo}"#)
- .file("baz.tex", r#"\ref{foo}"#)
- .main("foo.tex")
- .position(0, 7)
- .new_name("bar")
- .test_rename(LatexLabelRenameProvider)
- .await
- .unwrap();
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- FeatureTester::uri("foo.tex").into(),
- vec![TextEdit::new(Range::new_simple(0, 7, 0, 10), "bar".into())],
- );
- expected_changes.insert(
- FeatureTester::uri("bar.tex").into(),
- vec![TextEdit::new(Range::new_simple(0, 5, 0, 8), "bar".into())],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
- }
-
- #[tokio::test]
- async fn command_args() {
- let actual_edit = FeatureTester::new()
- .file("main.tex", r#"\foo{bar}"#)
- .main("main.tex")
- .position(0, 5)
- .new_name("baz")
- .test_rename(LatexLabelRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .position(0, 0)
- .new_name("")
- .test_rename(LatexLabelRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_edit = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .position(0, 0)
- .new_name("")
- .test_rename(LatexLabelRenameProvider)
- .await;
-
- assert_eq!(actual_edit, None);
- }
-}
diff --git a/support/texlab/src/rename/mod.rs b/support/texlab/src/rename/mod.rs
deleted file mode 100644
index 40bf8ce1e1..0000000000
--- a/support/texlab/src/rename/mod.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-mod bibtex_entry;
-mod latex_cmd;
-mod latex_env;
-mod latex_label;
-
-use self::{
- bibtex_entry::{BibtexEntryPrepareRenameProvider, BibtexEntryRenameProvider},
- latex_cmd::{LatexCommandPrepareRenameProvider, LatexCommandRenameProvider},
- latex_env::{LatexEnvironmentPrepareRenameProvider, LatexEnvironmentRenameProvider},
- latex_label::{LatexLabelPrepareRenameProvider, LatexLabelRenameProvider},
-};
-use crate::{
- feature::{ChoiceProvider, FeatureProvider, FeatureRequest},
- protocol::{Range, RenameParams, TextDocumentPositionParams, WorkspaceEdit},
-};
-use async_trait::async_trait;
-
-pub struct PrepareRenameProvider {
- provider: ChoiceProvider<TextDocumentPositionParams, Range>,
-}
-
-impl PrepareRenameProvider {
- pub fn new() -> Self {
- Self {
- provider: ChoiceProvider::new(vec![
- Box::new(BibtexEntryPrepareRenameProvider),
- Box::new(LatexCommandPrepareRenameProvider),
- Box::new(LatexEnvironmentPrepareRenameProvider),
- Box::new(LatexLabelPrepareRenameProvider),
- ]),
- }
- }
-}
-
-impl Default for PrepareRenameProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for PrepareRenameProvider {
- type Params = TextDocumentPositionParams;
- type Output = Option<Range>;
-
- async fn execute<'a>(
- &'a self,
- req: &'a FeatureRequest<TextDocumentPositionParams>,
- ) -> Option<Range> {
- self.provider.execute(req).await
- }
-}
-
-pub struct RenameProvider {
- provider: ChoiceProvider<RenameParams, WorkspaceEdit>,
-}
-
-impl RenameProvider {
- pub fn new() -> Self {
- Self {
- provider: ChoiceProvider::new(vec![
- Box::new(BibtexEntryRenameProvider),
- Box::new(LatexCommandRenameProvider),
- Box::new(LatexEnvironmentRenameProvider),
- Box::new(LatexLabelRenameProvider),
- ]),
- }
- }
-}
-
-impl Default for RenameProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for RenameProvider {
- type Params = RenameParams;
- type Output = Option<WorkspaceEdit>;
-
- async fn execute<'a>(
- &'a self,
- request: &'a FeatureRequest<RenameParams>,
- ) -> Option<WorkspaceEdit> {
- self.provider.execute(request).await
- }
-}
diff --git a/support/texlab/src/req_queue.rs b/support/texlab/src/req_queue.rs
new file mode 100644
index 0000000000..3fb875a8be
--- /dev/null
+++ b/support/texlab/src/req_queue.rs
@@ -0,0 +1,13 @@
+use cancellation::CancellationTokenSource;
+use crossbeam_channel::Sender;
+use lsp_server::ResponseError;
+
+pub struct IncomingData {
+ pub(crate) token_source: CancellationTokenSource,
+}
+
+pub struct OutgoingData {
+ pub(crate) sender: Sender<Result<serde_json::Value, ResponseError>>,
+}
+
+pub type ReqQueue = lsp_server::ReqQueue<IncomingData, OutgoingData>;
diff --git a/support/texlab/src/server.rs b/support/texlab/src/server.rs
index 9c5e1b857b..5a78d5e2e2 100644
--- a/support/texlab/src/server.rs
+++ b/support/texlab/src/server.rs
@@ -1,131 +1,113 @@
-#[cfg(feature = "citation")]
-use crate::citeproc::render_citation;
+use std::{
+ path::PathBuf,
+ sync::{Arc, Mutex},
+ thread,
+};
+
+use anyhow::Result;
+use cancellation::{CancellationToken, CancellationTokenSource};
+use crossbeam_channel::Sender;
+use log::{info, warn};
+use lsp_server::{Connection, ErrorCode, Message, RequestId};
+use lsp_types::{
+ notification::{
+ Cancel, DidChangeConfiguration, DidChangeTextDocument, DidOpenTextDocument,
+ DidSaveTextDocument, LogMessage, PublishDiagnostics,
+ },
+ request::{
+ DocumentLinkRequest, FoldingRangeRequest, Formatting, GotoDefinition, PrepareRenameRequest,
+ References, Rename, SemanticTokensRangeRequest,
+ },
+ *,
+};
+use notification::DidCloseTextDocument;
+use request::{
+ Completion, DocumentHighlightRequest, DocumentSymbolRequest, HoverRequest,
+ ResolveCompletionItem, WorkspaceSymbol,
+};
+use serde::Serialize;
+use threadpool::ThreadPool;
use crate::{
- build::BuildProvider,
- completion::{CompletionItemData, CompletionProvider, COMPLETION_LIMIT},
- components::COMPONENT_DATABASE,
- config::ConfigManager,
- definition::DefinitionProvider,
- diagnostics::DiagnosticsManager,
- feature::{DocumentView, FeatureProvider, FeatureRequest},
- folding::FoldingProvider,
- forward_search,
- highlight::HighlightProvider,
- hover::HoverProvider,
- link::LinkProvider,
- protocol::*,
- reference::ReferenceProvider,
- rename::{PrepareRenameProvider, RenameProvider},
- symbol::{document_symbols, workspace_symbols, SymbolProvider},
- syntax::{bibtex, latexindent, CharStream, SyntaxNode},
- tex::{Distribution, DistributionKind, KpsewhichError},
- workspace::{DocumentContent, Workspace},
+ client::send_notification,
+ component_db::COMPONENT_DATABASE,
+ config::{pull_config, push_config, register_config_capability},
+ create_workspace_full,
+ diagnostics::{DiagnosticsDebouncer, DiagnosticsManager, DiagnosticsMessage},
+ dispatch::{NotificationDispatcher, RequestDispatcher},
+ distro::Distribution,
+ features::{
+ build_document, find_all_references, find_document_highlights, find_document_links,
+ find_document_symbols, find_foldings, find_hover, find_workspace_symbols,
+ format_source_code, goto_definition, prepare_rename_all, rename_all, BuildParams,
+ BuildResult, FeatureRequest, ForwardSearchResult,
+ },
+ req_queue::{IncomingData, ReqQueue},
+ DocumentLanguage, ServerContext, Uri, Workspace, WorkspaceSource,
};
-use async_trait::async_trait;
-use chashmap::CHashMap;
-use futures::lock::Mutex;
-use jsonrpc::{server::Result, Middleware};
-use jsonrpc_derive::{jsonrpc_method, jsonrpc_server};
-use log::{debug, error, info, warn};
-use once_cell::sync::{Lazy, OnceCell};
-use std::{mem, path::PathBuf, sync::Arc};
-
-pub struct LatexLspServer<C> {
- distro: Arc<dyn Distribution>,
- client: Arc<C>,
- client_capabilities: OnceCell<Arc<ClientCapabilities>>,
- client_info: OnceCell<Option<ClientInfo>>,
- current_dir: Arc<PathBuf>,
- config_manager: OnceCell<ConfigManager<C>>,
- action_manager: ActionManager,
- workspace: Workspace,
- build_provider: BuildProvider<C>,
- completion_provider: CompletionProvider,
- definition_provider: DefinitionProvider,
- folding_provider: FoldingProvider,
- highlight_provider: HighlightProvider,
- link_provider: LinkProvider,
- reference_provider: ReferenceProvider,
- prepare_rename_provider: PrepareRenameProvider,
- rename_provider: RenameProvider,
- symbol_provider: SymbolProvider,
- hover_provider: HoverProvider,
- diagnostics_manager: DiagnosticsManager,
- last_position_by_uri: CHashMap<Uri, Position>,
+
+pub struct Server {
+ connection: Connection,
+ context: Arc<ServerContext>,
+ req_queue: Arc<Mutex<ReqQueue>>,
+ workspace: Arc<dyn Workspace>,
+ static_debouncer: DiagnosticsDebouncer,
+ chktex_debouncer: DiagnosticsDebouncer,
+ pool: ThreadPool,
+ load_resolver: bool,
}
-#[jsonrpc_server]
-impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
- pub fn new(distro: Arc<dyn Distribution>, client: Arc<C>, current_dir: Arc<PathBuf>) -> Self {
- let workspace = Workspace::new(distro.clone(), Arc::clone(&current_dir));
- Self {
- distro,
- client: Arc::clone(&client),
- client_capabilities: OnceCell::new(),
- client_info: OnceCell::new(),
- current_dir,
- config_manager: OnceCell::new(),
- action_manager: ActionManager::default(),
+impl Server {
+ pub fn with_connection(
+ connection: Connection,
+ current_dir: PathBuf,
+ load_resolver: bool,
+ ) -> Result<Self> {
+ let context = Arc::new(ServerContext::new(current_dir));
+ let req_queue = Arc::default();
+ let workspace = Arc::new(create_workspace_full(Arc::clone(&context))?);
+ let diag_manager = Arc::new(Mutex::new(DiagnosticsManager::default()));
+
+ let static_debouncer =
+ create_static_debouncer(Arc::clone(&diag_manager), &connection, Arc::clone(&context));
+
+ let chktex_debouncer =
+ create_chktex_debouncer(diag_manager, &connection, Arc::clone(&context));
+
+ Ok(Self {
+ connection,
+ context,
+ req_queue,
workspace,
- build_provider: BuildProvider::new(client),
- completion_provider: CompletionProvider::new(),
- definition_provider: DefinitionProvider::new(),
- folding_provider: FoldingProvider::new(),
- highlight_provider: HighlightProvider::new(),
- link_provider: LinkProvider::new(),
- reference_provider: ReferenceProvider::new(),
- prepare_rename_provider: PrepareRenameProvider::new(),
- rename_provider: RenameProvider::new(),
- symbol_provider: SymbolProvider::new(),
- hover_provider: HoverProvider::new(),
- diagnostics_manager: DiagnosticsManager::default(),
- last_position_by_uri: CHashMap::new(),
- }
- }
-
- fn client_capabilities(&self) -> Arc<ClientCapabilities> {
- Arc::clone(
- self.client_capabilities
- .get()
- .expect("initialize has not been called"),
- )
- }
-
- fn config_manager(&self) -> &ConfigManager<C> {
- self.config_manager
- .get()
- .expect("initialize has not been called")
+ static_debouncer,
+ chktex_debouncer,
+ pool: threadpool::Builder::new().build(),
+ load_resolver,
+ })
}
- #[jsonrpc_method("initialize", kind = "request")]
- pub async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> {
- self.client_capabilities
- .set(Arc::new(params.capabilities))
- .expect("initialize was called two times");
-
- self.client_info
- .set(params.client_info)
- .expect("initialize was called two times");
-
- let _ = self.config_manager.set(ConfigManager::new(
- Arc::clone(&self.client),
- self.client_capabilities(),
- ));
-
- let capabilities = ServerCapabilities {
+ fn capabilities(&self) -> ServerCapabilities {
+ ServerCapabilities {
text_document_sync: Some(TextDocumentSyncCapability::Options(
TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::Full),
will_save: None,
will_save_wait_until: None,
- save: Some(SaveOptions {
+ save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions {
include_text: Some(false),
- }),
+ })),
},
)),
- hover_provider: Some(true),
+ document_link_provider: Some(DocumentLinkOptions {
+ resolve_provider: Some(false),
+ work_done_progress_options: WorkDoneProgressOptions::default(),
+ }),
+ folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
+ definition_provider: Some(OneOf::Left(true)),
+ references_provider: Some(OneOf::Left(true)),
+ hover_provider: Some(HoverProviderCapability::Simple(true)),
+ #[cfg(feature = "completion")]
completion_provider: Some(CompletionOptions {
resolve_provider: Some(true),
trigger_characters: Some(vec![
@@ -138,625 +120,728 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
]),
..CompletionOptions::default()
}),
- definition_provider: Some(true),
- references_provider: Some(true),
- document_highlight_provider: Some(true),
- document_symbol_provider: Some(true),
- workspace_symbol_provider: Some(true),
- document_formatting_provider: Some(true),
- rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
+ document_symbol_provider: Some(OneOf::Left(true)),
+ workspace_symbol_provider: Some(OneOf::Left(true)),
+ rename_provider: Some(OneOf::Right(RenameOptions {
prepare_provider: Some(true),
work_done_progress_options: WorkDoneProgressOptions::default(),
})),
- document_link_provider: Some(DocumentLinkOptions {
- resolve_provider: Some(false),
- work_done_progress_options: WorkDoneProgressOptions::default(),
- }),
- folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
+ document_highlight_provider: Some(OneOf::Left(true)),
+ document_formatting_provider: Some(OneOf::Left(true)),
+ #[cfg(feature = "semantic")]
+ semantic_tokens_provider: Some(
+ SemanticTokensServerCapabilities::SemanticTokensOptions(SemanticTokensOptions {
+ full: None,
+ range: Some(true),
+ legend: SemanticTokensLegend {
+ token_types: crate::features::legend::SUPPORTED_TYPES.to_vec(),
+ token_modifiers: crate::features::legend::SUPPORTED_MODIFIERS.to_vec(),
+ },
+ work_done_progress_options: WorkDoneProgressOptions::default(),
+ }),
+ ),
..ServerCapabilities::default()
- };
+ }
+ }
+
+ fn initialize(&mut self) -> Result<()> {
+ let (id, params) = self.connection.initialize_start()?;
+ let params: InitializeParams = serde_json::from_value(params)?;
- Lazy::force(&COMPONENT_DATABASE);
- Ok(InitializeResult {
- capabilities,
+ *self.context.client_capabilities.lock().unwrap() = params.capabilities;
+ *self.context.client_info.lock().unwrap() = params.client_info;
+
+ let result = InitializeResult {
+ capabilities: self.capabilities(),
server_info: Some(ServerInfo {
name: "TexLab".to_owned(),
version: Some(env!("CARGO_PKG_VERSION").to_owned()),
}),
- })
+ };
+ self.connection
+ .initialize_finish(id, serde_json::to_value(result)?)?;
+
+ let cx = Arc::clone(&self.context);
+ if self.load_resolver {
+ self.pool.execute(move || {
+ let distro = Distribution::detect();
+ info!("Detected distribution: {}", distro.kind);
+ *cx.resolver.lock().unwrap() = distro.resolver;
+ });
+ }
+
+ self.register_diagnostics_handler();
+
+ let req_queue = Arc::clone(&self.req_queue);
+ let sender = self.connection.sender.clone();
+ let context = Arc::clone(&self.context);
+ self.pool.execute(move || {
+ register_config_capability(&req_queue, &sender, &context.client_capabilities);
+ pull_config(
+ &req_queue,
+ &sender,
+ &context.options,
+ &context.client_capabilities.lock().unwrap(),
+ );
+ });
+ Ok(())
}
- #[jsonrpc_method("initialized", kind = "notification")]
- pub async fn initialized(&self, _params: InitializedParams) {
- self.action_manager.push(Action::PullConfiguration).await;
- self.action_manager.push(Action::RegisterCapabilities).await;
- self.action_manager.push(Action::LoadDistribution).await;
- self.action_manager.push(Action::PublishDiagnostics).await;
+ fn register_diagnostics_handler(&mut self) {
+ let sender = self.static_debouncer.sender.clone();
+ self.workspace
+ .register_open_handler(Arc::new(move |workspace, document| {
+ let message = DiagnosticsMessage::Analyze {
+ workspace,
+ document,
+ };
+ sender.send(message).unwrap();
+ }));
+ }
+
+ fn register_incoming_request(&self, id: RequestId) -> Arc<CancellationToken> {
+ let token_source = CancellationTokenSource::new();
+ let token = Arc::clone(token_source.token());
+ let mut req_queue = self.req_queue.lock().unwrap();
+ req_queue
+ .incoming
+ .register(id.clone(), IncomingData { token_source });
+ token
+ }
+
+ fn cancel(&self, params: CancelParams) -> Result<()> {
+ let id = match params.id {
+ NumberOrString::Number(id) => RequestId::from(id),
+ NumberOrString::String(id) => RequestId::from(id),
+ };
+
+ let mut req_queue = self.req_queue.lock().unwrap();
+ if let Some(data) = req_queue.incoming.complete(id.clone()) {
+ data.token_source.cancel();
+ }
+
+ Ok(())
}
- #[jsonrpc_method("shutdown", kind = "request")]
- pub async fn shutdown(&self, _params: ()) -> Result<()> {
+ fn did_change_configuration(&self, params: DidChangeConfigurationParams) -> Result<()> {
+ push_config(&self.context.options, params.settings);
Ok(())
}
- #[jsonrpc_method("exit", kind = "notification")]
- pub async fn exit(&self, _params: ()) {}
-
- #[jsonrpc_method("$/cancelRequest", kind = "notification")]
- pub async fn cancel_request(&self, _params: CancelParams) {}
-
- #[jsonrpc_method("textDocument/didOpen", kind = "notification")]
- pub async fn did_open(&self, params: DidOpenTextDocumentParams) {
- let uri = params.text_document.uri.clone();
- let options = self.config_manager().get().await;
- self.workspace.add(params.text_document, &options).await;
- self.action_manager
- .push(Action::DetectRoot(uri.clone().into()))
- .await;
- self.action_manager
- .push(Action::RunLinter(uri.into(), LintReason::Save))
- .await;
- self.action_manager.push(Action::PublishDiagnostics).await;
- }
-
- #[jsonrpc_method("textDocument/didChange", kind = "notification")]
- pub async fn did_change(&self, params: DidChangeTextDocumentParams) {
- let options = self.config_manager().get().await;
- for change in params.content_changes {
- let uri = params.text_document.uri.clone();
- self.workspace
- .update(uri.into(), change.text, &options)
- .await;
- }
- self.action_manager
- .push(Action::RunLinter(
- params.text_document.uri.clone().into(),
- LintReason::Change,
- ))
- .await;
- self.action_manager.push(Action::PublishDiagnostics).await;
- }
-
- #[jsonrpc_method("textDocument/didSave", kind = "notification")]
- pub async fn did_save(&self, params: DidSaveTextDocumentParams) {
- self.action_manager
- .push(Action::Build(params.text_document.uri.clone().into()))
- .await;
-
- self.action_manager
- .push(Action::RunLinter(
- params.text_document.uri.into(),
- LintReason::Save,
- ))
- .await;
- self.action_manager.push(Action::PublishDiagnostics).await;
- }
-
- #[jsonrpc_method("textDocument/didClose", kind = "notification")]
- pub async fn did_close(&self, _params: DidCloseTextDocumentParams) {}
-
- #[jsonrpc_method("workspace/didChangeConfiguration", kind = "notification")]
- pub async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
- let config_manager = self.config_manager();
- config_manager.push(params.settings).await;
- let options = config_manager.get().await;
- self.workspace.reparse(&options).await;
- }
-
- #[jsonrpc_method("window/workDoneProgress/cancel", kind = "notification")]
- pub async fn work_done_progress_cancel(&self, params: WorkDoneProgressCancelParams) {
- self.build_provider.cancel(params.token).await;
- }
-
- #[jsonrpc_method("textDocument/completion", kind = "request")]
- pub async fn completion(&self, params: CompletionParams) -> Result<CompletionList> {
- let req = self
- .make_feature_request(params.text_document_position.text_document.as_uri(), params)
- .await?;
-
- self.last_position_by_uri.insert(
- req.current().uri.clone(),
- req.params.text_document_position.position,
+ fn did_open(&self, params: DidOpenTextDocumentParams) -> Result<()> {
+ let language_id = &params.text_document.language_id;
+ let language = DocumentLanguage::by_language_id(language_id);
+ let document = self.workspace.open(
+ Arc::new(params.text_document.uri.into()),
+ params.text_document.text,
+ language.unwrap_or(DocumentLanguage::Latex),
+ WorkspaceSource::Client,
);
- let items = self.completion_provider.execute(&req).await;
- let is_incomplete = if self
- .client_info
- .get()
- .and_then(|info| info.as_ref())
- .map(|info| info.name.as_str())
- .unwrap_or_default()
- == "vscode"
+ let should_lint = { self.context.options.read().unwrap().chktex.on_open_and_save };
+ if let Some(document) = self
+ .workspace
+ .get(document.uri.as_ref())
+ .filter(|_| should_lint)
{
- true
- } else {
- items.len() >= COMPLETION_LIMIT
+ self.chktex_debouncer
+ .sender
+ .send(DiagnosticsMessage::Analyze {
+ workspace: Arc::clone(&self.workspace),
+ document,
+ })?;
};
+ Ok(())
+ }
- Ok(CompletionList {
- is_incomplete,
- items,
- })
+ fn did_change(&self, mut params: DidChangeTextDocumentParams) -> Result<()> {
+ let uri = params.text_document.uri.into();
+ assert_eq!(params.content_changes.len(), 1);
+ let text = params.content_changes.pop().unwrap().text;
+ let language = self
+ .workspace
+ .get(&uri)
+ .map(|document| document.data.language())
+ .unwrap_or(DocumentLanguage::Latex);
+
+ let document = self
+ .workspace
+ .open(Arc::new(uri), text, language, WorkspaceSource::Client);
+
+ let should_lint = { self.context.options.read().unwrap().chktex.on_edit };
+ if let Some(document) = self
+ .workspace
+ .get(document.uri.as_ref())
+ .filter(|_| should_lint)
+ {
+ self.chktex_debouncer
+ .sender
+ .send(DiagnosticsMessage::Analyze {
+ workspace: Arc::clone(&self.workspace),
+ document,
+ })?;
+ };
+
+ Ok(())
}
- #[jsonrpc_method("completionItem/resolve", kind = "request")]
- pub async fn completion_resolve(&self, mut item: CompletionItem) -> Result<CompletionItem> {
- let data: CompletionItemData = serde_json::from_value(item.data.clone().unwrap()).unwrap();
- match data {
- CompletionItemData::Package | CompletionItemData::Class => {
- item.documentation = COMPONENT_DATABASE
- .documentation(&item.label)
- .map(Documentation::MarkupContent);
- }
- #[cfg(feature = "citation")]
- CompletionItemData::Citation { uri, key } => {
- let snapshot = self.workspace.get().await;
- if let Some(doc) = snapshot.find(&uri) {
- if let DocumentContent::Bibtex(tree) = &doc.content {
- let markup = render_citation(&tree, &key);
- item.documentation = markup.map(Documentation::MarkupContent);
- }
- }
- }
- _ => {}
+ fn did_save(&self, params: DidSaveTextDocumentParams) -> Result<()> {
+ let uri = params.text_document.uri.into();
+ let should_lint = { self.context.options.read().unwrap().chktex.on_open_and_save };
+ if let Some(document) = self.workspace.get(&uri).filter(|_| should_lint) {
+ self.chktex_debouncer
+ .sender
+ .send(DiagnosticsMessage::Analyze {
+ workspace: Arc::clone(&self.workspace),
+ document,
+ })?;
};
- Ok(item)
+ Ok(())
}
- #[jsonrpc_method("textDocument/hover", kind = "request")]
- pub async fn hover(&self, params: TextDocumentPositionParams) -> Result<Option<Hover>> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
+ fn did_close(&self, params: DidCloseTextDocumentParams) -> Result<()> {
+ let uri = params.text_document.uri.into();
+ self.workspace.close(&uri);
+ Ok(())
+ }
- self.last_position_by_uri
- .insert(req.current().uri.clone(), req.params.position);
+ fn feature_request<P>(&self, uri: Arc<Uri>, params: P) -> Option<FeatureRequest<P>> {
+ let req_queue = Arc::clone(&self.req_queue);
+ let sender = self.connection.sender.clone();
+ let cx = Arc::clone(&self.context);
+ self.pool.execute(move || {
+ pull_config(
+ &req_queue,
+ &sender,
+ &cx.options,
+ &cx.client_capabilities.lock().unwrap(),
+ );
+ });
+
+ Some(FeatureRequest {
+ context: Arc::clone(&self.context),
+ params,
+ workspace: Arc::clone(&self.workspace),
+ subset: self.workspace.subset(uri)?,
+ })
+ }
- Ok(self.hover_provider.execute(&req).await)
+ fn send_feature_error(&self, id: RequestId) -> Result<()> {
+ let resp = lsp_server::Response::new_err(
+ id,
+ ErrorCode::InternalError as i32,
+ "unknown document URI".to_string(),
+ );
+ self.connection.sender.send(resp.into())?;
+ Ok(())
}
- #[jsonrpc_method("textDocument/definition", kind = "request")]
- pub async fn definition(
+ fn handle_feature_request<P, R, H>(
&self,
- params: TextDocumentPositionParams,
- ) -> Result<DefinitionResponse> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
- let results = self.definition_provider.execute(&req).await;
- let response = if req.client_capabilities.has_definition_link_support() {
- DefinitionResponse::LocationLinks(results)
- } else {
- DefinitionResponse::Locations(
- results
- .into_iter()
- .map(|link| Location::new(link.target_uri, link.target_selection_range))
- .collect(),
- )
+ id: RequestId,
+ params: P,
+ uri: Arc<Uri>,
+ token: &Arc<CancellationToken>,
+ handler: H,
+ ) -> Result<()>
+ where
+ P: Send + 'static,
+ R: Serialize,
+ H: FnOnce(FeatureRequest<P>, &CancellationToken) -> R + Send + 'static,
+ {
+ match self.feature_request(uri, params) {
+ Some(req) => {
+ let sender = self.connection.sender.clone();
+ let token = Arc::clone(token);
+ self.pool.execute(move || {
+ let result = handler(req, &token);
+ if token.is_canceled() {
+ sender.send(cancel_response(id).into()).unwrap();
+ } else {
+ sender
+ .send(lsp_server::Response::new_ok(id, result).into())
+ .unwrap();
+ }
+ });
+ }
+ None => {
+ self.send_feature_error(id)?;
+ }
};
-
- Ok(response)
+ Ok(())
}
- #[jsonrpc_method("textDocument/references", kind = "request")]
- pub async fn references(&self, params: ReferenceParams) -> Result<Vec<Location>> {
- let req = self
- .make_feature_request(params.text_document_position.as_uri(), params)
- .await?;
- Ok(self.reference_provider.execute(&req).await)
+ fn document_link(
+ &self,
+ id: RequestId,
+ params: DocumentLinkParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(id, params, uri, token, find_document_links)?;
+ Ok(())
}
- #[jsonrpc_method("textDocument/documentHighlight", kind = "request")]
- pub async fn document_highlight(
+ fn document_symbols(
&self,
- params: TextDocumentPositionParams,
- ) -> Result<Vec<DocumentHighlight>> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
- Ok(self.highlight_provider.execute(&req).await)
+ id: RequestId,
+ params: DocumentSymbolParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(id, params, uri, token, find_document_symbols)?;
+ Ok(())
}
- #[jsonrpc_method("workspace/symbol", kind = "request")]
- pub async fn workspace_symbol(
+ fn workspace_symbols(
&self,
+ id: RequestId,
params: WorkspaceSymbolParams,
- ) -> Result<Vec<SymbolInformation>> {
- let distro = self.distro.clone();
- let client_capabilities = self.client_capabilities();
- let snapshot = self.workspace.get().await;
- let options = self.config_manager().get().await;
- let symbols = workspace_symbols(
- distro,
- client_capabilities,
- snapshot,
- &options,
- Arc::clone(&self.current_dir),
- &params,
- )
- .await;
- Ok(symbols)
- }
-
- #[jsonrpc_method("textDocument/documentSymbol", kind = "request")]
- pub async fn document_symbol(
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let sender = self.connection.sender.clone();
+ let workspace = Arc::clone(&self.workspace);
+ let token = Arc::clone(token);
+ self.pool.execute(move || {
+ let result = find_workspace_symbols(workspace.as_ref(), &params, &token);
+ if token.is_canceled() {
+ sender.send(cancel_response(id).into()).unwrap();
+ } else {
+ sender
+ .send(lsp_server::Response::new_ok(id, result).into())
+ .unwrap();
+ }
+ });
+ Ok(())
+ }
+
+ #[cfg(feature = "completion")]
+ fn completion(
&self,
- params: DocumentSymbolParams,
- ) -> Result<DocumentSymbolResponse> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
-
- let symbols = self.symbol_provider.execute(&req).await;
- let response = document_symbols(
- &req.client_capabilities,
- req.snapshot(),
- &req.current().uri,
- &req.options,
- &req.current_dir,
- symbols.into_iter().map(Into::into).collect(),
+ id: RequestId,
+ params: CompletionParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(
+ params
+ .text_document_position
+ .text_document
+ .uri
+ .clone()
+ .into(),
);
- Ok(response)
- }
-
- #[jsonrpc_method("textDocument/documentLink", kind = "request")]
- pub async fn document_link(&self, params: DocumentLinkParams) -> Result<Vec<DocumentLink>> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
- Ok(self.link_provider.execute(&req).await)
- }
-
- #[jsonrpc_method("textDocument/formatting", kind = "request")]
- pub async fn formatting(&self, params: DocumentFormattingParams) -> Result<Vec<TextEdit>> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
- let mut edits = Vec::new();
- match &req.current().content {
- DocumentContent::Latex(_) => {
- Self::run_latexindent(&req.current().text, "tex", &mut edits).await;
- }
- DocumentContent::Bibtex(tree) => {
- let options = req
- .options
- .bibtex
- .clone()
- .and_then(|opts| opts.formatting)
- .unwrap_or_default();
-
- match options.formatter.unwrap_or_default() {
- BibtexFormatter::Texlab => {
- let params = bibtex::FormattingParams {
- tab_size: req.params.options.tab_size as usize,
- insert_spaces: req.params.options.insert_spaces,
- options: &options,
- };
-
- for node in tree.children(tree.root) {
- let should_format = match &tree.graph[node] {
- bibtex::Node::Preamble(_) | bibtex::Node::String(_) => true,
- bibtex::Node::Entry(entry) => !entry.is_comment(),
- _ => false,
- };
- if should_format {
- let text = bibtex::format(&tree, node, params);
- edits.push(TextEdit::new(tree.graph[node].range(), text));
- }
+ self.handle_feature_request(id, params, uri, token, crate::features::complete)?;
+ Ok(())
+ }
+
+ #[cfg(feature = "completion")]
+ fn completion_resolve(
+ &self,
+ id: RequestId,
+ mut item: CompletionItem,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let sender = self.connection.sender.clone();
+ let token = Arc::clone(token);
+ let workspace = Arc::clone(&self.workspace);
+ self.pool.execute(move || {
+ match serde_json::from_value(item.data.clone().unwrap()).unwrap() {
+ crate::features::CompletionItemData::Package
+ | crate::features::CompletionItemData::Class => {
+ item.documentation = COMPONENT_DATABASE
+ .documentation(&item.label)
+ .map(Documentation::MarkupContent);
+ }
+ #[cfg(feature = "citeproc")]
+ crate::features::CompletionItemData::Citation { uri, key } => {
+ if let Some(document) = workspace.get(&uri) {
+ if let Some(data) = document.data.as_bibtex() {
+ let markup = crate::citation::render_citation(&data.root, &key);
+ item.documentation = markup.map(Documentation::MarkupContent);
}
}
- BibtexFormatter::Latexindent => {
- Self::run_latexindent(&req.current().text, "bib", &mut edits).await;
- }
}
+ _ => {}
+ };
+
+ drop(workspace);
+ if token.is_canceled() {
+ sender.send(cancel_response(id).into()).unwrap();
+ } else {
+ sender
+ .send(lsp_server::Response::new_ok(id, item).into())
+ .unwrap();
}
- }
- Ok(edits)
+ });
+ Ok(())
}
- async fn run_latexindent(old_text: &str, extension: &str, edits: &mut Vec<TextEdit>) {
- match latexindent::format(old_text, extension).await {
- Ok(new_text) => {
- let mut stream = CharStream::new(&old_text);
- while stream.next().is_some() {}
- let range = Range::new(Position::new(0, 0), stream.current_position);
- edits.push(TextEdit::new(range, new_text));
- }
- Err(why) => {
- debug!("Failed to run latexindent.pl: {}", why);
- }
- }
+ fn folding_range(
+ &self,
+ id: RequestId,
+ params: FoldingRangeParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(id, params, uri, token, find_foldings)?;
+ Ok(())
}
- #[jsonrpc_method("textDocument/prepareRename", kind = "request")]
- pub async fn prepare_rename(
+ fn references(
&self,
- params: TextDocumentPositionParams,
- ) -> Result<Option<Range>> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
- Ok(self.prepare_rename_provider.execute(&req).await)
- }
-
- #[jsonrpc_method("textDocument/rename", kind = "request")]
- pub async fn rename(&self, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
- let req = self
- .make_feature_request(params.text_document_position.text_document.as_uri(), params)
- .await?;
- Ok(self.rename_provider.execute(&req).await)
- }
-
- #[jsonrpc_method("textDocument/foldingRange", kind = "request")]
- pub async fn folding_range(&self, params: FoldingRangeParams) -> Result<Vec<FoldingRange>> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
- Ok(self.folding_provider.execute(&req).await)
- }
-
- #[jsonrpc_method("textDocument/build", kind = "request")]
- pub async fn build(&self, params: BuildParams) -> Result<BuildResult> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
-
- let pos = self
- .last_position_by_uri
- .get(&req.current().uri)
- .map(|pos| *pos)
- .unwrap_or_default();
-
- let res = self.build_provider.execute(&req).await;
-
- if req
- .options
- .latex
- .and_then(|opts| opts.build)
- .unwrap_or_default()
- .forward_search_after()
- && !self.build_provider.is_building()
- {
- let params = TextDocumentPositionParams::new(req.params.text_document, pos);
- self.forward_search(params).await?;
- }
+ id: RequestId,
+ params: ReferenceParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(
+ params
+ .text_document_position
+ .text_document
+ .uri
+ .clone()
+ .into(),
+ );
+ self.handle_feature_request(id, params, uri, token, find_all_references)?;
+ Ok(())
+ }
+
+ fn hover(
+ &self,
+ id: RequestId,
+ params: HoverParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(
+ params
+ .text_document_position_params
+ .text_document
+ .uri
+ .clone()
+ .into(),
+ );
+ self.handle_feature_request(id, params, uri, token, find_hover)?;
+ Ok(())
+ }
- Ok(res)
+ fn goto_definition(
+ &self,
+ id: RequestId,
+ params: GotoDefinitionParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(
+ params
+ .text_document_position_params
+ .text_document
+ .uri
+ .clone()
+ .into(),
+ );
+ self.handle_feature_request(id, params, uri, token, goto_definition)?;
+ Ok(())
}
- #[jsonrpc_method("textDocument/forwardSearch", kind = "request")]
- pub async fn forward_search(
+ fn prepare_rename(
&self,
+ id: RequestId,
params: TextDocumentPositionParams,
- ) -> Result<ForwardSearchResult> {
- let req = self
- .make_feature_request(params.text_document.as_uri(), params)
- .await?;
-
- forward_search::search(
- &req.view.snapshot,
- &req.current().uri,
- req.params.position.line,
- &req.options,
- &self.current_dir,
- )
- .await
- .ok_or_else(|| "Unable to execute forward search".into())
- }
-
- #[jsonrpc_method("$/detectRoot", kind = "request")]
- pub async fn detect_root(&self, params: TextDocumentIdentifier) -> Result<()> {
- let options = self.config_manager().get().await;
- let _ = self.workspace.detect_root(&params.as_uri(), &options).await;
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(id, params, uri, token, prepare_rename_all)?;
Ok(())
}
- async fn make_feature_request<P>(&self, uri: Uri, params: P) -> Result<FeatureRequest<P>> {
- let options = self.pull_configuration().await;
- let snapshot = self.workspace.get().await;
- let client_capabilities = self.client_capabilities();
- match snapshot.find(&uri) {
- Some(current) => Ok(FeatureRequest {
- params,
- view: DocumentView::analyze(snapshot, current, &options, &self.current_dir),
- distro: self.distro.clone(),
- client_capabilities,
- options,
- current_dir: Arc::clone(&self.current_dir),
- }),
- None => {
- let msg = format!("Unknown document: {}", uri);
- Err(msg)
- }
- }
+ fn rename(
+ &self,
+ id: RequestId,
+ params: RenameParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(
+ params
+ .text_document_position
+ .text_document
+ .uri
+ .clone()
+ .into(),
+ );
+ self.handle_feature_request(id, params, uri, token, rename_all)?;
+ Ok(())
}
- async fn pull_configuration(&self) -> Options {
- let config_manager = self.config_manager();
- let has_changed = config_manager.pull().await;
- let options = config_manager.get().await;
- if has_changed {
- self.workspace.reparse(&options).await;
- }
- options
+ fn document_highlight(
+ &self,
+ id: RequestId,
+ params: DocumentHighlightParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(
+ params
+ .text_document_position_params
+ .text_document
+ .uri
+ .clone()
+ .into(),
+ );
+ self.handle_feature_request(id, params, uri, token, find_document_highlights)?;
+ Ok(())
}
- async fn update_build_diagnostics(&self) {
- let snapshot = self.workspace.get().await;
- let options = self.config_manager().get().await;
+ fn formatting(
+ &self,
+ id: RequestId,
+ params: DocumentFormattingParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(id, params, uri, token, format_source_code)?;
+ Ok(())
+ }
- for doc in snapshot.0.iter().filter(|doc| doc.uri.scheme() == "file") {
- if let DocumentContent::Latex(table) = &doc.content {
- if table.is_standalone {
- match self
- .diagnostics_manager
- .build
- .update(&snapshot, &doc.uri, &options, &self.current_dir)
- .await
- {
- Ok(true) => self.action_manager.push(Action::PublishDiagnostics).await,
- Ok(false) => (),
- Err(why) => {
- warn!("Unable to read log file ({}): {}", why, doc.uri.as_str())
- }
- }
- }
- }
- }
+ #[cfg(feature = "semantic")]
+ fn semantic_tokens_range(
+ &self,
+ id: RequestId,
+ params: SemanticTokensRangeParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(
+ id,
+ params,
+ uri,
+ token,
+ crate::features::find_semantic_tokens_range,
+ )?;
+ Ok(())
}
- async fn load_distribution(&self) {
- info!("Detected TeX distribution: {}", self.distro.kind());
- if self.distro.kind() == DistributionKind::Unknown {
- let params = ShowMessageParams {
- message: "Your TeX distribution could not be detected. \
- Please make sure that your distribution is in your PATH."
- .into(),
- typ: MessageType::Error,
- };
- self.client.show_message(params).await;
- }
+ #[cfg(not(feature = "semantic"))]
+ fn semantic_tokens_range(
+ &self,
+ _id: RequestId,
+ _params: SemanticTokensRangeParams,
+ _token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ Ok(())
+ }
- if let Err(why) = self.distro.load().await {
- let message = match why {
- KpsewhichError::NotInstalled | KpsewhichError::InvalidOutput => {
- "An error occurred while executing `kpsewhich`.\
- Please make sure that your distribution is in your PATH \
- environment variable and provides the `kpsewhich` tool."
- }
- KpsewhichError::CorruptDatabase | KpsewhichError::NoDatabase => {
- "The file database of your TeX distribution seems \
- to be corrupt. Please rebuild it and try again."
- }
- KpsewhichError::Decode(_) => {
- "An error occurred while decoding the output of `kpsewhich`."
- }
- KpsewhichError::IO(why) => {
- error!("An I/O error occurred while executing 'kpsewhich': {}", why);
- "An I/O error occurred while executing 'kpsewhich'"
+ fn build(
+ &self,
+ id: RequestId,
+ params: BuildParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ let lsp_sender = self.connection.sender.clone();
+ self.handle_feature_request(id, params, uri, token, |request, token| {
+ let (log_sender, log_receiver) = crossbeam_channel::unbounded();
+
+ thread::spawn(move || {
+ for message in &log_receiver {
+ send_notification::<LogMessage>(
+ &lsp_sender,
+ LogMessageParams {
+ message,
+ typ: MessageType::Log,
+ },
+ )
+ .unwrap();
}
- };
- let params = ShowMessageParams {
- message: message.into(),
- typ: MessageType::Error,
- };
- self.client.show_message(params).await;
- };
+ });
+
+ build_document(request, token, log_sender)
+ })?;
+ Ok(())
}
-}
-#[async_trait]
-impl<C: LspClient + Send + Sync + 'static> Middleware for LatexLspServer<C> {
- async fn before_message(&self) {
- if let Some(config_manager) = self.config_manager.get() {
- let options = config_manager.get().await;
- self.workspace.detect_children(&options).await;
- self.workspace.reparse_all_if_newer(&options).await;
- }
+ fn forward_search(
+ &self,
+ id: RequestId,
+ params: TextDocumentPositionParams,
+ token: &Arc<CancellationToken>,
+ ) -> Result<()> {
+ let uri = Arc::new(params.text_document.uri.clone().into());
+ self.handle_feature_request(
+ id,
+ params,
+ uri,
+ token,
+ crate::features::execute_forward_search,
+ )?;
+ Ok(())
}
- async fn after_message(&self) {
- self.update_build_diagnostics().await;
- for action in self.action_manager.take().await {
- match action {
- Action::LoadDistribution => {
- self.load_distribution().await;
- }
- Action::RegisterCapabilities => {
- let config_manager = self.config_manager();
- config_manager.register().await;
- }
- Action::PullConfiguration => {
- self.pull_configuration().await;
- }
- Action::DetectRoot(uri) => {
- let options = self.config_manager().get().await;
- let _ = self.workspace.detect_root(&uri, &options).await;
- }
- Action::PublishDiagnostics => {
- let snapshot = self.workspace.get().await;
- for doc in &snapshot.0 {
- let diagnostics = self.diagnostics_manager.get(doc).await;
- let params = PublishDiagnosticsParams {
- uri: doc.uri.clone().into(),
- diagnostics,
- version: None,
- };
- self.client.publish_diagnostics(params).await;
+ fn process_messages(&self) -> Result<()> {
+ for msg in &self.connection.receiver {
+ match msg {
+ Message::Request(request) => {
+ if self.connection.handle_shutdown(&request)? {
+ return Ok(());
}
- }
- Action::Build(uri) => {
- let options = self
- .config_manager()
- .get()
- .await
- .latex
- .and_then(|opts| opts.build)
- .unwrap_or_default();
-
- if options.on_save() {
- let text_document = TextDocumentIdentifier::new(uri.into());
- self.build(BuildParams { text_document }).await.unwrap();
+
+ let token = self.register_incoming_request(request.id.clone());
+ if let Some(response) = RequestDispatcher::new(request)
+ .on::<DocumentLinkRequest, _>(|id, params| {
+ self.document_link(id, params, &token)
+ })?
+ .on::<FoldingRangeRequest, _>(|id, params| {
+ self.folding_range(id, params, &token)
+ })?
+ .on::<References, _>(|id, params| self.references(id, params, &token))?
+ .on::<HoverRequest, _>(|id, params| self.hover(id, params, &token))?
+ .on::<DocumentSymbolRequest, _>(|id, params| {
+ self.document_symbols(id, params, &token)
+ })?
+ .on::<WorkspaceSymbol, _>(|id, params| {
+ self.workspace_symbols(id, params, &token)
+ })?
+ .on::<Completion, _>(|id, params| {
+ #[cfg(feature = "completion")]
+ self.completion(id, params, &token)?;
+ Ok(())
+ })?
+ .on::<ResolveCompletionItem, _>(|id, params| {
+ #[cfg(feature = "completion")]
+ self.completion_resolve(id, params, &token)?;
+ Ok(())
+ })?
+ .on::<GotoDefinition, _>(|id, params| {
+ self.goto_definition(id, params, &token)
+ })?
+ .on::<PrepareRenameRequest, _>(|id, params| {
+ self.prepare_rename(id, params, &token)
+ })?
+ .on::<Rename, _>(|id, params| self.rename(id, params, &token))?
+ .on::<DocumentHighlightRequest, _>(|id, params| {
+ self.document_highlight(id, params, &token)
+ })?
+ .on::<Formatting, _>(|id, params| self.formatting(id, params, &token))?
+ .on::<BuildRequest, _>(|id, params| self.build(id, params, &token))?
+ .on::<ForwardSearchRequest, _>(|id, params| {
+ self.forward_search(id, params, &token)
+ })?
+ .on::<SemanticTokensRangeRequest, _>(|id, params| {
+ self.semantic_tokens_range(id, params, &token)
+ })?
+ .default()
+ {
+ self.connection.sender.send(response.into())?;
}
}
- Action::RunLinter(uri, reason) => {
- let options = self
- .config_manager()
- .get()
- .await
- .latex
- .and_then(|opts| opts.lint)
- .unwrap_or_default();
-
- let should_lint = match reason {
- LintReason::Change => options.on_change(),
- LintReason::Save => options.on_save() || options.on_change(),
+ Message::Notification(notification) => {
+ NotificationDispatcher::new(notification)
+ .on::<Cancel, _>(|params| self.cancel(params))?
+ .on::<DidChangeConfiguration, _>(|params| {
+ self.did_change_configuration(params)
+ })?
+ .on::<DidOpenTextDocument, _>(|params| self.did_open(params))?
+ .on::<DidChangeTextDocument, _>(|params| self.did_change(params))?
+ .on::<DidSaveTextDocument, _>(|params| self.did_save(params))?
+ .on::<DidCloseTextDocument, _>(|params| self.did_close(params))?
+ .default();
+ }
+ Message::Response(response) => {
+ let mut req_queue = self.req_queue.lock().unwrap();
+ let data = req_queue.outgoing.complete(response.id);
+ let result = match response.result {
+ Some(result) => Ok(result),
+ None => Err(response
+ .error
+ .expect("response without result or error received")),
};
-
- if should_lint {
- let snapshot = self.workspace.get().await;
- if let Some(doc) = snapshot.find(&uri) {
- if let DocumentContent::Latex(_) = &doc.content {
- self.diagnostics_manager.latex.update(&uri, &doc.text).await;
- }
- }
- }
+ data.sender.send(result)?;
}
}
}
+ Ok(())
+ }
+
+ pub fn run(mut self) -> Result<()> {
+ self.initialize()?;
+ self.process_messages()?;
+ drop(self.static_debouncer);
+ drop(self.chktex_debouncer);
+ self.pool.join();
+ Ok(())
}
}
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-enum LintReason {
- Change,
- Save,
+fn create_static_debouncer(
+ manager: Arc<Mutex<DiagnosticsManager>>,
+ conn: &Connection,
+ context: Arc<ServerContext>,
+) -> DiagnosticsDebouncer {
+ let sender = conn.sender.clone();
+ DiagnosticsDebouncer::launch(context, move |workspace, document| {
+ let mut manager = manager.lock().unwrap();
+ manager.update_static(workspace.as_ref(), Arc::clone(&document.uri));
+ if let Err(why) = publish_diagnostics(&sender, workspace.as_ref(), &manager) {
+ warn!("Failed to publish diagnostics: {}", why);
+ }
+ })
}
-#[derive(Debug, PartialEq, Clone)]
-enum Action {
- LoadDistribution,
- RegisterCapabilities,
- PullConfiguration,
- DetectRoot(Uri),
- PublishDiagnostics,
- Build(Uri),
- RunLinter(Uri, LintReason),
+fn create_chktex_debouncer(
+ manager: Arc<Mutex<DiagnosticsManager>>,
+ conn: &Connection,
+ context: Arc<ServerContext>,
+) -> DiagnosticsDebouncer {
+ let sender = conn.sender.clone();
+ DiagnosticsDebouncer::launch(Arc::clone(&context), move |workspace, document| {
+ let options = { context.options.read().unwrap().clone() };
+ let mut manager = manager.lock().unwrap();
+ manager.update_chktex(workspace.as_ref(), Arc::clone(&document.uri), &options);
+ if let Err(why) = publish_diagnostics(&sender, workspace.as_ref(), &manager) {
+ warn!("Failed to publish diagnostics: {}", why);
+ }
+ })
}
-#[derive(Debug, Default)]
-struct ActionManager {
- actions: Mutex<Vec<Action>>,
+fn publish_diagnostics(
+ sender: &Sender<lsp_server::Message>,
+ workspace: &dyn Workspace,
+ diag_manager: &DiagnosticsManager,
+) -> Result<()> {
+ for document in workspace.documents() {
+ let diagnostics = diag_manager.publish(Arc::clone(&document.uri));
+ send_notification::<PublishDiagnostics>(
+ sender,
+ PublishDiagnosticsParams {
+ uri: document.uri.as_ref().clone().into(),
+ version: None,
+ diagnostics,
+ },
+ )?;
+ }
+ Ok(())
}
-impl ActionManager {
- pub async fn push(&self, action: Action) {
- let mut actions = self.actions.lock().await;
- actions.push(action);
- }
+fn cancel_response(id: RequestId) -> lsp_server::Response {
+ lsp_server::Response::new_err(
+ id,
+ ErrorCode::RequestCanceled as i32,
+ "canceled by client".to_string(),
+ )
+}
- pub async fn take(&self) -> Vec<Action> {
- let mut actions = self.actions.lock().await;
- mem::replace(&mut *actions, Vec::new())
- }
+struct BuildRequest;
+
+impl lsp_types::request::Request for BuildRequest {
+ type Params = BuildParams;
+
+ type Result = BuildResult;
+
+ const METHOD: &'static str = "textDocument/build";
+}
+
+struct ForwardSearchRequest;
+
+impl lsp_types::request::Request for ForwardSearchRequest {
+ type Params = TextDocumentPositionParams;
+
+ type Result = ForwardSearchResult;
+
+ const METHOD: &'static str = "textDocument/forwardSearch";
}
diff --git a/support/texlab/src/symbol/bibtex_entry.rs b/support/texlab/src/symbol/bibtex_entry.rs
deleted file mode 100644
index f719937e80..0000000000
--- a/support/texlab/src/symbol/bibtex_entry.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-use super::types::{LatexSymbol, LatexSymbolKind};
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::DocumentSymbolParams,
- syntax::{bibtex, BibtexEntryTypeCategory, SyntaxNode, LANGUAGE_DATA},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use petgraph::graph::NodeIndex;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexEntrySymbolProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexEntrySymbolProvider {
- type Params = DocumentSymbolParams;
- type Output = Vec<LatexSymbol>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut symbols = Vec::new();
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- for entry_node in tree.children(tree.root) {
- if let Some(entry) = tree
- .as_entry(entry_node)
- .filter(|entry| !entry.is_comment())
- .filter(|entry| entry.key.is_some())
- {
- let category = LANGUAGE_DATA
- .find_entry_type(&entry.ty.text()[1..])
- .map(|ty| ty.category)
- .unwrap_or(BibtexEntryTypeCategory::Misc);
-
- let key = entry.key.as_ref().unwrap();
- let symbol = LatexSymbol {
- name: key.text().to_owned(),
- label: None,
- kind: LatexSymbolKind::Entry(category),
- deprecated: false,
- full_range: entry.range(),
- selection_range: key.range(),
- children: Self::field_symbols(tree, entry_node),
- };
- symbols.push(symbol);
- }
- }
- }
- symbols
- }
-}
-
-impl BibtexEntrySymbolProvider {
- fn field_symbols(tree: &bibtex::Tree, entry_node: NodeIndex) -> Vec<LatexSymbol> {
- let mut symbols = Vec::new();
- for field in tree
- .children(entry_node)
- .filter_map(|node| tree.as_field(node))
- {
- let symbol = LatexSymbol {
- name: field.name.text().to_owned(),
- label: None,
- kind: LatexSymbolKind::Field,
- deprecated: false,
- full_range: field.range(),
- selection_range: field.name.range(),
- children: Vec::new(),
- };
- symbols.push(symbol);
- }
- symbols
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_symbols = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .test_symbol(BibtexEntrySymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_symbol(BibtexEntrySymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-
- #[tokio::test]
- async fn entry() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", r#"@article{key, foo = bar, baz = qux}"#)
- .main("main.bib")
- .test_symbol(BibtexEntrySymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "key".into(),
- label: None,
- kind: LatexSymbolKind::Entry(BibtexEntryTypeCategory::Article),
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 35),
- selection_range: Range::new_simple(0, 9, 0, 12),
- children: vec![
- LatexSymbol {
- name: "foo".into(),
- label: None,
- kind: LatexSymbolKind::Field,
- deprecated: false,
- full_range: Range::new_simple(0, 14, 0, 24),
- selection_range: Range::new_simple(0, 14, 0, 17),
- children: Vec::new(),
- },
- LatexSymbol {
- name: "baz".into(),
- label: None,
- kind: LatexSymbolKind::Field,
- deprecated: false,
- full_range: Range::new_simple(0, 25, 0, 34),
- selection_range: Range::new_simple(0, 25, 0, 28),
- children: Vec::new(),
- },
- ],
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn comment() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", r#"@comment{key, foo = bar, baz = qux}"#)
- .main("main.bib")
- .test_symbol(BibtexEntrySymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-}
diff --git a/support/texlab/src/symbol/bibtex_string.rs b/support/texlab/src/symbol/bibtex_string.rs
deleted file mode 100644
index d2283f640b..0000000000
--- a/support/texlab/src/symbol/bibtex_string.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use super::types::{LatexSymbol, LatexSymbolKind};
-use crate::{
- feature::{FeatureProvider, FeatureRequest},
- protocol::DocumentSymbolParams,
- syntax::SyntaxNode,
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct BibtexStringSymbolProvider;
-
-#[async_trait]
-impl FeatureProvider for BibtexStringSymbolProvider {
- type Params = DocumentSymbolParams;
- type Output = Vec<LatexSymbol>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut symbols = Vec::new();
- if let DocumentContent::Bibtex(tree) = &req.current().content {
- for string_node in tree.children(tree.root) {
- if let Some(string) = &tree.as_string(string_node) {
- if let Some(name) = &string.name {
- symbols.push(LatexSymbol {
- name: name.text().into(),
- label: None,
- kind: LatexSymbolKind::String,
- deprecated: false,
- full_range: string.range(),
- selection_range: name.range(),
- children: Vec::new(),
- });
- }
- }
- }
- }
- symbols
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- feature::FeatureTester,
- protocol::{Range, RangeExt},
- };
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_symbols = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .test_symbol(BibtexStringSymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_symbol(BibtexStringSymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-
- #[tokio::test]
- async fn valid() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", r#"@string{key = "value"}"#)
- .main("main.bib")
- .test_symbol(BibtexStringSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "key".into(),
- label: None,
- kind: LatexSymbolKind::String,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 22),
- selection_range: Range::new_simple(0, 8, 0, 11),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn invalid() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", r#"@string{}"#)
- .main("main.bib")
- .test_symbol(BibtexStringSymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-}
diff --git a/support/texlab/src/symbol/latex_section/enumeration.rs b/support/texlab/src/symbol/latex_section/enumeration.rs
deleted file mode 100644
index e96a856eac..0000000000
--- a/support/texlab/src/symbol/latex_section/enumeration.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-use super::{label_name, selection_range};
-use crate::{
- feature::DocumentView,
- outline::OutlineContext,
- protocol::{Range, RangeExt},
- symbol::types::{LatexSymbol, LatexSymbolKind},
- syntax::{latex, SyntaxNode},
-};
-use titlecase::titlecase;
-
-pub fn symbols(view: &DocumentView, table: &latex::SymbolTable) -> Vec<LatexSymbol> {
- table
- .environments
- .iter()
- .filter(|env| env.left.is_enum(&table))
- .map(|enumeration| make_symbol(view, table, *enumeration))
- .collect()
-}
-
-fn make_symbol(
- view: &DocumentView,
- table: &latex::SymbolTable,
- enumeration: latex::Environment,
-) -> LatexSymbol {
- let name = titlecase(enumeration.left.name(&table).unwrap().text());
-
- let items: Vec<_> = table
- .items
- .iter()
- .filter(|item| table.is_enum_item(enumeration, **item))
- .collect();
-
- let mut children = Vec::new();
- for i in 0..items.len() {
- let start = table[items[i].parent].start();
- let end = items
- .get(i + 1)
- .map(|item| table[item.parent].start())
- .unwrap_or_else(|| table[enumeration.right.parent].start());
- let range = Range::new(start, end);
-
- let label = find_item_label(table, range);
-
- let number = items[i]
- .name(&table)
- .or_else(|| label.and_then(|label| OutlineContext::find_number(view, table, *label)));
-
- let name = number.unwrap_or_else(|| "Item".into());
- children.push(LatexSymbol {
- name,
- label: label_name(table, label),
- kind: LatexSymbolKind::EnumerationItem,
- deprecated: false,
- full_range: range,
- selection_range: selection_range(table, table[items[i].parent].range(), label),
- children: Vec::new(),
- });
- }
-
- LatexSymbol {
- name,
- label: None,
- kind: LatexSymbolKind::Enumeration,
- deprecated: false,
- full_range: enumeration.range(&table),
- selection_range: enumeration.range(&table),
- children,
- }
-}
-
-fn find_item_label(table: &latex::SymbolTable, item_range: Range) -> Option<&latex::Label> {
- table.find_label_by_range(item_range).filter(|label| {
- table
- .environments
- .iter()
- .filter(|env| item_range.contains(env.range(&table).start))
- .all(|env| !env.range(&table).contains(table[label.parent].start()))
- })
-}
diff --git a/support/texlab/src/symbol/latex_section/equation.rs b/support/texlab/src/symbol/latex_section/equation.rs
deleted file mode 100644
index 2889aefd4d..0000000000
--- a/support/texlab/src/symbol/latex_section/equation.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use super::{label_name, selection_range};
-use crate::{
- feature::DocumentView,
- outline::OutlineContext,
- protocol::Range,
- symbol::types::{LatexSymbol, LatexSymbolKind},
- syntax::latex,
-};
-
-pub fn symbols(view: &DocumentView, table: &latex::SymbolTable) -> Vec<LatexSymbol> {
- let mut symbols = Vec::new();
- for equation in &table.equations {
- symbols.push(make_symbol(view, table, equation.range(&table)));
- }
-
- for equation in &table.environments {
- if equation.left.is_math(&table) {
- symbols.push(make_symbol(view, table, equation.range(&table)));
- }
- }
- symbols
-}
-
-fn make_symbol(view: &DocumentView, table: &latex::SymbolTable, full_range: Range) -> LatexSymbol {
- let label = table.find_label_by_range(full_range);
-
- let name = match label.and_then(|label| OutlineContext::find_number(view, table, *label)) {
- Some(num) => format!("Equation ({})", num),
- None => "Equation".to_owned(),
- };
-
- LatexSymbol {
- name,
- label: label_name(table, label),
- kind: LatexSymbolKind::Equation,
- deprecated: false,
- full_range,
- selection_range: selection_range(table, full_range, label),
- children: Vec::new(),
- }
-}
diff --git a/support/texlab/src/symbol/latex_section/float.rs b/support/texlab/src/symbol/latex_section/float.rs
deleted file mode 100644
index 7ade3602cf..0000000000
--- a/support/texlab/src/symbol/latex_section/float.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use super::{label_name, selection_range};
-use crate::{
- feature::DocumentView,
- outline::{OutlineCaptionKind, OutlineContext},
- symbol::types::{LatexSymbol, LatexSymbolKind},
- syntax::{latex, SyntaxNode},
-};
-
-pub fn symbols(view: &DocumentView, table: &latex::SymbolTable) -> Vec<LatexSymbol> {
- table
- .captions
- .iter()
- .filter_map(|caption| make_symbol(view, table, *caption))
- .collect()
-}
-
-fn make_symbol(
- view: &DocumentView,
- table: &latex::SymbolTable,
- caption: latex::Caption,
-) -> Option<LatexSymbol> {
- let env = table
- .environments
- .iter()
- .find(|env| table.is_direct_child(**env, table[caption.parent].start()))?;
-
- let text =
- table.print_group_content(caption.parent, latex::GroupKind::Group, caption.arg_index)?;
-
- let kind = env
- .left
- .name(&table)
- .map(latex::Token::text)
- .and_then(OutlineCaptionKind::parse)?;
-
- let label = table.find_label_by_environment(*env);
- let number = label.and_then(|label| OutlineContext::find_number(view, table, *label));
-
- let name = match &number {
- Some(number) => format!("{} {}: {}", kind.as_str(), number, text),
- None => format!("{}: {}", kind.as_str(), text),
- };
-
- let symbol = LatexSymbol {
- name,
- label: label_name(table, label),
- kind: match kind {
- OutlineCaptionKind::Figure => LatexSymbolKind::Figure,
- OutlineCaptionKind::Table => LatexSymbolKind::Table,
- OutlineCaptionKind::Listing => LatexSymbolKind::Listing,
- OutlineCaptionKind::Algorithm => LatexSymbolKind::Algorithm,
- },
- deprecated: false,
- full_range: env.range(&table),
- selection_range: selection_range(table, env.range(&table), label),
- children: Vec::new(),
- };
- Some(symbol)
-}
diff --git a/support/texlab/src/symbol/latex_section/mod.rs b/support/texlab/src/symbol/latex_section/mod.rs
deleted file mode 100644
index fc81695b50..0000000000
--- a/support/texlab/src/symbol/latex_section/mod.rs
+++ /dev/null
@@ -1,671 +0,0 @@
-mod enumeration;
-mod equation;
-mod float;
-mod theorem;
-
-use super::types::{LatexSymbol, LatexSymbolKind};
-use crate::{
- feature::{DocumentView, FeatureProvider, FeatureRequest},
- outline::{Outline, OutlineContext, OutlineContextItem},
- protocol::{DocumentSymbolParams, Options, Position, Range, RangeExt},
- syntax::{latex, CharStream, LatexLabelKind, SyntaxNode},
- workspace::DocumentContent,
-};
-use async_trait::async_trait;
-use std::path::Path;
-
-fn label_name(table: &latex::SymbolTable, label: Option<&latex::Label>) -> Option<String> {
- label.map(|label| label.names(&table)[0].text().to_owned())
-}
-
-fn selection_range(
- table: &latex::SymbolTable,
- full_range: Range,
- label: Option<&latex::Label>,
-) -> Range {
- label
- .map(|label| table[label.parent].range())
- .unwrap_or(full_range)
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-pub struct LatexSectionSymbolProvider;
-
-#[async_trait]
-impl FeatureProvider for LatexSectionSymbolProvider {
- type Params = DocumentSymbolParams;
- type Output = Vec<LatexSymbol>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- let mut symbols = Vec::new();
- if let DocumentContent::Latex(table) = &req.current().content {
- let mut section_tree =
- build_section_tree(&req.view, table, &req.options, &req.current_dir);
- for symbol in enumeration::symbols(&req.view, table) {
- section_tree.insert_symbol(&symbol);
- }
-
- for symbol in equation::symbols(&req.view, table) {
- section_tree.insert_symbol(&symbol);
- }
-
- for symbol in float::symbols(&req.view, table) {
- section_tree.insert_symbol(&symbol);
- }
-
- for symbol in theorem::symbols(&req.view, table) {
- section_tree.insert_symbol(&symbol);
- }
-
- for symbol in section_tree.symbols {
- symbols.push(symbol);
- }
-
- for child in section_tree.children {
- symbols.push(child.into());
- }
- }
- symbols
- }
-}
-
-pub fn build_section_tree<'a>(
- view: &'a DocumentView,
- table: &'a latex::SymbolTable,
- options: &'a Options,
- current_dir: &'a Path,
-) -> LatexSectionTree<'a> {
- let mut section_tree = LatexSectionTree::from(table);
- section_tree.set_full_text(&view.current.text);
- let end_position = compute_end_position(table, &view.current.text);
- LatexSectionNode::set_full_range(&mut section_tree.children, table, end_position);
- let outline = Outline::analyze(view, options, current_dir);
- for child in &mut section_tree.children {
- child.set_label(view, &outline);
- }
- section_tree
-}
-
-fn compute_end_position(table: &latex::SymbolTable, text: &str) -> Position {
- let mut stream = CharStream::new(text);
- while stream.next().is_some() {}
- table
- .environments
- .iter()
- .find(|env| env.left.name(&table).map(latex::Token::text) == Some("document"))
- .map(|env| table[env.right.parent].start())
- .unwrap_or(stream.current_position)
-}
-
-#[derive(Debug, Clone)]
-pub struct LatexSectionNode<'a> {
- pub table: &'a latex::SymbolTable,
- pub section: &'a latex::Section,
- pub full_range: Range,
- full_text: &'a str,
- label: Option<String>,
- number: Option<String>,
- symbols: Vec<LatexSymbol>,
- children: Vec<Self>,
-}
-
-impl<'a> LatexSectionNode<'a> {
- fn new(table: &'a latex::SymbolTable, section: &'a latex::Section) -> Self {
- Self {
- table,
- section,
- full_range: Range::default(),
- full_text: "",
- label: None,
- number: None,
- symbols: Vec::new(),
- children: Vec::new(),
- }
- }
-
- fn set_full_text(&mut self, full_text: &'a str) {
- self.full_text = full_text;
- for child in &mut self.children {
- child.set_full_text(full_text);
- }
- }
-
- fn name(&self) -> String {
- self.table
- .print_group_content(
- self.section.parent,
- latex::GroupKind::Group,
- self.section.arg_index,
- )
- .unwrap_or_else(|| "Unknown".into())
- }
-
- fn set_full_range(
- children: &mut Vec<Self>,
- table: &latex::SymbolTable,
- end_position: Position,
- ) {
- for i in 0..children.len() {
- let current_end = children
- .get(i + 1)
- .map(|next| table[next.section.parent].start())
- .unwrap_or(end_position);
-
- let mut current = &mut children[i];
- current.full_range = Range::new(table[current.section.parent].start(), current_end);
- Self::set_full_range(&mut current.children, table, current_end);
- }
- }
-
- fn set_label(&mut self, view: &DocumentView, outline: &Outline) {
- if let Some(label) = self
- .table
- .labels
- .iter()
- .filter(|label| label.kind == LatexLabelKind::Definition)
- .find(|label| self.full_range.contains(self.table[label.parent].start()))
- {
- if let Some(ctx) = OutlineContext::parse(view, outline, *label) {
- let mut is_section = false;
- if let OutlineContextItem::Section { text, .. } = &ctx.item {
- if self.name() == *text {
- for name in label.names(&self.table) {
- self.label = Some(name.text().to_owned());
- }
-
- is_section = true;
- }
- }
-
- if is_section {
- self.number = ctx.number;
- }
- }
- }
-
- for child in &mut self.children {
- child.set_label(view, outline);
- }
- }
-
- fn insert_section(
- nodes: &mut Vec<Self>,
- table: &'a latex::SymbolTable,
- section: &'a latex::Section,
- ) {
- match nodes.last_mut() {
- Some(parent) => {
- if parent.section.level < section.level {
- Self::insert_section(&mut parent.children, table, section);
- } else {
- nodes.push(LatexSectionNode::new(table, section));
- }
- }
- None => {
- nodes.push(LatexSectionNode::new(table, section));
- }
- }
- }
-
- fn insert_symbol(&mut self, symbol: &LatexSymbol) -> bool {
- if !self.full_range.contains(symbol.selection_range.start) {
- return false;
- }
-
- for child in &mut self.children {
- if child.insert_symbol(symbol) {
- return true;
- }
- }
-
- self.symbols.push(symbol.clone());
- true
- }
-
- fn find(&self, label: &str) -> Option<&Self> {
- if self.label.as_ref().map(AsRef::as_ref) == Some(label) {
- Some(self)
- } else {
- for child in &self.children {
- let result = child.find(label);
- if result.is_some() {
- return result;
- }
- }
- None
- }
- }
-}
-
-impl<'a> Into<LatexSymbol> for LatexSectionNode<'a> {
- fn into(self) -> LatexSymbol {
- let name = self.name();
-
- let mut children: Vec<LatexSymbol> = self.children.into_iter().map(Into::into).collect();
-
- for symbol in self.symbols {
- children.push(symbol);
- }
-
- let full_name = match &self.number {
- Some(number) => format!("{} {}", number, name),
- None => name,
- };
-
- LatexSymbol {
- name: full_name,
- label: self.label,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: self.full_range,
- selection_range: self.table[self.section.parent].range(),
- children,
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct LatexSectionTree<'a> {
- symbols: Vec<LatexSymbol>,
- children: Vec<LatexSectionNode<'a>>,
-}
-
-impl<'a> LatexSectionTree<'a> {
- fn new() -> Self {
- Self {
- symbols: Vec::new(),
- children: Vec::new(),
- }
- }
-
- fn set_full_text(&mut self, full_text: &'a str) {
- for child in &mut self.children {
- child.set_full_text(full_text);
- }
- }
-
- fn insert_symbol(&mut self, symbol: &LatexSymbol) {
- for child in &mut self.children {
- if child.insert_symbol(symbol) {
- return;
- }
- }
- self.symbols.push(symbol.clone());
- }
-
- pub fn find(&self, label: &str) -> Option<&LatexSectionNode<'a>> {
- for child in &self.children {
- let result = child.find(label);
- if result.is_some() {
- return result;
- }
- }
- None
- }
-}
-
-impl<'a> From<&'a latex::SymbolTable> for LatexSectionTree<'a> {
- fn from(table: &'a latex::SymbolTable) -> Self {
- let mut root = Self::new();
- for section in &table.sections {
- LatexSectionNode::insert_section(&mut root.children, table, section);
- }
- root
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::feature::FeatureTester;
- use indoc::indoc;
-
- #[tokio::test]
- async fn empty_latex_document() {
- let actual_symbols = FeatureTester::new()
- .file("main.tex", "")
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-
- #[tokio::test]
- async fn empty_bibtex_document() {
- let actual_symbols = FeatureTester::new()
- .file("main.bib", "")
- .main("main.bib")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- assert!(actual_symbols.is_empty());
- }
-
- #[tokio::test]
- async fn subsection() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \section{Foo}
- \subsection{Bar}\label{sec:bar}
- \subsection{Baz}
- \section{Qux}
- "#
- ),
- )
- .file(
- "main.aux",
- r#"\newlabel{sec:bar}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![
- LatexSymbol {
- name: "Foo".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 3, 0),
- selection_range: Range::new_simple(0, 0, 0, 13),
- children: vec![
- LatexSymbol {
- name: "2.1 Bar".into(),
- label: Some("sec:bar".into()),
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 2, 0),
- selection_range: Range::new_simple(1, 0, 1, 16),
- children: Vec::new(),
- },
- LatexSymbol {
- name: "Baz".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(2, 0, 3, 0),
- selection_range: Range::new_simple(2, 0, 2, 16),
- children: Vec::new(),
- },
- ],
- },
- LatexSymbol {
- name: "Qux".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(3, 0, 3, 13),
- selection_range: Range::new_simple(3, 0, 3, 13),
- children: Vec::new(),
- },
- ];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn section_inside_document_environment() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{document}\section{Foo}\relax
- \end{document}
- "#
- ),
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Foo".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(0, 16, 1, 0),
- selection_range: Range::new_simple(0, 16, 0, 29),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn enumeration() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \section{Foo}
- \begin{enumerate}
- \end{enumerate}
- "#
- ),
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Foo".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 2, 15),
- selection_range: Range::new_simple(0, 0, 0, 13),
- children: vec![LatexSymbol {
- name: "Enumerate".into(),
- label: None,
- kind: LatexSymbolKind::Enumeration,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 2, 15),
- selection_range: Range::new_simple(1, 0, 2, 15),
- children: Vec::new(),
- }],
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn equation() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \[Foo\]
- \begin{equation}\label{eq:foo}\end{equation}
- "#
- ),
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![
- LatexSymbol {
- name: "Equation".into(),
- label: None,
- kind: LatexSymbolKind::Equation,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 7),
- selection_range: Range::new_simple(0, 0, 0, 7),
- children: Vec::new(),
- },
- LatexSymbol {
- name: "Equation".into(),
- label: Some("eq:foo".into()),
- kind: LatexSymbolKind::Equation,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 1, 44),
- selection_range: Range::new_simple(1, 16, 1, 30),
- children: Vec::new(),
- },
- ];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn equation_number() {
- let actual_symbols = FeatureTester::new()
- .file("main.tex", r#"\[\label{eq:foo}\]"#)
- .file(
- "main.aux",
- r#"\newlabel{eq:foo}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Equation (2.1)".into(),
- label: Some("eq:foo".into()),
- kind: LatexSymbolKind::Equation,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 18),
- selection_range: Range::new_simple(0, 2, 0, 16),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn table() {
- let actual_symbols = FeatureTester::new()
- .file("main.tex", r#"\begin{table}\caption{Foo}\end{table}"#)
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Table: Foo".into(),
- label: None,
- kind: LatexSymbolKind::Table,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 37),
- selection_range: Range::new_simple(0, 0, 0, 37),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn figure_number() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- r#"\begin{figure}\caption{Foo}\label{fig:foo}\end{figure}"#,
- )
- .file(
- "main.aux",
- r#"\newlabel{fig:foo}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Figure 2.1: Foo".into(),
- label: Some("fig:foo".into()),
- kind: LatexSymbolKind::Figure,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 54),
- selection_range: Range::new_simple(0, 27, 0, 42),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn lemma() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- r#"\newtheorem{lemma}{Lemma}\begin{lemma}\end{lemma}"#,
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Lemma".into(),
- label: None,
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: Range::new_simple(0, 25, 0, 49),
- selection_range: Range::new_simple(0, 25, 0, 49),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn lemma_number() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \newtheorem{lemma}{Lemma}
- \begin{lemma}\label{thm:foo}\end{lemma}
- "#
- ),
- )
- .file(
- "main.aux",
- r#"\newlabel{thm:foo}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Lemma 2.1".into(),
- label: Some("thm:foo".into()),
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 1, 39),
- selection_range: Range::new_simple(1, 13, 1, 28),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-
- #[tokio::test]
- async fn lemma_description() {
- let actual_symbols = FeatureTester::new()
- .file(
- "main.tex",
- r#"\newtheorem{lemma}{Lemma}\begin{lemma}[Foo]\end{lemma}"#,
- )
- .main("main.tex")
- .test_symbol(LatexSectionSymbolProvider)
- .await;
-
- let expected_symbols = vec![LatexSymbol {
- name: "Lemma (Foo)".into(),
- label: None,
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: Range::new_simple(0, 25, 0, 54),
- selection_range: Range::new_simple(0, 25, 0, 54),
- children: Vec::new(),
- }];
-
- assert_eq!(actual_symbols, expected_symbols);
- }
-}
diff --git a/support/texlab/src/symbol/latex_section/theorem.rs b/support/texlab/src/symbol/latex_section/theorem.rs
deleted file mode 100644
index dac231fbfa..0000000000
--- a/support/texlab/src/symbol/latex_section/theorem.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use super::{label_name, selection_range};
-use crate::{
- feature::DocumentView,
- outline::OutlineContext,
- symbol::types::{LatexSymbol, LatexSymbolKind},
- syntax::latex,
- workspace::DocumentContent,
-};
-use titlecase::titlecase;
-
-pub fn symbols(view: &DocumentView, table: &latex::SymbolTable) -> Vec<LatexSymbol> {
- table
- .environments
- .iter()
- .filter_map(|env| make_symbol(view, table, *env))
- .collect()
-}
-
-fn make_symbol(
- view: &DocumentView,
- main_table: &latex::SymbolTable,
- env: latex::Environment,
-) -> Option<LatexSymbol> {
- let env_name = env.left.name(&main_table).map(latex::Token::text)?;
-
- for document in &view.related {
- if let DocumentContent::Latex(table) = &document.content {
- for definition in &table.theorem_definitions {
- if definition.name(&table).text() == env_name {
- let kind = table
- .print_group_content(
- definition.parent,
- latex::GroupKind::Group,
- definition.arg_index + 1,
- )
- .unwrap_or_else(|| titlecase(env_name));
-
- let desc = main_table.print_group_content(
- env.left.parent,
- latex::GroupKind::Options,
- 0,
- );
-
- let label = main_table.find_label_by_environment(env);
- let number = label
- .and_then(|label| OutlineContext::find_number(view, &main_table, *label));
-
- let name = match (desc, number) {
- (Some(desc), Some(num)) => format!("{} {} ({})", kind, num, desc),
- (Some(desc), None) => format!("{} ({})", kind, desc),
- (None, Some(num)) => format!("{} {}", kind, num),
- (None, None) => kind,
- };
-
- let symbol = LatexSymbol {
- name,
- label: label_name(main_table, label),
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: env.range(&main_table),
- selection_range: selection_range(main_table, env.range(&main_table), label),
- children: Vec::new(),
- };
- return Some(symbol);
- }
- }
- }
- }
- None
-}
diff --git a/support/texlab/src/symbol/mod.rs b/support/texlab/src/symbol/mod.rs
deleted file mode 100644
index b292f15bb2..0000000000
--- a/support/texlab/src/symbol/mod.rs
+++ /dev/null
@@ -1,178 +0,0 @@
-mod bibtex_entry;
-mod bibtex_string;
-mod latex_section;
-mod project_order;
-mod types;
-
-pub use self::latex_section::{build_section_tree, LatexSectionNode, LatexSectionTree};
-
-use self::{
- bibtex_entry::BibtexEntrySymbolProvider, bibtex_string::BibtexStringSymbolProvider,
- latex_section::LatexSectionSymbolProvider, project_order::ProjectOrdering, types::LatexSymbol,
-};
-use crate::{
- feature::{ConcatProvider, DocumentView, FeatureProvider, FeatureRequest},
- protocol::{
- ClientCapabilities, ClientCapabilitiesExt, DocumentSymbolParams, DocumentSymbolResponse,
- Options, PartialResultParams, SymbolInformation, TextDocumentIdentifier, Uri,
- WorkDoneProgressParams, WorkspaceSymbolParams,
- },
- tex::Distribution,
- workspace::Snapshot,
-};
-use async_trait::async_trait;
-use std::{
- cmp::Reverse,
- path::{Path, PathBuf},
- sync::Arc,
-};
-
-pub struct SymbolProvider {
- provider: ConcatProvider<DocumentSymbolParams, LatexSymbol>,
-}
-
-impl SymbolProvider {
- pub fn new() -> Self {
- Self {
- provider: ConcatProvider::new(vec![
- Box::new(BibtexEntrySymbolProvider),
- Box::new(BibtexStringSymbolProvider),
- Box::new(LatexSectionSymbolProvider),
- ]),
- }
- }
-}
-
-impl Default for SymbolProvider {
- fn default() -> Self {
- Self::new()
- }
-}
-
-#[async_trait]
-impl FeatureProvider for SymbolProvider {
- type Params = DocumentSymbolParams;
- type Output = Vec<LatexSymbol>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(req).await
- }
-}
-
-pub fn document_symbols(
- client_capabilities: &ClientCapabilities,
- snapshot: &Snapshot,
- uri: &Uri,
- options: &Options,
- current_dir: &Path,
- symbols: Vec<LatexSymbol>,
-) -> DocumentSymbolResponse {
- if client_capabilities.has_hierarchical_document_symbol_support() {
- DocumentSymbolResponse::Nested(symbols.into_iter().map(Into::into).collect())
- } else {
- let mut buffer = Vec::new();
- for symbol in symbols {
- symbol.flatten(&mut buffer);
- }
- let mut buffer = buffer
- .into_iter()
- .map(|symbol| symbol.into_symbol_info(uri.clone()))
- .collect();
- sort_symbols(snapshot, options, &current_dir, &mut buffer);
- DocumentSymbolResponse::Flat(buffer)
- }
-}
-
-struct WorkspaceSymbol {
- info: SymbolInformation,
- search_text: String,
-}
-
-pub async fn workspace_symbols<'a>(
- distro: Arc<dyn Distribution>,
- client_capabilities: Arc<ClientCapabilities>,
- snapshot: Arc<Snapshot>,
- options: &'a Options,
- current_dir: Arc<PathBuf>,
- params: &'a WorkspaceSymbolParams,
-) -> Vec<SymbolInformation> {
- let provider = SymbolProvider::new();
- let mut symbols = Vec::new();
-
- for doc in &snapshot.0 {
- let uri: Uri = doc.uri.clone();
- let req = FeatureRequest {
- params: DocumentSymbolParams {
- text_document: TextDocumentIdentifier::new(uri.clone().into()),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- },
- view: DocumentView::analyze(
- Arc::clone(&snapshot),
- Arc::clone(&doc),
- &options,
- &current_dir,
- ),
- distro: distro.clone(),
- client_capabilities: Arc::clone(&client_capabilities),
- options: options.clone(),
- current_dir: Arc::clone(&current_dir),
- };
-
- let mut buffer = Vec::new();
- for symbol in provider.execute(&req).await {
- symbol.flatten(&mut buffer);
- }
-
- for symbol in buffer {
- symbols.push(WorkspaceSymbol {
- search_text: symbol.search_text(),
- info: symbol.into_symbol_info(uri.clone()),
- });
- }
- }
-
- let query_words: Vec<_> = params
- .query
- .split_whitespace()
- .map(str::to_lowercase)
- .collect();
- let mut filtered = Vec::new();
- for symbol in symbols {
- let mut included = true;
- for word in &query_words {
- if !symbol.search_text.contains(word) {
- included = false;
- break;
- }
- }
-
- if included {
- filtered.push(symbol.info);
- }
- }
- sort_symbols(&snapshot, options, &current_dir, &mut filtered);
- filtered
-}
-
-fn sort_symbols(
- snapshot: &Snapshot,
- options: &Options,
- current_dir: &Path,
- symbols: &mut Vec<SymbolInformation>,
-) {
- let ordering = ProjectOrdering::analyze(snapshot, options, current_dir);
- symbols.sort_by(|left, right| {
- let left_key = (
- ordering.get(&Uri::from(left.location.uri.clone())),
- left.location.range.start,
- Reverse(left.location.range.end),
- );
- let right_key = (
- ordering.get(&Uri::from(right.location.uri.clone())),
- right.location.range.start,
- Reverse(right.location.range.end),
- );
- left_key.cmp(&right_key)
- });
-}
diff --git a/support/texlab/src/symbol/project_order.rs b/support/texlab/src/symbol/project_order.rs
deleted file mode 100644
index 8a2ec5f6d0..0000000000
--- a/support/texlab/src/symbol/project_order.rs
+++ /dev/null
@@ -1,181 +0,0 @@
-use crate::{
- protocol::{Options, Uri},
- workspace::{Document, DocumentContent, Snapshot},
-};
-use petgraph::{algo::tarjan_scc, Directed, Graph};
-use std::{collections::HashSet, path::Path, sync::Arc, usize};
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct ProjectOrdering {
- ordering: Vec<Arc<Document>>,
-}
-
-impl ProjectOrdering {
- pub fn get(&self, uri: &Uri) -> usize {
- self.ordering
- .iter()
- .position(|doc| doc.uri == *uri)
- .unwrap_or(usize::MAX)
- }
-
- pub fn analyze(snapshot: &Snapshot, options: &Options, current_dir: &Path) -> Self {
- let mut ordering = Vec::new();
- let comps = Self::connected_components(snapshot, options, current_dir);
- for comp in comps {
- let graph = Self::build_dependency_graph(&comp);
-
- let mut visited = HashSet::new();
- let root_index = *graph.node_weight(tarjan_scc(&graph)[0][0]).unwrap();
- let mut stack = vec![Arc::clone(&comp[root_index])];
-
- while let Some(doc) = stack.pop() {
- if !visited.insert(doc.uri.as_str().to_owned()) {
- continue;
- }
-
- ordering.push(Arc::clone(&doc));
- if let DocumentContent::Latex(tree) = &doc.content {
- for include in tree.includes.iter().rev() {
- for targets in &include.all_targets {
- for target in targets {
- if let Some(child) = snapshot.find(target) {
- stack.push(child);
- }
- }
- }
- }
- }
- }
- }
-
- Self { ordering }
- }
-
- fn connected_components(
- snapshot: &Snapshot,
- options: &Options,
- current_dir: &Path,
- ) -> Vec<Vec<Arc<Document>>> {
- let mut comps = Vec::new();
- let mut visited = HashSet::new();
- for root in &snapshot.0 {
- if !visited.insert(root.uri.clone()) {
- continue;
- }
-
- let comp = snapshot.relations(&root.uri, options, current_dir);
- for document in &comp {
- visited.insert(document.uri.clone());
- }
- comps.push(comp);
- }
- comps
- }
-
- fn build_dependency_graph(docs: &[Arc<Document>]) -> Graph<usize, (), Directed> {
- let mut graph = Graph::new();
- let nodes: Vec<_> = (0..docs.len()).map(|i| graph.add_node(i)).collect();
-
- for (i, doc) in docs.iter().enumerate() {
- if let DocumentContent::Latex(tree) = &doc.content {
- for targets in tree
- .includes
- .iter()
- .flat_map(|include| &include.all_targets)
- {
- for target in targets {
- if let Some(j) = docs.iter().position(|doc| doc.uri == *target) {
- graph.add_edge(nodes[j], nodes[i], ());
- break;
- }
- }
- }
- }
- }
- graph
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- tex::{Language, Resolver},
- workspace::DocumentParams,
- };
- use std::env;
-
- fn create_simple_document(uri: &Uri, language: Language, text: &str) -> Arc<Document> {
- Arc::new(Document::open(DocumentParams {
- uri: uri.clone(),
- text: text.into(),
- language,
- resolver: &Resolver::default(),
- options: &Options::default(),
- current_dir: &env::current_dir().unwrap(),
- }))
- }
-
- #[test]
- fn no_cycles() {
- let a = Uri::parse("http://example.com/a.tex").unwrap();
- let b = Uri::parse("http://example.com/b.tex").unwrap();
- let c = Uri::parse("http://example.com/c.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&a, Language::Latex, ""),
- create_simple_document(&b, Language::Latex, ""),
- create_simple_document(&c, Language::Latex, r#"\include{b}\include{a}"#),
- ];
-
- let current_dir = env::current_dir().unwrap();
- let ordering = ProjectOrdering::analyze(&snapshot, &Options::default(), &current_dir);
-
- assert_eq!(ordering.get(&a), 2);
- assert_eq!(ordering.get(&b), 1);
- assert_eq!(ordering.get(&c), 0);
- }
-
- #[test]
- fn cycles() {
- let a = Uri::parse("http://example.com/a.tex").unwrap();
- let b = Uri::parse("http://example.com/b.tex").unwrap();
- let c = Uri::parse("http://example.com/c.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&a, Language::Latex, r#"\include{b}"#),
- create_simple_document(&b, Language::Latex, r#"\include{a}"#),
- create_simple_document(&c, Language::Latex, r#"\include{a}"#),
- ];
-
- let current_dir = env::current_dir().unwrap();
- let ordering = ProjectOrdering::analyze(&snapshot, &Options::default(), &current_dir);
-
- assert_eq!(ordering.get(&a), 1);
- assert_eq!(ordering.get(&b), 2);
- assert_eq!(ordering.get(&c), 0);
- }
-
- #[test]
- fn multiple_roots() {
- let a = Uri::parse("http://example.com/a.tex").unwrap();
- let b = Uri::parse("http://example.com/b.tex").unwrap();
- let c = Uri::parse("http://example.com/c.tex").unwrap();
- let d = Uri::parse("http://example.com/d.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&a, Language::Latex, r#"\include{b}"#),
- create_simple_document(&b, Language::Latex, ""),
- create_simple_document(&c, Language::Latex, ""),
- create_simple_document(&d, Language::Latex, r#"\include{c}"#),
- ];
-
- let current_dir = env::current_dir().unwrap();
- let ordering = ProjectOrdering::analyze(&snapshot, &Options::default(), &current_dir);
-
- assert_eq!(ordering.get(&a), 0);
- assert_eq!(ordering.get(&b), 1);
- assert_eq!(ordering.get(&d), 2);
- assert_eq!(ordering.get(&c), 3);
- }
-}
diff --git a/support/texlab/src/syntax.rs b/support/texlab/src/syntax.rs
new file mode 100644
index 0000000000..5a906c0ea7
--- /dev/null
+++ b/support/texlab/src/syntax.rs
@@ -0,0 +1,17 @@
+use cstree::TextRange;
+
+pub mod bibtex;
+pub mod build_log;
+pub mod latex;
+
+pub trait CstNode<'a> {
+ type Lang: cstree::Language;
+
+ fn cast(node: &'a cstree::ResolvedNode<Self::Lang>) -> Option<Self>
+ where
+ Self: Sized;
+
+ fn syntax(&self) -> &'a cstree::ResolvedNode<Self::Lang>;
+
+ fn small_range(&self) -> TextRange;
+}
diff --git a/support/texlab/src/syntax/bibtex.rs b/support/texlab/src/syntax/bibtex.rs
new file mode 100644
index 0000000000..c6e8bb3760
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex.rs
@@ -0,0 +1,34 @@
+mod cst;
+mod kind;
+mod lexer;
+mod parser;
+
+pub use self::{
+ cst::*,
+ kind::SyntaxKind::{self, *},
+ parser::{parse, Parse},
+};
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum Language {}
+
+impl cstree::Language for Language {
+ type Kind = SyntaxKind;
+
+ fn kind_from_raw(raw: cstree::SyntaxKind) -> Self::Kind {
+ assert!(raw.0 <= ROOT as u16);
+ unsafe { std::mem::transmute::<u16, SyntaxKind>(raw.0) }
+ }
+
+ fn kind_to_raw(kind: Self::Kind) -> cstree::SyntaxKind {
+ kind.into()
+ }
+}
+
+pub type SyntaxNode = cstree::ResolvedNode<Language>;
+
+pub type SyntaxToken = cstree::ResolvedToken<Language>;
+
+pub type SyntaxElement = cstree::ResolvedElement<Language>;
+
+pub type SyntaxElementRef<'a> = cstree::ResolvedElementRef<'a, Language>;
diff --git a/support/texlab/src/syntax/bibtex/ast.rs b/support/texlab/src/syntax/bibtex/ast.rs
deleted file mode 100644
index 77ee98e26d..0000000000
--- a/support/texlab/src/syntax/bibtex/ast.rs
+++ /dev/null
@@ -1,431 +0,0 @@
-use crate::{
- protocol::{Position, Range, RangeExt},
- syntax::{Span, SyntaxNode},
-};
-use itertools::Itertools;
-use petgraph::graph::{Graph, NodeIndex};
-use serde::{Deserialize, Serialize};
-use std::fmt;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-pub enum TokenKind {
- PreambleKind,
- StringKind,
- EntryKind,
- Word,
- Command,
- Assign,
- Comma,
- Concat,
- Quote,
- BeginBrace,
- EndBrace,
- BeginParen,
- EndParen,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Token {
- pub span: Span,
- pub kind: TokenKind,
-}
-
-impl SyntaxNode for Token {
- fn range(&self) -> Range {
- self.span.range()
- }
-}
-
-impl Token {
- pub fn new(span: Span, kind: TokenKind) -> Self {
- Self { span, kind }
- }
-
- pub fn text(&self) -> &str {
- &self.span.text
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-pub struct Root {
- pub range: Range,
-}
-
-impl SyntaxNode for Root {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for Root {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Root")
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Comment {
- pub token: Token,
-}
-
-impl SyntaxNode for Comment {
- fn range(&self) -> Range {
- self.token.range()
- }
-}
-
-impl fmt::Debug for Comment {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Comment({})", self.token.text())
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Preamble {
- pub range: Range,
- pub ty: Token,
- pub left: Option<Token>,
- pub right: Option<Token>,
-}
-
-impl SyntaxNode for Preamble {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for Preamble {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Preamble")
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct String {
- pub range: Range,
- pub ty: Token,
- pub left: Option<Token>,
- pub name: Option<Token>,
- pub assign: Option<Token>,
- pub right: Option<Token>,
-}
-
-impl SyntaxNode for String {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for String {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "String({:?})", self.name.as_ref().map(Token::text))
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Entry {
- pub range: Range,
- pub ty: Token,
- pub left: Option<Token>,
- pub key: Option<Token>,
- pub comma: Option<Token>,
- pub right: Option<Token>,
-}
-
-impl SyntaxNode for Entry {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for Entry {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Entry({:?})", self.key.as_ref().map(Token::text))
- }
-}
-
-impl Entry {
- pub fn is_comment(&self) -> bool {
- self.ty.text().to_lowercase() == "@comment"
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Field {
- pub range: Range,
- pub name: Token,
- pub assign: Option<Token>,
- pub comma: Option<Token>,
-}
-
-impl SyntaxNode for Field {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for Field {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Field({})", self.name.text())
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Word {
- pub token: Token,
-}
-
-impl SyntaxNode for Word {
- fn range(&self) -> Range {
- self.token.range()
- }
-}
-
-impl fmt::Debug for Word {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Word({})", self.token.text())
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Command {
- pub token: Token,
-}
-
-impl SyntaxNode for Command {
- fn range(&self) -> Range {
- self.token.range()
- }
-}
-
-impl fmt::Debug for Command {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Command({})", self.token.text())
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct QuotedContent {
- pub range: Range,
- pub left: Token,
- pub right: Option<Token>,
-}
-
-impl SyntaxNode for QuotedContent {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for QuotedContent {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "QuotedContent")
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct BracedContent {
- pub range: Range,
- pub left: Token,
- pub right: Option<Token>,
-}
-
-impl SyntaxNode for BracedContent {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for BracedContent {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "BracedContent")
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Concat {
- pub range: Range,
- pub operator: Token,
-}
-
-impl SyntaxNode for Concat {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-impl fmt::Debug for Concat {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Concat")
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub enum Node {
- Root(Root),
- Comment(Comment),
- Preamble(Box<Preamble>),
- String(Box<String>),
- Entry(Box<Entry>),
- Field(Box<Field>),
- Word(Word),
- Command(Command),
- QuotedContent(QuotedContent),
- BracedContent(BracedContent),
- Concat(Concat),
-}
-
-impl SyntaxNode for Node {
- fn range(&self) -> Range {
- match self {
- Self::Root(root) => root.range(),
- Self::Comment(comment) => comment.range(),
- Self::Preamble(preamble) => preamble.range(),
- Self::String(string) => string.range(),
- Self::Entry(entry) => entry.range(),
- Self::Field(field) => field.range(),
- Self::Word(word) => word.range(),
- Self::Command(cmd) => cmd.range(),
- Self::QuotedContent(content) => content.range(),
- Self::BracedContent(content) => content.range(),
- Self::Concat(concat) => concat.range(),
- }
- }
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Tree {
- pub graph: Graph<Node, ()>,
- pub root: NodeIndex,
-}
-
-impl Tree {
- pub fn children(&self, parent: NodeIndex) -> impl Iterator<Item = NodeIndex> {
- self.graph
- .neighbors(parent)
- .sorted_by_key(|child| self.graph[*child].start())
- }
-
- pub fn has_children(&self, parent: NodeIndex) -> bool {
- self.children(parent).next().is_some()
- }
-
- pub fn walk<'a, V: Visitor<'a>>(&'a self, visitor: &mut V, parent: NodeIndex) {
- for child in self.children(parent) {
- visitor.visit(self, child);
- }
- }
-
- pub fn find(&self, pos: Position) -> Vec<NodeIndex> {
- let mut finder = Finder::new(pos);
- finder.visit(self, self.root);
- finder.results
- }
-
- pub fn as_preamble(&self, node: NodeIndex) -> Option<&Preamble> {
- if let Node::Preamble(preamble) = &self.graph[node] {
- Some(preamble)
- } else {
- None
- }
- }
-
- pub fn as_string(&self, node: NodeIndex) -> Option<&String> {
- if let Node::String(string) = &self.graph[node] {
- Some(string)
- } else {
- None
- }
- }
-
- pub fn as_entry(&self, node: NodeIndex) -> Option<&Entry> {
- if let Node::Entry(entry) = &self.graph[node] {
- Some(entry)
- } else {
- None
- }
- }
-
- pub fn as_field(&self, node: NodeIndex) -> Option<&Field> {
- if let Node::Field(field) = &self.graph[node] {
- Some(field)
- } else {
- None
- }
- }
-
- pub fn as_command(&self, node: NodeIndex) -> Option<&Command> {
- if let Node::Command(cmd) = &self.graph[node] {
- Some(cmd)
- } else {
- None
- }
- }
-
- pub fn as_word(&self, node: NodeIndex) -> Option<&Word> {
- if let Node::Word(word) = &self.graph[node] {
- Some(word)
- } else {
- None
- }
- }
-
- pub fn entry_by_key(&self, key: &str) -> Option<NodeIndex> {
- for node in self.children(self.root) {
- if let Some(entry) = self.as_entry(node) {
- if entry.key.as_ref().map(Token::text) == Some(key) {
- return Some(node);
- }
- }
- }
- None
- }
-
- pub fn field_by_name(&self, parent: NodeIndex, name: &str) -> Option<NodeIndex> {
- let name = name.to_lowercase();
- self.as_entry(parent)?;
- for node in self.children(parent) {
- if let Some(field) = self.as_field(node) {
- if field.name.text() == name {
- return Some(node);
- }
- }
- }
- None
- }
-
- pub fn crossref(&self, entry: NodeIndex) -> Option<NodeIndex> {
- let field = self.field_by_name(entry, "crossref")?;
- let content = self.children(field).next()?;
- let key = self.as_word(self.children(content).next()?)?;
- self.entry_by_key(key.token.text())
- }
-}
-
-pub trait Visitor<'a> {
- fn visit(&mut self, tree: &'a Tree, node: NodeIndex);
-}
-
-#[derive(Debug)]
-struct Finder {
- position: Position,
- results: Vec<NodeIndex>,
-}
-
-impl Finder {
- fn new(position: Position) -> Self {
- Self {
- position,
- results: Vec::new(),
- }
- }
-}
-
-impl<'a> Visitor<'a> for Finder {
- fn visit(&mut self, tree: &'a Tree, node: NodeIndex) {
- if tree.graph[node].range().contains(self.position) {
- self.results.push(node);
- tree.walk(self, node);
- }
- }
-}
diff --git a/support/texlab/src/syntax/bibtex/cst.rs b/support/texlab/src/syntax/bibtex/cst.rs
new file mode 100644
index 0000000000..7f824681dc
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/cst.rs
@@ -0,0 +1,212 @@
+use cstree::TextRange;
+
+use crate::syntax::CstNode;
+
+use super::{Language, SyntaxKind::*, SyntaxNode, SyntaxToken};
+
+macro_rules! cst_node {
+ ($name:ident, $($kind:pat),+) => {
+ #[derive(Clone)]
+ #[repr(transparent)]
+ pub struct $name<'a>(&'a SyntaxNode);
+
+ impl<'a> CstNode<'a> for $name<'a> {
+ type Lang = Language;
+
+ fn cast(node: &'a cstree::ResolvedNode<Self::Lang>) -> Option<Self>
+ where
+ Self: Sized,
+ {
+ match node.kind() {
+ $($kind => Some(Self(node)),)+
+ _ => None,
+ }
+ }
+
+ fn syntax(&self) -> &'a cstree::ResolvedNode<Self::Lang> {
+ &self.0
+ }
+
+ fn small_range(&self) -> TextRange {
+ let full_range = self.syntax().text_range();
+ let start = full_range.start();
+ let mut token = self.syntax().last_token();
+ while let Some(current) = token {
+ if !matches!(current.kind(), WHITESPACE | JUNK) {
+ return TextRange::new(start, current.text_range().end());
+ }
+ token = current.prev_token();
+ }
+ TextRange::new(start, start)
+ }
+ }
+ };
+}
+
+pub trait HasCurly<'a>: CstNode<'a, Lang = Language> {
+ fn left_curly(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == L_CURLY.into())
+ }
+
+ fn right_curly(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == R_CURLY.into())
+ }
+}
+
+pub trait HasQuotes<'a>: CstNode<'a, Lang = Language> {
+ fn left_quote(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == QUOTE.into())
+ }
+
+ fn right_quote(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .filter(|node| node.kind() == QUOTE.into())
+ .nth(1)
+ }
+}
+
+pub trait HasDelimiters<'a>: CstNode<'a, Lang = Language> {
+ fn left_delimiter(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| matches!(node.kind(), L_CURLY | L_PAREN))
+ }
+
+ fn right_delimiter(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| matches!(node.kind(), R_CURLY | R_PAREN))
+ }
+}
+
+pub trait HasType<'a>: CstNode<'a, Lang = Language> {
+ fn ty(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| {
+ matches!(
+ node.kind(),
+ PREAMBLE_TYPE | STRING_TYPE | COMMENT_TYPE | ENTRY_TYPE
+ )
+ })
+ }
+}
+
+cst_node!(Root, ROOT);
+
+cst_node!(Junk, JUNK);
+
+cst_node!(Comment, COMMENT);
+
+impl<'a> HasType<'a> for Comment<'a> {}
+
+cst_node!(Preamble, PREAMBLE);
+
+impl<'a> HasType<'a> for Preamble<'a> {}
+
+impl<'a> HasDelimiters<'a> for Preamble<'a> {}
+
+impl<'a> Preamble<'a> {
+ pub fn value(&self) -> Option<Value<'a>> {
+ self.syntax().children().find_map(Value::cast)
+ }
+}
+
+cst_node!(String, STRING);
+
+impl<'a> HasType<'a> for String<'a> {}
+
+impl<'a> HasDelimiters<'a> for String<'a> {}
+
+impl<'a> String<'a> {
+ pub fn name(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == WORD)
+ }
+
+ pub fn equality_sign(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == EQUALITY_SIGN)
+ }
+
+ pub fn value(&self) -> Option<Value<'a>> {
+ self.syntax().children().find_map(Value::cast)
+ }
+}
+
+cst_node!(Entry, ENTRY);
+
+impl<'a> HasType<'a> for Entry<'a> {}
+
+impl<'a> HasDelimiters<'a> for Entry<'a> {}
+
+impl<'a> Entry<'a> {
+ pub fn key(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == WORD)
+ }
+
+ pub fn fields(&self) -> impl Iterator<Item = Field<'a>> {
+ self.syntax().children().filter_map(Field::cast)
+ }
+}
+
+cst_node!(Field, FIELD);
+
+impl<'a> Field<'a> {
+ pub fn name(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == WORD)
+ }
+
+ pub fn equality_sign(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == EQUALITY_SIGN)
+ }
+
+ pub fn value(&self) -> Option<Value<'a>> {
+ self.syntax().children().find_map(Value::cast)
+ }
+}
+
+cst_node!(Value, VALUE);
+
+impl<'a> Value<'a> {
+ pub fn tokens(&self) -> impl Iterator<Item = Token<'a>> {
+ self.syntax().children().filter_map(Token::cast)
+ }
+}
+
+cst_node!(Token, TOKEN);
+
+cst_node!(BraceGroup, BRACE_GROUP);
+
+impl<'a> HasCurly<'a> for BraceGroup<'a> {}
+
+cst_node!(QuoteGroup, QUOTE_GROUP);
+
+impl<'a> HasQuotes<'a> for QuoteGroup<'a> {}
diff --git a/support/texlab/src/syntax/bibtex/formatter.rs b/support/texlab/src/syntax/bibtex/formatter.rs
deleted file mode 100644
index d4965e7cd4..0000000000
--- a/support/texlab/src/syntax/bibtex/formatter.rs
+++ /dev/null
@@ -1,329 +0,0 @@
-use super::ast::*;
-use crate::{protocol::BibtexFormattingOptions, syntax::text::SyntaxNode};
-use petgraph::graph::NodeIndex;
-use std::{i32, string::String as StdString};
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct FormattingParams<'a> {
- pub tab_size: usize,
- pub insert_spaces: bool,
- pub options: &'a BibtexFormattingOptions,
-}
-
-impl<'a> FormattingParams<'a> {
- fn line_length(self) -> i32 {
- let line_length = self.options.line_length.unwrap_or(120);
- if line_length <= 0 {
- i32::MAX
- } else {
- line_length
- }
- }
-
- fn indent(self) -> StdString {
- if self.insert_spaces {
- let mut buffer = StdString::new();
- for _ in 0..self.tab_size {
- buffer.push(' ');
- }
- buffer
- } else {
- "\t".into()
- }
- }
-}
-
-#[derive(Debug, Clone)]
-struct Formatter<'a> {
- params: FormattingParams<'a>,
- indent: StdString,
- output: StdString,
- align: Vec<usize>,
-}
-
-impl<'a> Formatter<'a> {
- fn new(params: FormattingParams<'a>) -> Self {
- Self {
- params,
- indent: params.indent(),
- output: StdString::new(),
- align: Vec::new(),
- }
- }
-
- fn visit_token_lowercase(&mut self, token: &Token) {
- self.output.push_str(token.text().to_lowercase().as_ref());
- }
-
- fn should_insert_space(previous: &Token, current: &Token) -> bool {
- previous.start().line != current.start().line
- || previous.end().character < current.start().character
- }
-}
-
-impl<'a, 'b> Visitor<'b> for Formatter<'a> {
- fn visit(&mut self, tree: &'b Tree, node: NodeIndex) {
- match &tree.graph[node] {
- Node::Root(_) => tree.walk(self, node),
- Node::Comment(comment) => self.output.push_str(comment.token.text()),
- Node::Preamble(preamble) => {
- self.visit_token_lowercase(&preamble.ty);
- self.output.push('{');
- if tree.has_children(node) {
- self.align.push(self.output.chars().count());
- tree.walk(self, node);
- self.output.push('}');
- }
- }
- Node::String(string) => {
- self.visit_token_lowercase(&string.ty);
- self.output.push('{');
- if let Some(name) = &string.name {
- self.output.push_str(name.text());
- self.output.push_str(" = ");
- if tree.has_children(node) {
- self.align.push(self.output.chars().count());
- tree.walk(self, node);
- self.output.push('}');
- }
- }
- }
- Node::Entry(entry) => {
- self.visit_token_lowercase(&entry.ty);
- self.output.push('{');
- if let Some(key) = &entry.key {
- self.output.push_str(key.text());
- self.output.push(',');
- self.output.push('\n');
- tree.walk(self, node);
- self.output.push('}');
- }
- }
- Node::Field(field) => {
- self.output.push_str(&self.indent);
- self.visit_token_lowercase(&field.name);
- self.output.push_str(" = ");
- if tree.has_children(node) {
- let count = field.name.text().chars().count();
- self.align.push(self.params.tab_size as usize + count + 3);
- tree.walk(self, node);
- self.output.push(',');
- self.output.push('\n');
- }
- }
- Node::Word(_)
- | Node::Command(_)
- | Node::BracedContent(_)
- | Node::QuotedContent(_)
- | Node::Concat(_) => {
- let mut analyzer = ContentAnalyzer::default();
- analyzer.visit(tree, node);
- let tokens = analyzer.tokens;
- self.output.push_str(tokens[0].text());
-
- let align = self.align.pop().unwrap_or_default();
- let mut length = align + tokens[0].text().chars().count();
- for i in 1..tokens.len() {
- let previous = tokens[i - 1];
- let current = tokens[i];
- let current_length = current.text().chars().count();
-
- let insert_space = Self::should_insert_space(previous, current);
- let space_length = if insert_space { 1 } else { 0 };
-
- if length + current_length + space_length > self.params.line_length() as usize {
- self.output.push('\n');
- self.output.push_str(self.indent.as_ref());
- for _ in 0..=align - self.params.tab_size {
- self.output.push(' ');
- }
- length = align;
- } else if insert_space {
- self.output.push(' ');
- length += 1;
- }
- self.output.push_str(current.text());
- length += current_length;
- }
- }
- }
- }
-}
-
-#[derive(Debug, Default)]
-struct ContentAnalyzer<'a> {
- tokens: Vec<&'a Token>,
-}
-
-impl<'a> Visitor<'a> for ContentAnalyzer<'a> {
- fn visit(&mut self, tree: &'a Tree, node: NodeIndex) {
- match &tree.graph[node] {
- Node::Root(_)
- | Node::Comment(_)
- | Node::Preamble(_)
- | Node::String(_)
- | Node::Entry(_)
- | Node::Field(_) => tree.walk(self, node),
- Node::Word(word) => self.tokens.push(&word.token),
- Node::Command(cmd) => self.tokens.push(&cmd.token),
- Node::QuotedContent(content) => {
- self.tokens.push(&content.left);
- tree.walk(self, node);
- if let Some(right) = &content.right {
- self.tokens.push(right);
- }
- }
- Node::BracedContent(content) => {
- self.tokens.push(&content.left);
- tree.walk(self, node);
- if let Some(right) = &content.right {
- self.tokens.push(right);
- }
- }
- Node::Concat(concat) => {
- let mut children = tree.children(node);
- let left = children.next().unwrap();
- self.visit(tree, left);
- self.tokens.push(&concat.operator);
- children.for_each(|right| self.visit(tree, right));
- }
- }
- }
-}
-
-pub fn format(tree: &Tree, node: NodeIndex, params: FormattingParams) -> StdString {
- let mut formatter = Formatter::new(params);
- formatter.visit(tree, node);
- formatter.output
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::syntax::bibtex;
- use indoc::indoc;
-
- fn verify(source: &str, expected: &str, line_length: i32) {
- let tree = bibtex::open(source);
- let options = BibtexFormattingOptions {
- line_length: Some(line_length),
- formatter: None,
- };
-
- let mut children = tree.children(tree.root);
- let declaration = children.next().unwrap();
- assert_eq!(children.next(), None);
-
- let actual = format(
- &tree,
- declaration,
- FormattingParams {
- tab_size: 4,
- insert_spaces: true,
- options: &options,
- },
- );
- assert_eq!(actual, expected);
- }
-
- #[test]
- fn wrap_long_lines() {
- let source =
- "@article{foo, bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit.},}";
- let expected = indoc!(
- "
- @article{foo,
- bar = {Lorem ipsum dolor
- sit amet,
- consectetur
- adipiscing elit.},
- }"
- );
- verify(source, expected, 30);
- }
-
- #[test]
- fn line_length_zero() {
- let source =
- "@article{foo, bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit.},}";
- let expected = indoc!(
- "
- @article{foo,
- bar = {Lorem ipsum dolor sit amet, consectetur adipiscing elit.},
- }"
- );
- verify(source, expected, 0);
- }
-
- #[test]
- fn trailing_commas() {
- let source = "@article{foo, bar = baz}";
- let expected = indoc!(
- "
- @article{foo,
- bar = baz,
- }"
- );
- verify(source, expected, 30);
- }
-
- #[test]
- fn insert_braces() {
- let source = "@article{foo, bar = baz,";
- let expected = indoc!(
- "
- @article{foo,
- bar = baz,
- }"
- );
- verify(source, expected, 30);
- }
-
- #[test]
- fn commands() {
- let source = "@article{foo, bar = \"\\baz\",}";
- let expected = indoc!(
- "@article{foo,
- bar = \"\\baz\",
- }"
- );
- verify(source, expected, 30);
- }
-
- #[test]
- fn concatenation() {
- let source = "@article{foo, bar = \"baz\" # \"qux\"}";
- let expected = indoc!(
- "
- @article{foo,
- bar = \"baz\" # \"qux\",
- }"
- );
- verify(source, expected, 30);
- }
-
- #[test]
- fn parentheses() {
- let source = "@article(foo,)";
- let expected = indoc!(
- "
- @article{foo,
- }"
- );
- verify(source, expected, 30);
- }
-
- #[test]
- fn string() {
- let source = "@string{foo=\"bar\"}";
- let expected = "@string{foo = \"bar\"}";
- verify(source, expected, 30);
- }
-
- #[test]
- fn preamble() {
- let source = "@preamble{\n\"foo bar baz\"}";
- let expected = "@preamble{\"foo bar baz\"}";
- verify(source, expected, 30);
- }
-}
diff --git a/support/texlab/src/syntax/bibtex/kind.rs b/support/texlab/src/syntax/bibtex/kind.rs
new file mode 100644
index 0000000000..fcb26b69bd
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/kind.rs
@@ -0,0 +1,51 @@
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
+#[allow(non_camel_case_types)]
+#[repr(u16)]
+pub enum SyntaxKind {
+ ERROR = 0,
+ MISSING,
+
+ WHITESPACE,
+ PREAMBLE_TYPE,
+ STRING_TYPE,
+ COMMENT_TYPE,
+ ENTRY_TYPE,
+ WORD,
+ L_CURLY,
+ R_CURLY,
+ L_PAREN,
+ R_PAREN,
+ COMMA,
+ HASH,
+ QUOTE,
+ EQUALITY_SIGN,
+ COMMAND_NAME,
+
+ JUNK,
+ PREAMBLE,
+ STRING,
+ COMMENT,
+ ENTRY,
+ FIELD,
+ VALUE,
+ TOKEN,
+ BRACE_GROUP,
+ QUOTE_GROUP,
+ ROOT,
+}
+
+impl SyntaxKind {
+ pub fn is_type(&self) -> bool {
+ use SyntaxKind::*;
+ matches!(
+ self,
+ PREAMBLE_TYPE | STRING_TYPE | COMMENT_TYPE | ENTRY_TYPE
+ )
+ }
+}
+
+impl From<SyntaxKind> for cstree::SyntaxKind {
+ fn from(kind: SyntaxKind) -> Self {
+ Self(kind as u16)
+ }
+}
diff --git a/support/texlab/src/syntax/bibtex/lexer.rs b/support/texlab/src/syntax/bibtex/lexer.rs
index e089b15864..dff111d645 100644
--- a/support/texlab/src/syntax/bibtex/lexer.rs
+++ b/support/texlab/src/syntax/bibtex/lexer.rs
@@ -1,173 +1,82 @@
-use super::ast::{Token, TokenKind};
-use crate::syntax::text::CharStream;
+use logos::Logos;
-#[derive(Debug)]
-pub struct Lexer<'a> {
- stream: CharStream<'a>,
-}
+use super::kind::SyntaxKind;
-impl<'a> Lexer<'a> {
- pub fn new(text: &'a str) -> Self {
- Self {
- stream: CharStream::new(text),
- }
- }
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord, Logos)]
+#[allow(non_camel_case_types)]
+#[repr(u16)]
+enum LogosToken {
+ #[regex(r"\s+")]
+ WHITESPACE = 2,
- fn kind(&mut self) -> Token {
- fn is_type_char(c: char) -> bool {
- c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'
- }
+ #[regex(r"@[Pp][Rr][Ee][Aa][Mm][Bb][Ll][Ee]")]
+ PREAMBLE_TYPE,
- self.stream.start_span();
- self.stream.next().unwrap();
- while self.stream.satifies(|c| is_type_char(*c)) {
- self.stream.next();
- }
- let span = self.stream.end_span();
- let kind = match span.text.to_lowercase().as_ref() {
- "@preamble" => TokenKind::PreambleKind,
- "@string" => TokenKind::StringKind,
- _ => TokenKind::EntryKind,
- };
- Token::new(span, kind)
- }
+ #[regex(r"@[Ss][Tt][Rr][Ii][Nn][Gg]")]
+ STRING_TYPE,
- fn single_character(&mut self, kind: TokenKind) -> Token {
- self.stream.start_span();
- self.stream.next();
- let span = self.stream.end_span();
- Token::new(span, kind)
- }
+ #[regex(r"@[Cc][Oo][Mm][Mm][Ee][Nn][Tt]")]
+ COMMENT_TYPE,
- fn command(&mut self) -> Token {
- let span = self.stream.command();
- Token::new(span, TokenKind::Command)
- }
+ #[regex(r"@[!\$\&\*\+\-\./:;<>\?@\[\]\\\^_`\|\~a-zA-Z][!\$\&\*\+\-\./:;<>\?@\[\]\\\^_`\|\~a-zA-Z0-9]*|@")]
+ ENTRY_TYPE,
- fn word(&mut self) -> Token {
- fn is_word_char(c: char) -> bool {
- !c.is_whitespace()
- && c != '@'
- && c != '='
- && c != ','
- && c != '#'
- && c != '"'
- && c != '{'
- && c != '}'
- && c != '('
- && c != ')'
- }
+ #[regex(r#"[^\s\{\}\(\),#"=\\]+"#)]
+ #[error]
+ WORD,
- self.stream.start_span();
- while self.stream.satifies(|c| is_word_char(*c)) {
- self.stream.next();
- }
- let span = self.stream.end_span();
- Token::new(span, TokenKind::Word)
- }
-}
+ #[token("{")]
+ L_CURLY,
-impl<'a> Iterator for Lexer<'a> {
- type Item = Token;
-
- fn next(&mut self) -> Option<Token> {
- loop {
- match self.stream.peek() {
- Some('@') => return Some(self.kind()),
- Some('=') => return Some(self.single_character(TokenKind::Assign)),
- Some(',') => return Some(self.single_character(TokenKind::Comma)),
- Some('#') => return Some(self.single_character(TokenKind::Concat)),
- Some('"') => return Some(self.single_character(TokenKind::Quote)),
- Some('{') => return Some(self.single_character(TokenKind::BeginBrace)),
- Some('}') => return Some(self.single_character(TokenKind::EndBrace)),
- Some('(') => return Some(self.single_character(TokenKind::BeginParen)),
- Some(')') => return Some(self.single_character(TokenKind::EndParen)),
- Some('\\') => return Some(self.command()),
- Some(c) => {
- if c.is_whitespace() {
- self.stream.next();
- } else {
- return Some(self.word());
- }
- }
- None => {
- return None;
- }
- }
- }
- }
-}
+ #[token("}")]
+ R_CURLY,
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- protocol::{Position, Range},
- syntax::text::Span,
- };
-
- fn verify<'a>(lexer: &mut Lexer<'a>, line: u64, character: u64, text: &str, kind: TokenKind) {
- let start = Position::new(line, character);
- let end = Position::new(line, character + text.chars().count() as u64);
- let range = Range::new(start, end);
- let span = Span::new(range, text.to_owned());
- let token = Token::new(span, kind);
- assert_eq!(Some(token), lexer.next());
- }
+ #[token("(")]
+ L_PAREN,
- #[test]
- fn word() {
- let mut lexer = Lexer::new("foo bar baz");
- verify(&mut lexer, 0, 0, "foo", TokenKind::Word);
- verify(&mut lexer, 0, 4, "bar", TokenKind::Word);
- verify(&mut lexer, 0, 8, "baz", TokenKind::Word);
- assert_eq!(None, lexer.next());
- }
+ #[token(")")]
+ R_PAREN,
- #[test]
- fn command() {
- let mut lexer = Lexer::new("\\foo\\bar@baz");
- verify(&mut lexer, 0, 0, "\\foo", TokenKind::Command);
- verify(&mut lexer, 0, 4, "\\bar@baz", TokenKind::Command);
- assert_eq!(None, lexer.next());
- }
+ #[token(",")]
+ COMMA,
- #[test]
- fn escape_sequence() {
- let mut lexer = Lexer::new("\\foo*\n\\%\\**");
- verify(&mut lexer, 0, 0, "\\foo*", TokenKind::Command);
- verify(&mut lexer, 1, 0, "\\%", TokenKind::Command);
- verify(&mut lexer, 1, 2, "\\*", TokenKind::Command);
- verify(&mut lexer, 1, 4, "*", TokenKind::Word);
- assert_eq!(None, lexer.next());
- }
+ #[token("#")]
+ HASH,
+
+ #[token("\"")]
+ QUOTE,
+
+ #[token("=")]
+ EQUALITY_SIGN,
- #[test]
- fn delimiter() {
- let mut lexer = Lexer::new("{}()\"");
- verify(&mut lexer, 0, 0, "{", TokenKind::BeginBrace);
- verify(&mut lexer, 0, 1, "}", TokenKind::EndBrace);
- verify(&mut lexer, 0, 2, "(", TokenKind::BeginParen);
- verify(&mut lexer, 0, 3, ")", TokenKind::EndParen);
- verify(&mut lexer, 0, 4, "\"", TokenKind::Quote);
- assert_eq!(None, lexer.next());
+ #[regex(r"\\([^\r\n]|[@a-zA-Z:_]+\*?)?")]
+ COMMAND_NAME,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct Lexer<'a> {
+ tokens: Vec<(SyntaxKind, &'a str)>,
+}
+
+impl<'a> Lexer<'a> {
+ pub fn new(text: &'a str) -> Self {
+ let mut tokens = Vec::new();
+ let mut lexer = LogosToken::lexer(text);
+ while let Some(kind) = lexer.next() {
+ tokens.push((
+ unsafe { std::mem::transmute::<LogosToken, SyntaxKind>(kind) },
+ lexer.slice(),
+ ));
+ }
+ tokens.reverse();
+ Self { tokens }
}
- #[test]
- fn kind() {
- let mut lexer = Lexer::new("@pReAmBlE\n@article\n@string");
- verify(&mut lexer, 0, 0, "@pReAmBlE", TokenKind::PreambleKind);
- verify(&mut lexer, 1, 0, "@article", TokenKind::EntryKind);
- verify(&mut lexer, 2, 0, "@string", TokenKind::StringKind);
- assert_eq!(None, lexer.next());
+ pub fn peek(&self) -> Option<SyntaxKind> {
+ self.tokens.last().map(|(kind, _)| *kind)
}
- #[test]
- fn operator() {
- let mut lexer = Lexer::new("=,#");
- verify(&mut lexer, 0, 0, "=", TokenKind::Assign);
- verify(&mut lexer, 0, 1, ",", TokenKind::Comma);
- verify(&mut lexer, 0, 2, "#", TokenKind::Concat);
- assert_eq!(None, lexer.next());
+ pub fn consume(&mut self) -> Option<(SyntaxKind, &'a str)> {
+ self.tokens.pop()
}
}
diff --git a/support/texlab/src/syntax/bibtex/mod.rs b/support/texlab/src/syntax/bibtex/mod.rs
deleted file mode 100644
index aa7242c1f7..0000000000
--- a/support/texlab/src/syntax/bibtex/mod.rs
+++ /dev/null
@@ -1,396 +0,0 @@
-mod ast;
-mod formatter;
-mod lexer;
-mod parser;
-
-pub use self::{ast::*, formatter::*};
-
-use self::{lexer::Lexer, parser::Parser};
-
-pub fn open(text: &str) -> Tree {
- let lexer = Lexer::new(text);
- let parser = Parser::new(lexer);
- parser.parse()
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- protocol::{Range, RangeExt},
- syntax::text::SyntaxNode,
- };
- use petgraph::graph::NodeIndex;
-
- #[derive(Debug, Default)]
- struct TreeTraversal {
- nodes: Vec<NodeIndex>,
- }
-
- impl<'a> Visitor<'a> for TreeTraversal {
- fn visit(&mut self, tree: &Tree, node: NodeIndex) {
- self.nodes.push(node);
- tree.walk(self, node);
- }
- }
-
- mod range {
- use super::*;
- use indoc::indoc;
-
- fn verify(expected_ranges: Vec<Range>, text: &str) {
- let tree = open(text.trim());
-
- let mut traversal = TreeTraversal::default();
- traversal.visit(&tree, tree.root);
- let actual_ranges: Vec<_> = traversal
- .nodes
- .into_iter()
- .map(|node| tree.graph[node].range())
- .collect();
-
- assert_eq!(actual_ranges, expected_ranges);
- }
-
- #[test]
- fn empty_document() {
- verify(vec![Range::new_simple(0, 0, 0, 0)], "");
- }
-
- #[test]
- fn comment() {
- verify(
- vec![Range::new_simple(0, 0, 0, 3), Range::new_simple(0, 0, 0, 3)],
- "foo",
- );
- }
-
- #[test]
- fn preamble_no_left() {
- verify(
- vec![Range::new_simple(0, 0, 0, 9), Range::new_simple(0, 0, 0, 9)],
- "@preamble",
- );
- }
-
- #[test]
- fn preamble_no_content() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 10),
- Range::new_simple(0, 0, 0, 10),
- ],
- "@preamble{",
- );
- }
-
- #[test]
- fn preamble_no_right() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 15),
- Range::new_simple(0, 0, 0, 15),
- Range::new_simple(0, 10, 0, 15),
- Range::new_simple(0, 11, 0, 14),
- ],
- r#"@preamble{"foo""#,
- );
- }
-
- #[test]
- fn preamble_complete() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 16),
- Range::new_simple(0, 0, 0, 16),
- Range::new_simple(0, 10, 0, 15),
- Range::new_simple(0, 11, 0, 14),
- ],
- r#"@preamble{"foo"}"#,
- );
- }
-
- #[test]
- fn string_no_left() {
- verify(
- vec![Range::new_simple(0, 0, 0, 7), Range::new_simple(0, 0, 0, 7)],
- r#"@string"#,
- );
- }
-
- #[test]
- fn string_no_name() {
- verify(
- vec![Range::new_simple(0, 0, 0, 8), Range::new_simple(0, 0, 0, 8)],
- r#"@string{"#,
- );
- }
-
- #[test]
- fn string_no_assign() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 11),
- Range::new_simple(0, 0, 0, 11),
- ],
- r#"@string{foo"#,
- );
- }
-
- #[test]
- fn string_no_value() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 13),
- Range::new_simple(0, 0, 0, 13),
- ],
- r#"@string{foo ="#,
- );
- }
-
- #[test]
- fn string_no_right() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 19),
- Range::new_simple(0, 0, 0, 19),
- Range::new_simple(0, 14, 0, 19),
- Range::new_simple(0, 15, 0, 18),
- ],
- r#"@string{foo = "bar""#,
- );
- }
-
- #[test]
- fn string_complete() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 20),
- Range::new_simple(0, 0, 0, 20),
- Range::new_simple(0, 14, 0, 19),
- Range::new_simple(0, 15, 0, 18),
- ],
- r#"@string{foo = "bar"}"#,
- );
- }
-
- #[test]
- fn entry_no_left() {
- verify(
- vec![Range::new_simple(0, 0, 0, 8), Range::new_simple(0, 0, 0, 8)],
- r#"@article"#,
- );
- }
-
- #[test]
- fn entry_no_key() {
- verify(
- vec![Range::new_simple(0, 0, 0, 9), Range::new_simple(0, 0, 0, 9)],
- r#"@article{"#,
- );
- }
-
- #[test]
- fn entry_no_comma() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 12),
- Range::new_simple(0, 0, 0, 12),
- ],
- r#"@article{foo"#,
- );
- }
-
- #[test]
- fn entry_no_right() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 13),
- Range::new_simple(0, 0, 0, 13),
- ],
- r#"@article{foo,"#,
- );
- }
-
- #[test]
- fn entry_parentheses() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 14),
- Range::new_simple(0, 0, 0, 14),
- ],
- r#"@article(foo,)"#,
- );
- }
-
- #[test]
- fn field_no_assign() {
- verify(
- vec![
- Range::new_simple(0, 0, 1, 10),
- Range::new_simple(0, 0, 1, 10),
- Range::new_simple(1, 4, 1, 10),
- ],
- indoc!(
- r#"
- @article{foo,
- author
- "#
- ),
- );
- }
-
- #[test]
- fn field_no_value() {
- verify(
- vec![
- Range::new_simple(0, 0, 1, 12),
- Range::new_simple(0, 0, 1, 12),
- Range::new_simple(1, 4, 1, 12),
- ],
- indoc!(
- r#"
- @article{foo,
- author =
- "#
- ),
- );
- }
-
- #[test]
- fn field_no_comma() {
- verify(
- vec![
- Range::new_simple(0, 0, 1, 16),
- Range::new_simple(0, 0, 1, 16),
- Range::new_simple(1, 4, 1, 16),
- Range::new_simple(1, 13, 1, 16),
- ],
- indoc!(
- r#"
- @article{foo,
- author = bar
- "#
- ),
- );
- }
-
- #[test]
- fn field_complete() {
- verify(
- vec![
- Range::new_simple(0, 0, 2, 1),
- Range::new_simple(0, 0, 2, 1),
- Range::new_simple(1, 4, 1, 17),
- Range::new_simple(1, 13, 1, 16),
- ],
- indoc!(
- r#"
- @article{foo,
- author = bar,
- }
- "#
- ),
- );
- }
-
- #[test]
- fn entry_two_fields() {
- verify(
- vec![
- Range::new_simple(0, 0, 3, 1),
- Range::new_simple(0, 0, 3, 1),
- Range::new_simple(1, 4, 1, 17),
- Range::new_simple(1, 13, 1, 16),
- Range::new_simple(2, 4, 2, 16),
- Range::new_simple(2, 12, 2, 15),
- ],
- indoc!(
- r#"
- @article{foo,
- author = bar,
- title = baz,
- }
- "#
- ),
- );
- }
-
- #[test]
- fn quoted_content_no_children() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 12),
- Range::new_simple(0, 0, 0, 12),
- Range::new_simple(0, 10, 0, 11),
- ],
- r#"@preamble{"}"#,
- );
- }
-
- #[test]
- fn quoted_content_no_right() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 16),
- Range::new_simple(0, 0, 0, 16),
- Range::new_simple(0, 10, 0, 15),
- Range::new_simple(0, 11, 0, 15),
- ],
- r#"@preamble{"word}"#,
- );
- }
-
- #[test]
- fn braced_content_no_children() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 11),
- Range::new_simple(0, 0, 0, 11),
- Range::new_simple(0, 10, 0, 11),
- ],
- r#"@preamble{{"#,
- );
- }
-
- #[test]
- fn braced_content_no_right() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 15),
- Range::new_simple(0, 0, 0, 15),
- Range::new_simple(0, 10, 0, 15),
- Range::new_simple(0, 11, 0, 15),
- ],
- r#"@preamble{{word"#,
- );
- }
-
- #[test]
- fn concat_no_right() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 16),
- Range::new_simple(0, 0, 0, 16),
- Range::new_simple(0, 10, 0, 15),
- Range::new_simple(0, 10, 0, 13),
- ],
- r#"@preamble{foo #}"#,
- );
- }
-
- #[test]
- fn concat_complete() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 20),
- Range::new_simple(0, 0, 0, 20),
- Range::new_simple(0, 10, 0, 19),
- Range::new_simple(0, 10, 0, 13),
- Range::new_simple(0, 16, 0, 19),
- ],
- r#"@preamble{foo # bar}"#,
- );
- }
- }
-}
diff --git a/support/texlab/src/syntax/bibtex/parser.rs b/support/texlab/src/syntax/bibtex/parser.rs
index b23903aeb3..ffdb1c94a0 100644
--- a/support/texlab/src/syntax/bibtex/parser.rs
+++ b/support/texlab/src/syntax/bibtex/parser.rs
@@ -1,401 +1,413 @@
-use super::ast::*;
-use crate::{
- protocol::{Range, RangeExt},
- syntax::text::SyntaxNode,
+use cstree::GreenNodeBuilder;
+
+use super::{
+ lexer::Lexer,
+ SyntaxKind::{self, *},
+ SyntaxNode,
};
-use petgraph::graph::{Graph, NodeIndex};
-use std::iter::Peekable;
-pub struct Parser<I: Iterator<Item = Token>> {
- graph: Graph<Node, ()>,
- tokens: Peekable<I>,
+#[derive(Debug, Clone)]
+pub struct Parse {
+ pub root: SyntaxNode,
+}
+
+struct Parser<'a> {
+ lexer: Lexer<'a>,
+ builder: GreenNodeBuilder<'static, 'static>,
}
-impl<I: Iterator<Item = Token>> Parser<I> {
- pub fn new(tokens: I) -> Self {
+impl<'a> Parser<'a> {
+ pub fn new(lexer: Lexer<'a>) -> Self {
Self {
- tokens: tokens.peekable(),
- graph: Graph::new(),
+ lexer,
+ builder: GreenNodeBuilder::new(),
}
}
- pub fn parse(mut self) -> Tree {
- let mut children = Vec::new();
+ fn peek(&self) -> Option<SyntaxKind> {
+ self.lexer.peek()
+ }
- while let Some(ref token) = self.tokens.peek() {
- match token.kind {
- TokenKind::PreambleKind => children.push(self.preamble()),
- TokenKind::StringKind => children.push(self.string()),
- TokenKind::EntryKind => children.push(self.entry()),
- _ => children.push(self.comment()),
- }
- }
+ fn eat(&mut self) {
+ let (kind, text) = self.lexer.consume().unwrap();
+ self.builder.token(kind.into(), text);
+ }
- let range = if children.is_empty() {
- Range::new_simple(0, 0, 0, 0)
+ fn expect(&mut self, kind: SyntaxKind) {
+ if self.peek() == Some(kind) {
+ self.eat();
+ self.trivia();
} else {
- let start = self.graph[children[0]].start();
- let end = self.graph[children[children.len() - 1]].end();
- Range::new(start, end)
- };
+ self.builder.token(MISSING.into(), "");
+ }
+ }
- let root = self.graph.add_node(Node::Root(Root { range }));
- self.connect(root, &children);
- Tree {
- graph: self.graph,
- root,
+ pub fn parse(mut self) -> Parse {
+ self.builder.start_node(ROOT.into());
+ while let Some(kind) = self.peek() {
+ match kind {
+ PREAMBLE_TYPE => self.preamble(),
+ STRING_TYPE => self.string(),
+ COMMENT_TYPE => self.comment(),
+ ENTRY_TYPE => self.entry(),
+ _ => self.junk(),
+ }
+ }
+ self.builder.finish_node();
+ let (green, resolver) = self.builder.finish();
+ Parse {
+ root: SyntaxNode::new_root_with_resolver(green, resolver.unwrap()),
}
}
- fn preamble(&mut self) -> NodeIndex {
- let ty = self.tokens.next().unwrap();
+ fn trivia(&mut self) {
+ while self.peek() == Some(WHITESPACE) {
+ self.eat();
+ }
+ }
- let left = self.expect2(TokenKind::BeginBrace, TokenKind::BeginParen);
- if left.is_none() {
- return self.graph.add_node(Node::Preamble(Box::new(Preamble {
- range: ty.range(),
- ty,
- left: None,
- right: None,
- })));
+ fn junk(&mut self) {
+ self.builder.start_node(JUNK.into());
+ while self
+ .lexer
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ PREAMBLE_TYPE | STRING_TYPE | COMMENT_TYPE | ENTRY_TYPE,
+ )
+ })
+ .is_some()
+ {
+ self.eat();
}
+ self.builder.finish_node();
+ }
- if !self.can_match_content() {
- return self.graph.add_node(Node::Preamble(Box::new(Preamble {
- range: Range::new(ty.start(), left.as_ref().unwrap().end()),
- ty,
- left,
- right: None,
- })));
+ fn left_delimiter_or_missing(&mut self) {
+ if self
+ .lexer
+ .peek()
+ .filter(|&kind| matches!(kind, L_CURLY | L_PAREN))
+ .is_some()
+ {
+ self.eat();
+ self.trivia();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
+ }
- let content = self.content();
-
- let right = self.expect2(TokenKind::EndBrace, TokenKind::EndParen);
- let end = right
- .as_ref()
- .map(Token::end)
- .unwrap_or_else(|| self.graph[content].end());
-
- let parent = self.graph.add_node(Node::Preamble(Box::new(Preamble {
- range: Range::new(ty.start(), end),
- ty,
- left,
- right,
- })));
- self.graph.add_edge(parent, content, ());
- parent
- }
-
- fn string(&mut self) -> NodeIndex {
- let ty = self.tokens.next().unwrap();
-
- let left = self.expect2(TokenKind::BeginBrace, TokenKind::BeginParen);
- if left.is_none() {
- return self.graph.add_node(Node::String(Box::new(String {
- range: ty.range(),
- ty,
- left: None,
- name: None,
- assign: None,
- right: None,
- })));
+ fn right_delimiter_or_missing(&mut self) {
+ if self
+ .lexer
+ .peek()
+ .filter(|&kind| matches!(kind, R_CURLY | R_PAREN))
+ .is_some()
+ {
+ self.eat();
+ self.trivia();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
+ }
- let name = self.expect1(TokenKind::Word);
- if name.is_none() {
- return self.graph.add_node(Node::String(Box::new(String {
- range: Range::new(ty.start(), left.as_ref().unwrap().end()),
- ty,
- left,
- name: None,
- assign: None,
- right: None,
- })));
+ fn value_or_missing(&mut self) {
+ if self
+ .lexer
+ .peek()
+ .filter(|&kind| matches!(kind, L_CURLY | QUOTE | WORD))
+ .is_some()
+ {
+ self.value();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
+ }
+
+ fn preamble(&mut self) {
+ self.builder.start_node(PREAMBLE.into());
+ self.eat();
+ self.trivia();
+ self.left_delimiter_or_missing();
+ self.value_or_missing();
+ self.right_delimiter_or_missing();
+ self.builder.finish_node();
+ }
- let assign = self.expect1(TokenKind::Assign);
- if assign.is_none() {
- return self.graph.add_node(Node::String(Box::new(String {
- range: Range::new(ty.start(), name.as_ref().unwrap().end()),
- ty,
- left,
- name,
- assign: None,
- right: None,
- })));
+ fn string(&mut self) {
+ self.builder.start_node(STRING.into());
+ self.eat();
+ self.trivia();
+ self.left_delimiter_or_missing();
+
+ if self.peek() != Some(WORD) {
+ self.builder.token(MISSING.into(), "");
+ self.builder.finish_node();
+ return;
}
+ self.eat();
+ self.trivia();
+ self.expect(EQUALITY_SIGN);
+
+ self.value_or_missing();
+
+ self.right_delimiter_or_missing();
+ self.builder.finish_node();
+ }
+
+ fn comment(&mut self) {
+ self.builder.start_node(COMMENT.into());
+ self.eat();
+ self.builder.finish_node();
+ }
- if !self.can_match_content() {
- return self.graph.add_node(Node::String(Box::new(String {
- range: Range::new(ty.start(), assign.as_ref().unwrap().end()),
- ty,
- left,
- name,
- assign,
- right: None,
- })));
+ fn entry(&mut self) {
+ self.builder.start_node(ENTRY.into());
+ self.eat();
+ self.trivia();
+
+ self.left_delimiter_or_missing();
+
+ if self.peek() != Some(WORD) {
+ self.builder.token(MISSING.into(), "");
+ self.builder.finish_node();
+ return;
}
- let value = self.content();
-
- let right = self.expect2(TokenKind::EndBrace, TokenKind::EndParen);
- let end = right
- .as_ref()
- .map(Token::end)
- .unwrap_or_else(|| self.graph[value].end());
-
- let parent = self.graph.add_node(Node::String(Box::new(String {
- range: Range::new(ty.start(), end),
- ty,
- left,
- name,
- assign,
- right,
- })));
- self.graph.add_edge(parent, value, ());
- parent
- }
-
- fn entry(&mut self) -> NodeIndex {
- let ty = self.tokens.next().unwrap();
-
- let left = self.expect2(TokenKind::BeginBrace, TokenKind::BeginParen);
- if left.is_none() {
- return self.graph.add_node(Node::Entry(Box::new(Entry {
- range: ty.range(),
- ty,
- left: None,
- key: None,
- comma: None,
- right: None,
- })));
+ self.eat();
+
+ while let Some(kind) = self.peek() {
+ match kind {
+ WHITESPACE => self.eat(),
+ WORD => self.field(),
+ COMMA => self.eat(),
+ _ => break,
+ };
}
- let key = self.expect1(TokenKind::Word);
- if key.is_none() {
- return self.graph.add_node(Node::Entry(Box::new(Entry {
- range: Range::new(ty.start(), left.as_ref().unwrap().end()),
- ty,
- left,
- key: None,
- comma: None,
- right: None,
- })));
- }
+ self.right_delimiter_or_missing();
- let comma = self.expect1(TokenKind::Comma);
- if comma.is_none() {
- return self.graph.add_node(Node::Entry(Box::new(Entry {
- range: Range::new(ty.start(), key.as_ref().unwrap().end()),
- ty,
- left,
- key,
- comma: None,
- right: None,
- })));
- }
+ self.builder.finish_node();
+ }
- let mut fields = Vec::new();
- while self.next_of_kind(TokenKind::Word) {
- fields.push(self.field());
- }
+ fn field(&mut self) {
+ self.builder.start_node(FIELD.into());
+ self.eat();
+ self.trivia();
- let right = self.expect2(TokenKind::EndBrace, TokenKind::EndParen);
-
- let end = right
- .as_ref()
- .map(Token::end)
- .or_else(|| fields.last().map(|field| self.graph[*field].end()))
- .unwrap_or_else(|| comma.as_ref().unwrap().end());
- let parent = self.graph.add_node(Node::Entry(Box::new(Entry {
- range: Range::new(ty.start(), end),
- ty,
- left,
- key,
- comma,
- right,
- })));
- self.connect(parent, &fields);
- parent
- }
-
- fn comment(&mut self) -> NodeIndex {
- let token = self.tokens.next().unwrap();
- self.graph.add_node(Node::Comment(Comment { token }))
- }
-
- fn field(&mut self) -> NodeIndex {
- let name = self.tokens.next().unwrap();
-
- let assign = self.expect1(TokenKind::Assign);
- if assign.is_none() {
- return self.graph.add_node(Node::Field(Box::new(Field {
- range: name.range(),
- name,
- assign: None,
- comma: None,
- })));
+ if self.peek() == Some(EQUALITY_SIGN) {
+ self.eat();
+ self.trivia();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
- if !self.can_match_content() {
- return self.graph.add_node(Node::Field(Box::new(Field {
- range: Range::new(name.start(), assign.as_ref().unwrap().end()),
- name,
- assign,
- comma: None,
- })));
+ if self
+ .lexer
+ .peek()
+ .filter(|&kind| matches!(kind, L_CURLY | QUOTE | WORD))
+ .is_some()
+ {
+ self.value();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
- let content = self.content();
-
- let comma = self.expect1(TokenKind::Comma);
-
- let end = comma
- .as_ref()
- .map(Token::end)
- .unwrap_or_else(|| self.graph[content].end());
- let parent = self.graph.add_node(Node::Field(Box::new(Field {
- range: Range::new(name.start(), end),
- name,
- assign,
- comma,
- })));
- self.graph.add_edge(parent, content, ());
- parent
- }
-
- fn content(&mut self) -> NodeIndex {
- let token = self.tokens.next().unwrap();
- let left = match token.kind {
- TokenKind::PreambleKind
- | TokenKind::StringKind
- | TokenKind::EntryKind
- | TokenKind::Word
- | TokenKind::Assign
- | TokenKind::Comma
- | TokenKind::BeginParen
- | TokenKind::EndParen => self.graph.add_node(Node::Word(Word { token })),
- TokenKind::Command => self.graph.add_node(Node::Command(Command { token })),
- TokenKind::Quote => {
- let mut children = Vec::new();
- while self.can_match_content() {
- if self.next_of_kind(TokenKind::Quote) {
- break;
- }
- children.push(self.content());
- }
- let right = self.expect1(TokenKind::Quote);
-
- let end = right
- .as_ref()
- .map(Token::end)
- .or_else(|| children.last().map(|child| self.graph[*child].end()))
- .unwrap_or_else(|| token.end());
- let parent = self.graph.add_node(Node::QuotedContent(QuotedContent {
- range: Range::new(token.start(), end),
- left: token,
- right,
- }));
- self.connect(parent, &children);
- parent
- }
- TokenKind::BeginBrace => {
- let mut children = Vec::new();
- while self.can_match_content() {
- children.push(self.content());
- }
- let right = self.expect1(TokenKind::EndBrace);
-
- let end = right
- .as_ref()
- .map(Token::end)
- .or_else(|| children.last().map(|child| self.graph[*child].end()))
- .unwrap_or_else(|| token.end());
- let parent = self.graph.add_node(Node::BracedContent(BracedContent {
- range: Range::new(token.start(), end),
- left: token,
- right,
- }));
- self.connect(parent, &children);
- parent
+ self.builder.finish_node();
+ }
+
+ fn value(&mut self) {
+ self.builder.start_node(VALUE.into());
+ self.token();
+ while let Some(kind) = self.peek() {
+ match kind {
+ WHITESPACE => self.eat(),
+ L_CURLY | QUOTE | WORD => self.token(),
+ HASH => self.eat(),
+ _ => break,
}
+ }
+ self.builder.finish_node();
+ }
+
+ fn token(&mut self) {
+ self.builder.start_node(TOKEN.into());
+ match self.peek().unwrap() {
+ L_CURLY => self.brace_group(),
+ QUOTE => self.quote_group(),
+ WORD => self.eat(),
_ => unreachable!(),
};
+ self.builder.finish_node();
+ }
- match self.expect1(TokenKind::Concat) {
- Some(operator) => {
- if self.can_match_content() {
- let right = self.content();
- let parent = self.graph.add_node(Node::Concat(Concat {
- range: Range::new(self.graph[left].start(), self.graph[right].end()),
- operator,
- }));
- self.graph.add_edge(parent, left, ());
- self.graph.add_edge(parent, right, ());
- parent
- } else {
- let parent = self.graph.add_node(Node::Concat(Concat {
- range: Range::new(self.graph[left].start(), operator.end()),
- operator,
- }));
- self.graph.add_edge(parent, left, ());
- parent
- }
- }
- None => left,
+ fn brace_group(&mut self) {
+ self.builder.start_node(BRACE_GROUP.into());
+ self.eat();
+
+ while let Some(kind) = self.peek() {
+ match kind {
+ WHITESPACE => self.eat(),
+ PREAMBLE_TYPE => break,
+ STRING_TYPE => break,
+ COMMENT_TYPE => break,
+ ENTRY_TYPE => break,
+ WORD => self.eat(),
+ L_CURLY => self.brace_group(),
+ R_CURLY => break,
+ L_PAREN => self.eat(),
+ R_PAREN => self.eat(),
+ COMMA => self.eat(),
+ HASH => self.eat(),
+ QUOTE => self.eat(),
+ EQUALITY_SIGN => self.eat(),
+ COMMAND_NAME => self.eat(),
+ _ => unreachable!(),
+ };
}
+
+ self.expect(R_CURLY);
+
+ self.builder.finish_node();
}
- fn connect(&mut self, parent: NodeIndex, children: &[NodeIndex]) {
- for child in children {
- self.graph.add_edge(parent, *child, ());
+ fn quote_group(&mut self) {
+ self.builder.start_node(QUOTE_GROUP.into());
+ self.eat();
+
+ while let Some(kind) = self.peek() {
+ match kind {
+ WHITESPACE => self.eat(),
+ PREAMBLE_TYPE => break,
+ STRING_TYPE => break,
+ COMMENT_TYPE => break,
+ ENTRY_TYPE => break,
+ WORD => self.eat(),
+ L_CURLY => self.brace_group(),
+ R_CURLY => break,
+ L_PAREN => self.eat(),
+ R_PAREN => self.eat(),
+ COMMA => self.eat(),
+ HASH => self.eat(),
+ QUOTE => break,
+ EQUALITY_SIGN => self.eat(),
+ COMMAND_NAME => self.eat(),
+ _ => unreachable!(),
+ };
}
+
+ self.expect(QUOTE);
+ self.builder.finish_node();
}
+}
- fn can_match_content(&mut self) -> bool {
- if let Some(ref token) = self.tokens.peek() {
- match token.kind {
- TokenKind::PreambleKind
- | TokenKind::StringKind
- | TokenKind::EntryKind
- | TokenKind::Word
- | TokenKind::Command
- | TokenKind::Assign
- | TokenKind::Comma
- | TokenKind::Quote
- | TokenKind::BeginBrace
- | TokenKind::BeginParen
- | TokenKind::EndParen => true,
- TokenKind::Concat | TokenKind::EndBrace => false,
- }
- } else {
- false
- }
+pub fn parse(text: &str) -> Parse {
+ Parser::new(Lexer::new(text)).parse()
+}
+
+#[cfg(test)]
+mod tests {
+ use insta::assert_debug_snapshot;
+
+ use super::*;
+
+ fn setup(text: &str) -> SyntaxNode {
+ parse(&text.trim().replace("\r", "")).root
}
- fn expect1(&mut self, kind: TokenKind) -> Option<Token> {
- if let Some(ref token) = self.tokens.peek() {
- if token.kind == kind {
- return self.tokens.next();
- }
- }
- None
+ #[test]
+ fn test_empty() {
+ assert_debug_snapshot!(setup(r#""#));
}
- fn expect2(&mut self, kind1: TokenKind, kind2: TokenKind) -> Option<Token> {
- if let Some(ref token) = self.tokens.peek() {
- if token.kind == kind1 || token.kind == kind2 {
- return self.tokens.next();
- }
- }
- None
+ #[test]
+ fn test_junk() {
+ assert_debug_snapshot!(setup(r#"Hello World!"#));
}
- fn next_of_kind(&mut self, kind: TokenKind) -> bool {
- if let Some(token) = self.tokens.peek() {
- token.kind == kind
- } else {
- false
- }
+ #[test]
+ fn test_preamble_complete() {
+ assert_debug_snapshot!(setup(r#"@preamble{ "Hello World" }"#));
+ }
+
+ #[test]
+ fn test_preamble_missing_end() {
+ assert_debug_snapshot!(setup(r#"@preamble{ "Hello World" "#));
+ }
+
+ #[test]
+ fn test_preamble_casing() {
+ assert_debug_snapshot!(setup(r#"@preAmbLe{ "Hello World" }"#));
+ }
+
+ #[test]
+ fn test_string_complete() {
+ assert_debug_snapshot!(setup(r#"@string{foo = {Hello World}}"#));
+ }
+
+ #[test]
+ fn test_string_incomplete() {
+ assert_debug_snapshot!(setup(r#"@string{foo = {Hello World}"#));
+ }
+
+ #[test]
+ fn test_string_concatenation() {
+ assert_debug_snapshot!(setup(
+ r#"@string{foo = {Hello World}} @string{bar = foo # "!"}"#
+ ));
+ }
+
+ #[test]
+ fn test_string_casing() {
+ assert_debug_snapshot!(setup(r#"@STRING{foo = "Hello World"}"#));
+ }
+
+ #[test]
+ fn test_string_missing_quote() {
+ assert_debug_snapshot!(setup(r#"@STRING{foo = "Hello World}"#));
+ }
+
+ #[test]
+ fn test_entry_no_fields() {
+ assert_debug_snapshot!(setup(r#"@article{foo,}"#));
+ }
+
+ #[test]
+ fn test_entry_no_fields_missing_comma() {
+ assert_debug_snapshot!(setup(r#"@article{foo}"#));
+ }
+
+ #[test]
+ fn test_entry_one_field() {
+ assert_debug_snapshot!(setup(r#"@article{foo, author = {Foo Bar}}"#));
+ }
+
+ #[test]
+ fn test_entry_one_field_number_key() {
+ assert_debug_snapshot!(setup(r#"@article{foo2021, author = {Foo Bar}}"#));
+ }
+
+ #[test]
+ fn test_entry_one_field_trailing_comma() {
+ assert_debug_snapshot!(setup(r#"@article{foo, author = {Foo Bar},}"#));
+ }
+
+ #[test]
+ fn test_entry_two_fields() {
+ assert_debug_snapshot!(setup(
+ r#"@article{foo, author = {Foo Bar}, title = {Hello World}}"#
+ ));
+ }
+
+ #[test]
+ fn test_entry_two_fields_incomplete() {
+ assert_debug_snapshot!(setup(r#"@article{foo, author = {Foo Bar}, t}"#));
+ }
+
+ #[test]
+ fn test_entry_complete_parens() {
+ assert_debug_snapshot!(setup(
+ r#"@article(foo, author = {Foo Bar}, title = {Hello})"#
+ ));
}
}
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__empty.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__empty.snap
new file mode 100644
index 0000000000..55e1954d2f
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__empty.snap
@@ -0,0 +1,7 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"\"#)"
+
+---
+ROOT@0..0
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap
new file mode 100644
index 0000000000..cfd469f161
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap
@@ -0,0 +1,40 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article(foo, author = {Foo Bar}, title = {Hello})\"#)"
+
+---
+ROOT@0..50
+ ENTRY@0..50
+ ENTRY_TYPE@0..8 "@article"
+ L_PAREN@8..9 "("
+ WORD@9..12 "foo"
+ COMMA@12..13 ","
+ WHITESPACE@13..14 " "
+ FIELD@14..32
+ WORD@14..20 "author"
+ WHITESPACE@20..21 " "
+ EQUALITY_SIGN@21..22 "="
+ WHITESPACE@22..23 " "
+ VALUE@23..32
+ TOKEN@23..32
+ BRACE_GROUP@23..32
+ L_CURLY@23..24 "{"
+ WORD@24..27 "Foo"
+ WHITESPACE@27..28 " "
+ WORD@28..31 "Bar"
+ R_CURLY@31..32 "}"
+ COMMA@32..33 ","
+ WHITESPACE@33..34 " "
+ FIELD@34..49
+ WORD@34..39 "title"
+ WHITESPACE@39..40 " "
+ EQUALITY_SIGN@40..41 "="
+ WHITESPACE@41..42 " "
+ VALUE@42..49
+ TOKEN@42..49
+ BRACE_GROUP@42..49
+ L_CURLY@42..43 "{"
+ WORD@43..48 "Hello"
+ R_CURLY@48..49 "}"
+ R_PAREN@49..50 ")"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap
new file mode 100644
index 0000000000..a98df7e382
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap
@@ -0,0 +1,13 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo,}\"#)"
+
+---
+ROOT@0..14
+ ENTRY@0..14
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..12 "foo"
+ COMMA@12..13 ","
+ R_CURLY@13..14 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap
new file mode 100644
index 0000000000..b83037aae0
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap
@@ -0,0 +1,12 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo}\"#)"
+
+---
+ROOT@0..13
+ ENTRY@0..13
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..12 "foo"
+ R_CURLY@12..13 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap
new file mode 100644
index 0000000000..704cbbbd47
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap
@@ -0,0 +1,27 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo, author = {Foo Bar}}\"#)"
+
+---
+ROOT@0..33
+ ENTRY@0..33
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..12 "foo"
+ COMMA@12..13 ","
+ WHITESPACE@13..14 " "
+ FIELD@14..32
+ WORD@14..20 "author"
+ WHITESPACE@20..21 " "
+ EQUALITY_SIGN@21..22 "="
+ WHITESPACE@22..23 " "
+ VALUE@23..32
+ TOKEN@23..32
+ BRACE_GROUP@23..32
+ L_CURLY@23..24 "{"
+ WORD@24..27 "Foo"
+ WHITESPACE@27..28 " "
+ WORD@28..31 "Bar"
+ R_CURLY@31..32 "}"
+ R_CURLY@32..33 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap
new file mode 100644
index 0000000000..8f00c5ee1c
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap
@@ -0,0 +1,27 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo2021, author = {Foo Bar}}\"#)"
+
+---
+ROOT@0..37
+ ENTRY@0..37
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..16 "foo2021"
+ COMMA@16..17 ","
+ WHITESPACE@17..18 " "
+ FIELD@18..36
+ WORD@18..24 "author"
+ WHITESPACE@24..25 " "
+ EQUALITY_SIGN@25..26 "="
+ WHITESPACE@26..27 " "
+ VALUE@27..36
+ TOKEN@27..36
+ BRACE_GROUP@27..36
+ L_CURLY@27..28 "{"
+ WORD@28..31 "Foo"
+ WHITESPACE@31..32 " "
+ WORD@32..35 "Bar"
+ R_CURLY@35..36 "}"
+ R_CURLY@36..37 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap
new file mode 100644
index 0000000000..af8b1593df
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap
@@ -0,0 +1,28 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo, author = {Foo Bar},}\"#)"
+
+---
+ROOT@0..34
+ ENTRY@0..34
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..12 "foo"
+ COMMA@12..13 ","
+ WHITESPACE@13..14 " "
+ FIELD@14..32
+ WORD@14..20 "author"
+ WHITESPACE@20..21 " "
+ EQUALITY_SIGN@21..22 "="
+ WHITESPACE@22..23 " "
+ VALUE@23..32
+ TOKEN@23..32
+ BRACE_GROUP@23..32
+ L_CURLY@23..24 "{"
+ WORD@24..27 "Foo"
+ WHITESPACE@27..28 " "
+ WORD@28..31 "Bar"
+ R_CURLY@31..32 "}"
+ COMMA@32..33 ","
+ R_CURLY@33..34 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap
new file mode 100644
index 0000000000..f47b3b6917
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap
@@ -0,0 +1,42 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo, author = {Foo Bar}, title = {Hello World}}\"#)"
+
+---
+ROOT@0..56
+ ENTRY@0..56
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..12 "foo"
+ COMMA@12..13 ","
+ WHITESPACE@13..14 " "
+ FIELD@14..32
+ WORD@14..20 "author"
+ WHITESPACE@20..21 " "
+ EQUALITY_SIGN@21..22 "="
+ WHITESPACE@22..23 " "
+ VALUE@23..32
+ TOKEN@23..32
+ BRACE_GROUP@23..32
+ L_CURLY@23..24 "{"
+ WORD@24..27 "Foo"
+ WHITESPACE@27..28 " "
+ WORD@28..31 "Bar"
+ R_CURLY@31..32 "}"
+ COMMA@32..33 ","
+ WHITESPACE@33..34 " "
+ FIELD@34..55
+ WORD@34..39 "title"
+ WHITESPACE@39..40 " "
+ EQUALITY_SIGN@40..41 "="
+ WHITESPACE@41..42 " "
+ VALUE@42..55
+ TOKEN@42..55
+ BRACE_GROUP@42..55
+ L_CURLY@42..43 "{"
+ WORD@43..48 "Hello"
+ WHITESPACE@48..49 " "
+ WORD@49..54 "World"
+ R_CURLY@54..55 "}"
+ R_CURLY@55..56 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap
new file mode 100644
index 0000000000..34a9019582
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap
@@ -0,0 +1,33 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@article{foo, author = {Foo Bar}, t}\"#)"
+
+---
+ROOT@0..36
+ ENTRY@0..36
+ ENTRY_TYPE@0..8 "@article"
+ L_CURLY@8..9 "{"
+ WORD@9..12 "foo"
+ COMMA@12..13 ","
+ WHITESPACE@13..14 " "
+ FIELD@14..32
+ WORD@14..20 "author"
+ WHITESPACE@20..21 " "
+ EQUALITY_SIGN@21..22 "="
+ WHITESPACE@22..23 " "
+ VALUE@23..32
+ TOKEN@23..32
+ BRACE_GROUP@23..32
+ L_CURLY@23..24 "{"
+ WORD@24..27 "Foo"
+ WHITESPACE@27..28 " "
+ WORD@28..31 "Bar"
+ R_CURLY@31..32 "}"
+ COMMA@32..33 ","
+ WHITESPACE@33..34 " "
+ FIELD@34..35
+ WORD@34..35 "t"
+ MISSING@35..35 ""
+ MISSING@35..35 ""
+ R_CURLY@35..36 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__junk.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__junk.snap
new file mode 100644
index 0000000000..e77313cabf
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__junk.snap
@@ -0,0 +1,11 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"Hello World!\"#)"
+
+---
+ROOT@0..12
+ JUNK@0..12
+ WORD@0..5 "Hello"
+ WHITESPACE@5..6 " "
+ WORD@6..12 "World!"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_casing.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_casing.snap
new file mode 100644
index 0000000000..f4669b8a01
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_casing.snap
@@ -0,0 +1,21 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@preAmbLe{ \"Hello World\" }\"#)"
+
+---
+ROOT@0..26
+ PREAMBLE@0..26
+ PREAMBLE_TYPE@0..9 "@preAmbLe"
+ L_CURLY@9..10 "{"
+ WHITESPACE@10..11 " "
+ VALUE@11..25
+ TOKEN@11..25
+ QUOTE_GROUP@11..25
+ QUOTE@11..12 "\""
+ WORD@12..17 "Hello"
+ WHITESPACE@17..18 " "
+ WORD@18..23 "World"
+ QUOTE@23..24 "\""
+ WHITESPACE@24..25 " "
+ R_CURLY@25..26 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_complete.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_complete.snap
new file mode 100644
index 0000000000..d1977f2e76
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_complete.snap
@@ -0,0 +1,21 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@preamble{ \"Hello World\" }\"#)"
+
+---
+ROOT@0..26
+ PREAMBLE@0..26
+ PREAMBLE_TYPE@0..9 "@preamble"
+ L_CURLY@9..10 "{"
+ WHITESPACE@10..11 " "
+ VALUE@11..25
+ TOKEN@11..25
+ QUOTE_GROUP@11..25
+ QUOTE@11..12 "\""
+ WORD@12..17 "Hello"
+ WHITESPACE@17..18 " "
+ WORD@18..23 "World"
+ QUOTE@23..24 "\""
+ WHITESPACE@24..25 " "
+ R_CURLY@25..26 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_missing_end.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_missing_end.snap
new file mode 100644
index 0000000000..4ba447a2ae
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__preamble_missing_end.snap
@@ -0,0 +1,20 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@preamble{ \"Hello World\" \"#)"
+
+---
+ROOT@0..24
+ PREAMBLE@0..24
+ PREAMBLE_TYPE@0..9 "@preamble"
+ L_CURLY@9..10 "{"
+ WHITESPACE@10..11 " "
+ VALUE@11..24
+ TOKEN@11..24
+ QUOTE_GROUP@11..24
+ QUOTE@11..12 "\""
+ WORD@12..17 "Hello"
+ WHITESPACE@17..18 " "
+ WORD@18..23 "World"
+ QUOTE@23..24 "\""
+ MISSING@24..24 ""
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_casing.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_casing.snap
new file mode 100644
index 0000000000..1c8b1dbea4
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_casing.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@STRING{foo = \"Hello World\"}\"#)"
+
+---
+ROOT@0..28
+ STRING@0..28
+ STRING_TYPE@0..7 "@STRING"
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ WHITESPACE@11..12 " "
+ EQUALITY_SIGN@12..13 "="
+ WHITESPACE@13..14 " "
+ VALUE@14..27
+ TOKEN@14..27
+ QUOTE_GROUP@14..27
+ QUOTE@14..15 "\""
+ WORD@15..20 "Hello"
+ WHITESPACE@20..21 " "
+ WORD@21..26 "World"
+ QUOTE@26..27 "\""
+ R_CURLY@27..28 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_complete.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_complete.snap
new file mode 100644
index 0000000000..506452894d
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_complete.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@string{foo = {Hello World}}\"#)"
+
+---
+ROOT@0..28
+ STRING@0..28
+ STRING_TYPE@0..7 "@string"
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ WHITESPACE@11..12 " "
+ EQUALITY_SIGN@12..13 "="
+ WHITESPACE@13..14 " "
+ VALUE@14..27
+ TOKEN@14..27
+ BRACE_GROUP@14..27
+ L_CURLY@14..15 "{"
+ WORD@15..20 "Hello"
+ WHITESPACE@20..21 " "
+ WORD@21..26 "World"
+ R_CURLY@26..27 "}"
+ R_CURLY@27..28 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_concatenation.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_concatenation.snap
new file mode 100644
index 0000000000..7f457d6964
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_concatenation.snap
@@ -0,0 +1,43 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@string{foo = {Hello World}} @string{bar = foo # \"!\"}\"#)"
+
+---
+ROOT@0..53
+ STRING@0..29
+ STRING_TYPE@0..7 "@string"
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ WHITESPACE@11..12 " "
+ EQUALITY_SIGN@12..13 "="
+ WHITESPACE@13..14 " "
+ VALUE@14..27
+ TOKEN@14..27
+ BRACE_GROUP@14..27
+ L_CURLY@14..15 "{"
+ WORD@15..20 "Hello"
+ WHITESPACE@20..21 " "
+ WORD@21..26 "World"
+ R_CURLY@26..27 "}"
+ R_CURLY@27..28 "}"
+ WHITESPACE@28..29 " "
+ STRING@29..53
+ STRING_TYPE@29..36 "@string"
+ L_CURLY@36..37 "{"
+ WORD@37..40 "bar"
+ WHITESPACE@40..41 " "
+ EQUALITY_SIGN@41..42 "="
+ WHITESPACE@42..43 " "
+ VALUE@43..52
+ TOKEN@43..46
+ WORD@43..46 "foo"
+ WHITESPACE@46..47 " "
+ HASH@47..48 "#"
+ WHITESPACE@48..49 " "
+ TOKEN@49..52
+ QUOTE_GROUP@49..52
+ QUOTE@49..50 "\""
+ WORD@50..51 "!"
+ QUOTE@51..52 "\""
+ R_CURLY@52..53 "}"
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_incomplete.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_incomplete.snap
new file mode 100644
index 0000000000..685d02a179
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_incomplete.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@string{foo = {Hello World}\"#)"
+
+---
+ROOT@0..27
+ STRING@0..27
+ STRING_TYPE@0..7 "@string"
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ WHITESPACE@11..12 " "
+ EQUALITY_SIGN@12..13 "="
+ WHITESPACE@13..14 " "
+ VALUE@14..27
+ TOKEN@14..27
+ BRACE_GROUP@14..27
+ L_CURLY@14..15 "{"
+ WORD@15..20 "Hello"
+ WHITESPACE@20..21 " "
+ WORD@21..26 "World"
+ R_CURLY@26..27 "}"
+ MISSING@27..27 ""
+
diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_missing_quote.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_missing_quote.snap
new file mode 100644
index 0000000000..8eeefa9bf9
--- /dev/null
+++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__string_missing_quote.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/bibtex/parser.rs
+expression: "setup(r#\"@STRING{foo = \"Hello World}\"#)"
+
+---
+ROOT@0..27
+ STRING@0..27
+ STRING_TYPE@0..7 "@STRING"
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ WHITESPACE@11..12 " "
+ EQUALITY_SIGN@12..13 "="
+ WHITESPACE@13..14 " "
+ VALUE@14..26
+ TOKEN@14..26
+ QUOTE_GROUP@14..26
+ QUOTE@14..15 "\""
+ WORD@15..20 "Hello"
+ WHITESPACE@20..21 " "
+ WORD@21..26 "World"
+ MISSING@26..26 ""
+ R_CURLY@26..27 "}"
+
diff --git a/support/texlab/src/diagnostics/build.rs b/support/texlab/src/syntax/build_log.rs
index 16870e8fd8..65a5938262 100644
--- a/support/texlab/src/diagnostics/build.rs
+++ b/support/texlab/src/syntax/build_log.rs
@@ -1,136 +1,20 @@
-use crate::{
- protocol::{Diagnostic, DiagnosticSeverity, Options, Position, Range, Uri},
- workspace::{Document, Snapshot},
-};
-use futures::lock::Mutex;
+use std::{cmp::Ordering, path::PathBuf};
+
use once_cell::sync::Lazy;
use regex::{Match, Regex};
-use std::{
- cmp::Ordering,
- collections::HashMap,
- io,
- path::{Path, PathBuf},
- str,
- time::SystemTime,
-};
-use tokio::fs;
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-struct LogFile {
- path: PathBuf,
- modified: SystemTime,
-}
-
-#[derive(Debug, Default)]
-pub struct BuildDiagnosticsProvider {
- diagnostics_by_uri: Mutex<HashMap<Uri, Vec<Diagnostic>>>,
- log_files: Mutex<Vec<LogFile>>,
-}
-
-impl BuildDiagnosticsProvider {
- pub async fn get(&self, doc: &Document) -> Vec<Diagnostic> {
- match self.diagnostics_by_uri.lock().await.get(&doc.uri) {
- Some(diagnostics) => diagnostics.to_owned(),
- None => Vec::new(),
- }
- }
-
- pub async fn update(
- &self,
- snapshot: &Snapshot,
- tex_uri: &Uri,
- options: &Options,
- current_dir: &Path,
- ) -> io::Result<bool> {
- let log_uris = snapshot
- .resolve_aux_targets(tex_uri, options, current_dir, "log")
- .unwrap_or_default();
- if let Some(log_path) = log_uris
- .into_iter()
- .filter(|uri| uri.scheme() == "file")
- .filter_map(|uri| uri.to_file_path().ok())
- .find(|path| path.exists())
- {
- let modified = fs::metadata(&log_path).await?.modified()?;
- let mut log_files = self.log_files.lock().await;
- for log_file in log_files.iter_mut() {
- if log_file.path == log_path {
- return if modified > log_file.modified {
- log_file.modified = modified;
- self.update_diagnostics(tex_uri, &log_path).await
- } else {
- Ok(false)
- };
- }
- }
-
- self.update_diagnostics(tex_uri, &log_path).await?;
- log_files.push(LogFile {
- path: log_path,
- modified,
- });
- }
-
- Ok(true)
- }
-
- async fn update_diagnostics(&self, tex_uri: &Uri, log_path: &Path) -> io::Result<bool> {
- let log = String::from_utf8_lossy(&fs::read(log_path).await?).into_owned();
- let mut diagnostics_by_uri = self.diagnostics_by_uri.lock().await;
- diagnostics_by_uri.clear();
- for error in parse_build_log(tex_uri, &log) {
- let diagnostics = diagnostics_by_uri
- .entry(error.uri.clone())
- .or_insert_with(Vec::new);
- diagnostics.push(error.into());
- }
- Ok(true)
- }
-}
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum BuildErrorKind {
+#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
+pub enum BuildErrorLevel {
Error,
Warning,
}
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct BuildError {
- pub uri: Uri,
- pub kind: BuildErrorKind,
+ pub relative_path: PathBuf,
+ pub level: BuildErrorLevel,
pub message: String,
- pub line: Option<u64>,
-}
-
-impl BuildError {
- pub fn new(uri: Uri, kind: BuildErrorKind, message: String, line: Option<u64>) -> Self {
- Self {
- uri,
- kind,
- message,
- line,
- }
- }
-}
-
-impl Into<Diagnostic> for BuildError {
- fn into(self) -> Diagnostic {
- let position = Position::new(self.line.unwrap_or(0), 0);
- let severity = match self.kind {
- BuildErrorKind::Error => DiagnosticSeverity::Error,
- BuildErrorKind::Warning => DiagnosticSeverity::Warning,
- };
- let range = Range::new(position, position);
- Diagnostic {
- range,
- severity: Some(severity),
- source: Some("latex".into()),
- code: None,
- message: self.message,
- tags: None,
- related_information: None,
- }
- }
+ pub line: Option<u32>,
}
const MAX_LINE_LENGTH: usize = 79;
@@ -152,27 +36,33 @@ pub static BAD_BOX_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new("(?P<msg>(Ov|Und)erfull \\\\[hv]box[^\r\n]*lines? (?P<line>\\d+)[^\r\n]*)").unwrap()
});
-fn parse_build_log(uri: &Uri, log: &str) -> Vec<BuildError> {
+#[derive(Debug, PartialEq, Eq, Clone, Hash)]
+pub struct Parse {
+ pub errors: Vec<BuildError>,
+}
+
+pub fn parse(log: &str) -> Parse {
let log = prepare_log(log);
let mut ranges: Vec<FileRange> = FILE_REGEX
.find_iter(&log)
- .map(|result| create_file_range(uri.clone(), &log, result))
+ .map(|result| FileRange::create(&log, result))
.collect();
ranges.sort();
- let tex_errors = extract_matches(&log, &uri, &ranges, &TEX_ERROR_REGEX, BuildErrorKind::Error);
- let warnings = extract_matches(&log, &uri, &ranges, &WARNING_REGEX, BuildErrorKind::Warning);
- let bad_boxes = extract_matches(&log, &uri, &ranges, &BAD_BOX_REGEX, BuildErrorKind::Warning);
+ let tex_errors = extract_matches(&log, &ranges, &TEX_ERROR_REGEX, BuildErrorLevel::Error);
+ let warnings = extract_matches(&log, &ranges, &WARNING_REGEX, BuildErrorLevel::Warning);
+ let bad_boxes = extract_matches(&log, &ranges, &BAD_BOX_REGEX, BuildErrorLevel::Warning);
- vec![tex_errors, warnings, bad_boxes].concat()
+ Parse {
+ errors: vec![tex_errors, warnings, bad_boxes].concat(),
+ }
}
fn extract_matches(
log: &str,
- parent_uri: &Uri,
ranges: &[FileRange],
regex: &Regex,
- kind: BuildErrorKind,
+ level: BuildErrorLevel,
) -> Vec<BuildError> {
let mut errors = Vec::new();
for result in regex.find_iter(&log) {
@@ -191,10 +81,14 @@ fn extract_matches(
if let Some(range) = ranges.iter().find(|range| range.contains(result.start())) {
let line = captures
.name("line")
- .map(|result| u64::from_str_radix(result.as_str(), 10).unwrap() - 1);
+ .map(|result| u32::from_str_radix(result.as_str(), 10).unwrap() - 1);
- let uri = range.uri.as_ref().unwrap_or(parent_uri);
- errors.push(BuildError::new(uri.clone(), kind, message, line));
+ errors.push(BuildError {
+ relative_path: range.path.clone(),
+ level,
+ message,
+ line,
+ });
}
}
errors
@@ -230,52 +124,41 @@ fn prepare_log(log: &str) -> String {
new_lines.join("\n")
}
-fn create_file_range(parent: Uri, log: &str, result: Match) -> FileRange {
- let mut balance = 1;
- let mut end = result.start() + 1;
- let chars = (&log[result.start() + 1..]).chars();
- for c in chars {
- if balance <= 0 {
- break;
- }
-
- if c == '(' {
- balance += 1;
- } else if c == ')' {
- balance -= 1;
- }
- end += c.len_utf8();
- }
-
- let captures = FILE_REGEX.captures(result.as_str()).unwrap();
- let base_path = PathBuf::from(parent.path());
- let mut full_path = base_path.clone();
- full_path.push(captures.name("file").unwrap().as_str());
- let uri = if full_path.starts_with(base_path) {
- parent
- .join(captures.name("file").unwrap().as_str())
- .map(Into::into)
- .ok()
- } else {
- None
- };
-
- FileRange::new(uri, result.start(), end)
-}
-
#[derive(Debug, PartialEq, Eq, Clone)]
struct FileRange {
- pub uri: Option<Uri>,
+ pub path: PathBuf,
pub start: usize,
pub end: usize,
}
impl FileRange {
- fn new(uri: Option<Uri>, start: usize, end: usize) -> Self {
- Self { uri, start, end }
+ fn create(log: &str, result: Match) -> Self {
+ let mut balance = 1;
+ let mut end = result.start() + 1;
+ let chars = (&log[result.start() + 1..]).chars();
+ for c in chars {
+ if balance <= 0 {
+ break;
+ }
+
+ if c == '(' {
+ balance += 1;
+ } else if c == ')' {
+ balance -= 1;
+ }
+ end += c.len_utf8();
+ }
+
+ let captures = FILE_REGEX.captures(result.as_str()).unwrap();
+ let path = PathBuf::from(captures.name("file").unwrap().as_str());
+ Self {
+ path,
+ start: result.start(),
+ end,
+ }
}
- fn length(&self) -> usize {
+ fn len(&self) -> usize {
self.end - self.start + 1
}
@@ -285,13 +168,13 @@ impl FileRange {
}
impl Ord for FileRange {
- fn cmp(&self, other: &FileRange) -> Ordering {
- self.length().cmp(&other.length())
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.len().cmp(&other.len())
}
}
impl PartialOrd for FileRange {
- fn partial_cmp(&self, other: &FileRange) -> Option<Ordering> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
@@ -301,15 +184,10 @@ mod tests {
use super::*;
use indoc::indoc;
- fn create_uri(name: &str) -> Uri {
- let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(name);
- Uri::from_file_path(path.to_str().unwrap()).unwrap()
- }
-
#[test]
- fn bad_box() {
- let log = indoc!(
- r#"
+ fn test_parse_001() {
+ let log = indoc! {
+ r#"
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/W32TeX) (preloaded format=pdflatex 2018.3.30) 26 DEC 2018 16:50
entering extended mode
restricted \write18 enabled.
@@ -362,7 +240,7 @@ mod tests {
Overfull \hbox (200.00162pt too wide) in paragraph at lines 8--9
[]\OT1/cmr/m/n/10 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[]
LaTeX Font Info: External font `cmex10' loaded for size
@@ -392,30 +270,33 @@ mod tests {
16 PDF objects out of 1000 (max. 8388607)
10 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
- 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#
- );
-
- let actual_errors = parse_build_log(&create_uri("parent.tex"), log);
+ 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#,
+ };
- let error1 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "Overfull \\hbox (200.00162pt too wide) in paragraph at lines 8--9".into(),
- Some(7),
- );
- let error2 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "Overfull \\vbox (3.19998pt too high) detected at line 23".into(),
- Some(22),
+ assert_eq!(
+ parse(&log).errors,
+ vec![
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "Overfull \\hbox (200.00162pt too wide) in paragraph at lines 8--9"
+ .into(),
+ line: Some(7),
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "Overfull \\vbox (3.19998pt too high) detected at line 23".into(),
+ line: Some(22),
+ }
+ ]
);
- assert_eq!(actual_errors, vec![error1, error2]);
}
#[test]
- fn related() {
- let log = indoc!(
- r#"
+ fn test_parse_002() {
+ let log = indoc! {
+ r#"
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/W32TeX) (preloaded format=pdflatex 2018.3.30) 26 DEC 2018 16:52
entering extended mode
restricted \write18 enabled.
@@ -442,7 +323,7 @@ mod tests {
\bibindent=\dimen102
) (./parent.aux (./child.aux))
\openout1 = `parent.aux'.
-
+
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 4.
LaTeX Font Info: ... okay on input line 4.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 4.
@@ -458,14 +339,14 @@ mod tests {
(./child.tex
! Undefined control sequence.
l.1 \foo
-
+
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
-
- ) (./parent.aux) )
+
+ ) (./parent.aux) )
Here is how much of TeX's memory you used:
205 strings out of 492995
2149 string characters out of 6138727
@@ -474,29 +355,29 @@ mod tests {
3640 words of font info for 14 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
23i,1n,17p,116b,36s stack positions out of 5000i,500n,10000p,200000b,80000s
-
+
No pages of output.
PDF statistics:
0 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
- 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#
- );
-
- let actual_errors = parse_build_log(&create_uri("parent.tex"), log);
+ 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#,
+ };
- let error = BuildError::new(
- create_uri("child.tex"),
- BuildErrorKind::Error,
- "Undefined control sequence.".into(),
- Some(0),
+ assert_eq!(
+ parse(&log).errors,
+ vec![BuildError {
+ relative_path: "./child.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Undefined control sequence.".into(),
+ line: Some(0)
+ }]
);
- assert_eq!(actual_errors, vec![error]);
}
#[test]
- fn citation_warning() {
- let log = indoc!(
- r#"
+ fn test_parse_003() {
+ let log = indoc! {
+ r#"
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/W32TeX) (preloaded format=pdflatex 2018.3.30) 26 DEC 2018 16:51
entering extended mode
restricted \write18 enabled.
@@ -523,7 +404,7 @@ mod tests {
\bibindent=\dimen102
) (./parent.aux)
\openout1 = `parent.aux'.
-
+
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 4.
LaTeX Font Info: ... okay on input line 4.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 4.
@@ -536,17 +417,16 @@ mod tests {
LaTeX Font Info: ... okay on input line 4.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 4.
LaTeX Font Info: ... okay on input line 4.
-
-
+
LaTeX Warning: Citation `foo' on page 1 undefined on input line 6.
-
+
[1
-
+
{/TexLive/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./parent.aux)
-
+
LaTeX Warning: There were undefined references.
-
- )
+
+ )
Here is how much of TeX's memory you used:
204 strings out of 492995
2142 string characters out of 6138727
@@ -562,30 +442,32 @@ mod tests {
16 PDF objects out of 1000 (max. 8388607)
10 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
- 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#
- );
-
- let actual_errors = parse_build_log(&create_uri("parent.tex"), log);
+ 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#,
+ };
- let error1 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "Citation `foo' on page 1 undefined on input line 6.".into(),
- None,
- );
- let error2 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "There were undefined references.".into(),
- None,
+ assert_eq!(
+ parse(&log).errors,
+ vec![
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "Citation `foo' on page 1 undefined on input line 6.".into(),
+ line: None
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "There were undefined references.".into(),
+ line: None,
+ }
+ ]
);
- assert_eq!(actual_errors, vec![error1, error2]);
}
#[test]
- fn package_error() {
- let log = indoc!(
- r#"
+ fn test_parse_004() {
+ let log = indoc! {
+ r#"
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/W32TeX) (preloaded format=pdflatex 2018.3.30) 26 DEC 2018 16:40
entering extended mode
restricted \write18 enabled.
@@ -613,37 +495,35 @@ mod tests {
)
(/TexLive/texmf-dist/tex/generic/babel/babel.sty
Package: babel 2017/05/19 3.10 The Babel package
-
-
+
! Package babel Error: Unknown option `foo'. Either you misspelled it
(babel) or the language definition file foo.ldf was not found.
-
+
See the babel package documentation for explanation.
Type H <return> for immediate help.
- ...
-
+ ...
+
l.393 \ProcessOptions*
-
+
Valid options are: shorthands=, KeepShorthandsActive,
activeacute, activegrave, noconfigs, safe=, main=, math=
headfoot=, strings=, config=, hyphenmap=, or a language name.
-
-
+
! Package babel Error: You haven't specified a language option.
-
+
See the babel package documentation for explanation.
Type H <return> for immediate help.
- ...
-
+ ...
+
l.426 ...ry to proceed from here, type x to quit.}
-
+
You need to specify a language, either as a global option
or as an optional argument to the \usepackage command;
You shouldn't try to proceed from here, type x to quit.
-
+
) (./parent.aux)
\openout1 = `parent.aux'.
-
+
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 5.
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 5.
@@ -656,7 +536,7 @@ mod tests {
LaTeX Font Info: ... okay on input line 5.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 5.
LaTeX Font Info: ... okay on input line 5.
- (./parent.aux) )
+ (./parent.aux) )
Here is how much of TeX's memory you used:
304 strings out of 492995
3421 string characters out of 6138727
@@ -665,36 +545,37 @@ mod tests {
3640 words of font info for 14 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
23i,1n,17p,116b,36s stack positions out of 5000i,500n,10000p,200000b,80000s
-
+
No pages of output.
PDF statistics:
0 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
- 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#
- );
-
- let actual_errors = parse_build_log(&create_uri("parent.tex"), log);
+ 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#,
+ };
- let error1 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Package babel Error: Unknown option `foo'. Either you misspelled it or the language definition file foo.ldf was not found."
- .into(),
- Some(392),
- );
- let error2 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Package babel Error: You haven't specified a language option.".into(),
- Some(425),
+ assert_eq!(
+ parse(&log).errors,
+ vec![
+ BuildError {
+ relative_path: "/TexLive/texmf-dist/tex/generic/babel/babel.sty".into(),
+ level: BuildErrorLevel::Error,
+ message: "Package babel Error: Unknown option `foo'. Either you misspelled it or the language definition file foo.ldf was not found.".into(),
+ line: Some(392)
+ },
+ BuildError {
+ relative_path: "/TexLive/texmf-dist/tex/generic/babel/babel.sty".into(),
+ level: BuildErrorLevel::Error,
+ message: "Package babel Error: You haven't specified a language option.".into(),
+ line: Some(425)
+ }
+ ]
);
- assert_eq!(actual_errors, vec![error1, error2]);
}
#[test]
- fn package_warning() {
- let log = indoc!(
- r#"
+ fn test_parse_005() {
+ let log = indoc! {
+ r#"
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/W32TeX) (preloaded format=pdflatex 2018.3.30) 26 DEC 2018 16:45
entering extended mode
restricted \write18 enabled.
@@ -722,10 +603,10 @@ mod tests {
)
(/TexLive/texmf-dist/tex/generic/babel/babel.sty
Package: babel 2017/05/19 3.10 The Babel package
-
+
(/TexLive/texmf-dist/tex/generic/babel-spanish/spanish.ldf
Language: spanish.ldf 2016/03/03 v5.0p Spanish support from the babel system
-
+
(/TexLive/texmf-dist/tex/generic/babel/babel.def
File: babel.def 2017/05/19 3.10 Babel common definitions
\babel@savecnt=\count87
@@ -740,11 +621,11 @@ mod tests {
))
(/TexLive/texmf-dist/tex/latex/biblatex/biblatex.sty
Package: biblatex 2016/12/05 v3.7 programmable bibliographies (PK/JW/AB)
-
+
(/TexLive/texmf-dist/tex/generic/oberdiek/pdftexcmds.sty
Package: pdftexcmds 2017/03/19 v0.25 Utility functions of pdfTeX for LuaTeX (HO
)
-
+
(/TexLive/texmf-dist/tex/generic/oberdiek/infwarerr.sty
Package: infwarerr 2016/05/16 v1.4 Providing info/warning/error messages (HO)
)
@@ -773,10 +654,10 @@ mod tests {
)
(/TexLive/texmf-dist/tex/latex/oberdiek/kvoptions.sty
Package: kvoptions 2016/05/16 v3.12 Key value format for package options (HO)
-
+
(/TexLive/texmf-dist/tex/generic/oberdiek/kvsetkeys.sty
Package: kvsetkeys 2016/05/16 v1.17 Key value parser (HO)
-
+
(/TexLive/texmf-dist/tex/generic/oberdiek/etexcmds.sty
Package: etexcmds 2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO)
Package etexcmds Info: Could not find \expanded.
@@ -787,7 +668,7 @@ mod tests {
(/TexLive/texmf-dist/tex/latex/logreq/logreq.sty
Package: logreq 2010/08/04 v1.0 xml request logger
\lrq@indent=\count90
-
+
(/TexLive/texmf-dist/tex/latex/logreq/logreq.def
File: logreq.def 2010/08/04 v1.0 logreq spec v1.0
))
@@ -859,7 +740,7 @@ mod tests {
\c@mincompwidth=\count133
Package biblatex Info: Trying to load biblatex default data model...
Package biblatex Info: ... file 'blx-dm.def' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/blx-dm.def)
Package biblatex Info: Trying to load biblatex style data model...
Package biblatex Info: ... file 'ieee.dbx' not found.
@@ -939,13 +820,13 @@ mod tests {
\shorteditorwidth=\skip56
Package biblatex Info: Trying to load compatibility code...
Package biblatex Info: ... file 'blx-compat.def' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/blx-compat.def
File: blx-compat.def 2016/12/05 v3.7 biblatex compatibility (PK/JW/AB)
)
Package biblatex Info: Trying to load generic definitions...
Package biblatex Info: ... file 'biblatex.def' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/biblatex.def
File: biblatex.def 2016/12/05 v3.7 biblatex compatibility (PK/JW/AB)
\c@textcitecount=\count266
@@ -958,22 +839,22 @@ mod tests {
)
Package biblatex Info: Trying to load bibliography style 'ieee'...
Package biblatex Info: ... file 'ieee.bbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex-ieee/ieee.bbx
File: ieee.bbx 2017/03/27 v1.2d biblatex bibliography style
Package biblatex Info: Trying to load bibliography style 'numeric-comp'...
Package biblatex Info: ... file 'numeric-comp.bbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/bbx/numeric-comp.bbx
File: numeric-comp.bbx 2016/12/05 v3.7 biblatex bibliography style (PK/JW/AB)
Package biblatex Info: Trying to load bibliography style 'numeric'...
Package biblatex Info: ... file 'numeric.bbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/bbx/numeric.bbx
File: numeric.bbx 2016/12/05 v3.7 biblatex bibliography style (PK/JW/AB)
Package biblatex Info: Trying to load bibliography style 'standard'...
Package biblatex Info: ... file 'standard.bbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/bbx/standard.bbx
File: standard.bbx 2016/12/05 v3.7 biblatex bibliography style (PK/JW/AB)
\c@bbx:relatedcount=\count273
@@ -981,12 +862,12 @@ mod tests {
))))
Package biblatex Info: Trying to load citation style 'ieee'...
Package biblatex Info: ... file 'ieee.cbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex-ieee/ieee.cbx
File: ieee.cbx 2017/03/27 v1.2d biblatex citation style
Package biblatex Info: Trying to load citation style 'numeric-comp'...
Package biblatex Info: ... file 'numeric-comp.cbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/cbx/numeric-comp.cbx
File: numeric-comp.cbx 2016/12/05 v3.7 biblatex citation style (PK/JW/AB)
\c@cbx@tempcnta=\count275
@@ -1008,25 +889,25 @@ mod tests {
)
Package biblatex Info: Trying to load configuration file...
Package biblatex Info: ... file 'biblatex.cfg' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/biblatex.cfg
- File: biblatex.cfg
+ File: biblatex.cfg
))
Package biblatex Info: Trying to load language 'spanish'...
Package biblatex Info: ... file 'spanish.lbx' found.
-
+
(/TexLive/texmf-dist/tex/latex/biblatex/lbx/spanish.lbx
File: spanish.lbx 2016/12/05 v3.7 biblatex localization (PK/JW/AB)
)
-
+
Package biblatex Warning: 'babel/polyglossia' detected but 'csquotes' missing.
(biblatex) Loading 'csquotes' recommended.
-
+
\@quotelevel=\count277
\@quotereset=\count278
(./parent.aux)
\openout1 = `parent.aux'.
-
+
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 6.
LaTeX Font Info: ... okay on input line 6.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 6.
@@ -1047,26 +928,25 @@ mod tests {
Package biblatex Info: Automatic encoding selection.
(biblatex) Assuming data encoding 'ascii'.
\openout4 = `parent.bcf'.
-
+
Package biblatex Info: Trying to load bibliographic data...
Package biblatex Info: ... file 'parent.bbl' not found.
-
+
No file parent.bbl.
Package biblatex Info: Reference section=0 on input line 6.
Package biblatex Info: Reference segment=0 on input line 6.
(./parent.aux)
-
+
LaTeX Warning: There were undefined references.
-
-
+
Package biblatex Warning: Please (re)run Biber on the file:
(biblatex) parent
(biblatex) and rerun LaTeX afterwards.
-
+
Package logreq Info: Writing requests to 'parent.run.xml'.
\openout1 = `parent.run.xml'.
-
- )
+
+ )
Here is how much of TeX's memory you used:
7717 strings out of 492995
133301 string characters out of 6138727
@@ -1075,41 +955,42 @@ mod tests {
3640 words of font info for 14 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
35i,1n,30p,856b,700s stack positions out of 5000i,500n,10000p,200000b,80000s
-
+
No pages of output.
PDF statistics:
0 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
- 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#
- );
-
- let actual_errors = parse_build_log(&create_uri("parent.tex"), log);
+ 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#,
+ };
- let error1 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "'babel/polyglossia' detected but 'csquotes' missing. Loading 'csquotes' recommended."
- .to_owned(),
- None,
- );
- let error2 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "There were undefined references.".into(),
- None,
- );
- let error3 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Warning,
- "Please (re)run Biber on the file: parent and rerun LaTeX afterwards.".into(),
- None,
+ assert_eq!(
+ parse(&log).errors,
+ vec![
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "'babel/polyglossia' detected but 'csquotes' missing. Loading 'csquotes' recommended.".into(),
+ line: None
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "There were undefined references.".into(),
+ line: None,
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Warning,
+ message: "Please (re)run Biber on the file: parent and rerun LaTeX afterwards.".into(),
+ line: None
+ }
+ ]
);
- assert_eq!(actual_errors, vec![error1, error2, error3]);
}
#[test]
- fn tex_error() {
- let log = indoc!(
+ fn test_parse_006() {
+ let log = indoc! {
r#"
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/W32TeX) (preloaded format=pdflatex 2018.3.30) 26 DEC 2018 16:33
entering extended mode
@@ -1138,7 +1019,7 @@ mod tests {
) (./parent.aux
(./child.tex.aux))
\openout1 = `parent.aux'.
-
+
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 3.
LaTeX Font Info: ... okay on input line 3.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 3.
@@ -1152,73 +1033,71 @@ mod tests {
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 3.
LaTeX Font Info: ... okay on input line 3.
\openout2 = `child.aux'.
-
+
(./child.tex)
! Undefined control sequence.
l.7 \foo
-
+
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
-
+
! Missing $ inserted.
- <inserted text>
+ <inserted text>
$
l.8 \bar
-
+
I've inserted a begin-math/end-math symbol since I think
you left one out. Proceed, with fingers crossed.
-
+
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <7> on input line 8.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <5> on input line 8.
! Undefined control sequence.
l.9 \baz
-
+
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
-
+
! Missing { inserted.
- <to be read again>
- \par
- l.10
-
+ <to be read again>
+ \par
+ l.10
+
A left brace was mandatory here, so I've put one in.
You might want to delete and/or insert some corrections
so that I will find a matching right brace soon.
(If you're confused by all this, try typing `I}' now.)
-
+
! Missing $ inserted.
- <inserted text>
+ <inserted text>
$
- l.10
-
+ l.10
+
I've inserted a begin-math/end-math symbol since I think
you left one out. Proceed, with fingers crossed.
-
+
! Missing } inserted.
- <inserted text>
+ <inserted text>
}
- l.10
-
+ l.10
+
I've inserted something that you may have forgotten.
(See the <inserted text> above.)
With luck, this will get me unwedged. But if you
really didn't forget anything, try typing `2' now; then
my insertion and my current dilemma will both disappear.
-
+
[1
-
-
-
+
{/TexLive/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./parent.aux
- (./child.aux)) )
+ (./child.aux)) )
Here is how much of TeX's memory you used:
212 strings out of 492995
2238 string characters out of 6138727
@@ -1234,50 +1113,49 @@ mod tests {
12 PDF objects out of 1000 (max. 8388607)
7 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
- 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#
- );
-
- let actual_errors = parse_build_log(&create_uri("parent.tex"), log);
+ 1 words of extra memory for PDF output out of 10000 (max. 10000000)"#,
+ };
- let error1 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Undefined control sequence.".into(),
- Some(6),
- );
- let error2 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Missing $ inserted.".into(),
- Some(7),
- );
- let error3 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Undefined control sequence.".into(),
- Some(8),
- );
- let error4 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Missing { inserted.".into(),
- Some(9),
- );
- let error5 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Missing $ inserted.".into(),
- Some(9),
- );
- let error6 = BuildError::new(
- create_uri("parent.tex"),
- BuildErrorKind::Error,
- "Missing } inserted.".into(),
- Some(9),
- );
assert_eq!(
- actual_errors,
- vec![error1, error2, error3, error4, error5, error6]
+ parse(&log).errors,
+ vec![
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Undefined control sequence.".into(),
+ line: Some(6)
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Missing $ inserted.".into(),
+ line: Some(7)
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Undefined control sequence.".into(),
+ line: Some(8)
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Missing { inserted.".into(),
+ line: Some(9)
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Missing $ inserted.".into(),
+ line: Some(9)
+ },
+ BuildError {
+ relative_path: "./parent.tex".into(),
+ level: BuildErrorLevel::Error,
+ message: "Missing } inserted.".into(),
+ line: Some(9)
+ },
+ ]
);
}
}
diff --git a/support/texlab/src/syntax/generic_ast.rs b/support/texlab/src/syntax/generic_ast.rs
deleted file mode 100644
index 3311460c0a..0000000000
--- a/support/texlab/src/syntax/generic_ast.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use serde::{Deserialize, Serialize};
-use std::ops::Index;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-pub struct AstNodeIndex(usize);
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct Ast<T> {
- nodes: Vec<T>,
- edges: Vec<Vec<AstNodeIndex>>,
-}
-
-impl<T> Ast<T> {
- pub fn new() -> Self {
- Self {
- nodes: Vec::new(),
- edges: Vec::new(),
- }
- }
-
- pub fn nodes(&self) -> Vec<AstNodeIndex> {
- let mut nodes = Vec::new();
- for i in 0..self.nodes.len() {
- nodes.push(AstNodeIndex(i));
- }
- nodes
- }
-
- pub fn add_node(&mut self, value: T) -> AstNodeIndex {
- let node = AstNodeIndex(self.nodes.len());
- self.nodes.push(value);
- self.edges.push(Vec::new());
- node
- }
-
- pub fn add_edge(&mut self, parent: AstNodeIndex, child: AstNodeIndex) {
- self.edges[parent.0].push(child);
- }
-
- pub fn children<'a>(&'a self, parent: AstNodeIndex) -> impl Iterator<Item = AstNodeIndex> + 'a {
- self.edges[parent.0].iter().map(|child| *child)
- }
-}
-
-impl<T> Index<AstNodeIndex> for Ast<T> {
- type Output = T;
-
- fn index(&self, index: AstNodeIndex) -> &Self::Output {
- &self.nodes[index.0]
- }
-}
diff --git a/support/texlab/src/syntax/lang_data.rs b/support/texlab/src/syntax/lang_data.rs
deleted file mode 100644
index 4ea7cc44da..0000000000
--- a/support/texlab/src/syntax/lang_data.rs
+++ /dev/null
@@ -1,231 +0,0 @@
-use once_cell::sync::Lazy;
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexEnvironmentCommand {
- pub name: String,
- pub index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexCitationCommand {
- pub name: String,
- pub index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum LatexLabelReferenceSource {
- Everything,
- Math,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum LatexLabelKind {
- Definition,
- Reference(LatexLabelReferenceSource),
-}
-
-impl LatexLabelKind {
- pub fn is_reference(self) -> bool {
- match self {
- LatexLabelKind::Definition => false,
- LatexLabelKind::Reference(_) => true,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexLabelCommand {
- pub name: String,
- pub index: usize,
- pub kind: LatexLabelKind,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexSectionCommand {
- pub name: String,
- pub index: usize,
- pub level: i32,
- pub prefix: String,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum LatexIncludeKind {
- Package,
- Class,
- Latex,
- Bibliography,
- Image,
- Svg,
- Pdf,
- Everything,
-}
-
-impl LatexIncludeKind {
- pub fn extensions(self) -> Option<&'static [&'static str]> {
- match self {
- LatexIncludeKind::Package => Some(&["sty"]),
- LatexIncludeKind::Class => Some(&["cls"]),
- LatexIncludeKind::Latex => Some(&["tex"]),
- LatexIncludeKind::Bibliography => Some(&["bib"]),
- LatexIncludeKind::Image => Some(&["pdf", "png", "jpg", "jpeg", "bmp"]),
- LatexIncludeKind::Svg => Some(&["svg"]),
- LatexIncludeKind::Pdf => Some(&["pdf"]),
- LatexIncludeKind::Everything => None,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexIncludeCommand {
- pub name: String,
- pub index: usize,
- pub kind: LatexIncludeKind,
- pub include_extension: bool,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexCommandDefinitionCommand {
- pub name: String,
- pub definition_index: usize,
- pub arg_count_index: usize,
- pub implementation_index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexMathOperatorCommand {
- pub name: String,
- pub definition_index: usize,
- pub implementation_index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexTheoremDefinitionCommand {
- pub name: String,
- pub index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexColorCommand {
- pub name: String,
- pub index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexColorModelCommand {
- pub name: String,
- pub index: usize,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum LatexGlossaryEntryKind {
- General,
- Acronym,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexGlossaryEntryDefinitionCommand {
- pub name: String,
- pub label_index: usize,
- pub kind: LatexGlossaryEntryKind,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LatexGlossaryEntryReferenceCommand {
- pub name: String,
- pub index: usize,
- pub kind: LatexGlossaryEntryKind,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum BibtexEntryTypeCategory {
- Misc,
- String,
- Article,
- Book,
- Collection,
- Part,
- Thesis,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BibtexEntryTypeDoc {
- pub name: String,
- pub category: BibtexEntryTypeCategory,
- pub documentation: Option<String>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct BibtexFieldDoc {
- pub name: String,
- pub documentation: String,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LanguageData {
- pub environment_commands: Vec<LatexEnvironmentCommand>,
- pub citation_commands: Vec<LatexCitationCommand>,
- pub label_commands: Vec<LatexLabelCommand>,
- pub section_commands: Vec<LatexSectionCommand>,
- pub include_commands: Vec<LatexIncludeCommand>,
- pub command_definition_commands: Vec<LatexCommandDefinitionCommand>,
- pub math_operator_commands: Vec<LatexMathOperatorCommand>,
- pub theorem_definition_commands: Vec<LatexTheoremDefinitionCommand>,
- pub colors: Vec<String>,
- pub color_commands: Vec<LatexColorCommand>,
- pub color_model_commands: Vec<LatexColorModelCommand>,
- pub glossary_entry_definition_commands: Vec<LatexGlossaryEntryDefinitionCommand>,
- pub glossary_entry_reference_commands: Vec<LatexGlossaryEntryReferenceCommand>,
- pub entry_types: Vec<BibtexEntryTypeDoc>,
- pub fields: Vec<BibtexFieldDoc>,
- pub pgf_libraries: Vec<String>,
- pub tikz_libraries: Vec<String>,
- pub math_environments: Vec<String>,
- pub enum_environments: Vec<String>,
-}
-
-impl LanguageData {
- pub fn find_entry_type(&self, name: &str) -> Option<&BibtexEntryTypeDoc> {
- let name = name.to_lowercase();
- self.entry_types
- .iter()
- .find(|ty| ty.name.to_lowercase() == name)
- }
-
- pub fn entry_type_documentation(&self, name: &str) -> Option<&str> {
- self.find_entry_type(name)
- .and_then(|ty| ty.documentation.as_ref().map(AsRef::as_ref))
- }
-
- pub fn field_documentation(&self, name: &str) -> Option<&str> {
- self.fields
- .iter()
- .find(|field| field.name.to_lowercase() == name.to_lowercase())
- .map(|field| field.documentation.as_ref())
- }
-}
-
-pub static LANGUAGE_DATA: Lazy<LanguageData> = Lazy::new(|| {
- const JSON: &str = include_str!("../../data/lang_data.json");
- serde_json::from_str(JSON).expect("Failed to deserialize language.json")
-});
diff --git a/support/texlab/src/syntax/latex.rs b/support/texlab/src/syntax/latex.rs
new file mode 100644
index 0000000000..7839c1795b
--- /dev/null
+++ b/support/texlab/src/syntax/latex.rs
@@ -0,0 +1,36 @@
+mod analysis;
+mod cst;
+mod kind;
+mod lexer;
+mod parser;
+
+pub use self::{
+ analysis::*,
+ cst::*,
+ kind::SyntaxKind::{self, *},
+ parser::{parse, Parse},
+};
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum Language {}
+
+impl cstree::Language for Language {
+ type Kind = SyntaxKind;
+
+ fn kind_from_raw(raw: cstree::SyntaxKind) -> Self::Kind {
+ assert!(raw.0 <= ROOT as u16);
+ unsafe { std::mem::transmute::<u16, SyntaxKind>(raw.0) }
+ }
+
+ fn kind_to_raw(kind: Self::Kind) -> cstree::SyntaxKind {
+ kind.into()
+ }
+}
+
+pub type SyntaxNode = cstree::ResolvedNode<Language>;
+
+pub type SyntaxToken = cstree::ResolvedToken<Language>;
+
+pub type SyntaxElement = cstree::ResolvedElement<Language>;
+
+pub type SyntaxElementRef<'a> = cstree::ResolvedElementRef<'a, Language>;
diff --git a/support/texlab/src/syntax/latex/analysis.rs b/support/texlab/src/syntax/latex/analysis.rs
index af8b756f31..063d8e95f3 100644
--- a/support/texlab/src/syntax/latex/analysis.rs
+++ b/support/texlab/src/syntax/latex/analysis.rs
@@ -1,913 +1,36 @@
-use crate::{
- protocol::{Options, Position, Range, RangeExt, Uri},
- syntax::{generic_ast::AstNodeIndex, lang_data::*, latex::ast::*, text::SyntaxNode},
- tex::Resolver,
+mod command;
+mod distro_file;
+mod environment;
+mod explicit_link;
+mod implicit_link;
+mod label_name;
+mod label_number;
+mod theorem;
+mod types;
+
+use crate::syntax::latex;
+
+pub use self::types::*;
+use self::{
+ command::analyze_command,
+ environment::analyze_begin,
+ explicit_link::{analyze_import, analyze_include},
+ implicit_link::analyze_implicit_links,
+ label_name::analyze_label_name,
+ label_number::analyze_label_number,
+ theorem::analyze_theorem_definition,
};
-use itertools::{iproduct, Itertools};
-use serde::{Deserialize, Serialize};
-use std::{borrow::Cow, ops::Deref, path::Path};
-#[derive(Debug, Clone)]
-pub struct SymbolTableParams<'a> {
- pub tree: Tree,
- pub uri: &'a Uri,
- pub resolver: &'a Resolver,
- pub options: &'a Options,
- pub current_dir: &'a Path,
-}
-
-#[derive(Debug, Clone)]
-pub struct SymbolTable {
- pub(crate) tree: Tree,
- pub commands: Vec<AstNodeIndex>,
- pub environments: Vec<Environment>,
- pub is_standalone: bool,
- pub includes: Vec<Include>,
- pub imports: Vec<Import>,
- pub components: Vec<String>,
- pub citations: Vec<Citation>,
- pub command_definitions: Vec<CommandDefinition>,
- pub glossary_entries: Vec<GlossaryEntry>,
- pub equations: Vec<Equation>,
- pub inlines: Vec<Inline>,
- pub math_operators: Vec<MathOperator>,
- pub theorem_definitions: Vec<TheoremDefinition>,
- pub sections: Vec<Section>,
- pub labels: Vec<Label>,
- pub label_numberings: Vec<LabelNumbering>,
- pub captions: Vec<Caption>,
- pub items: Vec<Item>,
-}
-
-impl SymbolTable {
- pub fn analyze(params: SymbolTableParams) -> Self {
- let SymbolTableParams {
- tree,
- uri,
- resolver,
- options,
- current_dir,
- } = params;
-
- let commands: Vec<_> = tree.commands().collect();
- let ctx = SymbolContext {
- tree: &tree,
- commands: &commands,
- uri,
- resolver,
- options,
- current_dir,
- };
-
- let mut environments = None;
- let mut includes = None;
- let mut imports = None;
- let mut citations = None;
- let mut command_definitions = None;
- let mut glossary_entries = None;
- let mut equations = None;
- let mut inlines = None;
- let mut math_operators = None;
- let mut theorem_definitions = None;
- let mut sections = None;
- let mut labels = None;
- let mut label_numberings = None;
- let mut captions = None;
- let mut items = None;
-
- rayon::scope(|s| {
- s.spawn(|_| environments = Some(Environment::parse(ctx)));
- s.spawn(|_| includes = Some(Include::parse(ctx)));
- s.spawn(|_| imports = Some(Import::parse(ctx)));
- s.spawn(|_| citations = Some(Citation::parse(ctx)));
- s.spawn(|_| command_definitions = Some(CommandDefinition::parse(ctx)));
- s.spawn(|_| glossary_entries = Some(GlossaryEntry::parse(ctx)));
- s.spawn(|_| equations = Some(Equation::parse(ctx)));
- s.spawn(|_| inlines = Some(Inline::parse(ctx)));
- s.spawn(|_| math_operators = Some(MathOperator::parse(ctx)));
- s.spawn(|_| theorem_definitions = Some(TheoremDefinition::parse(ctx)));
- s.spawn(|_| sections = Some(Section::parse(ctx)));
- s.spawn(|_| labels = Some(Label::parse(ctx)));
- s.spawn(|_| label_numberings = Some(LabelNumbering::parse(ctx)));
- s.spawn(|_| captions = Some(Caption::parse(ctx)));
- s.spawn(|_| items = Some(Item::parse(ctx)));
- });
-
- let is_standalone = environments
- .as_ref()
- .unwrap()
- .iter()
- .any(|env| env.is_root(&tree));
-
- let components = includes
- .as_ref()
- .unwrap()
- .iter()
- .flat_map(|include| include.components(&tree))
- .collect();
-
- Self {
- tree,
- commands,
- environments: environments.unwrap(),
- is_standalone,
- includes: includes.unwrap(),
- imports: imports.unwrap(),
- components,
- citations: citations.unwrap(),
- command_definitions: command_definitions.unwrap(),
- glossary_entries: glossary_entries.unwrap(),
- equations: equations.unwrap(),
- inlines: inlines.unwrap(),
- math_operators: math_operators.unwrap(),
- theorem_definitions: theorem_definitions.unwrap(),
- sections: sections.unwrap(),
- labels: labels.unwrap(),
- label_numberings: label_numberings.unwrap(),
- captions: captions.unwrap(),
- items: items.unwrap(),
- }
- }
-
- pub fn is_direct_child(&self, env: Environment, pos: Position) -> bool {
- env.range(&self.tree).contains(pos)
- && !self
- .environments
- .iter()
- .filter(|e| e.left.parent != env.left.parent)
- .filter(|e| env.range(&self.tree).contains(e.range(&self.tree).start))
- .any(|e| e.range(&self.tree).contains(pos))
- }
-
- pub fn is_enum_item(&self, enumeration: Environment, item: Item) -> bool {
- let item_range = self.tree[item.parent].range();
- enumeration.range(&self.tree).contains(item_range.start)
- && !self
- .environments
- .iter()
- .filter(|env| env.left.parent != enumeration.left.parent)
- .filter(|env| env.left.is_enum(&self.tree))
- .filter(|env| {
- enumeration
- .range(&self.tree)
- .contains(env.range(&self.tree).start)
- })
- .any(|env| env.range(&self.tree).contains(item_range.start))
- }
-
- pub fn find_label_by_range(&self, range: Range) -> Option<&Label> {
- self.labels
- .iter()
- .filter(|label| label.kind == LatexLabelKind::Definition)
- .filter(|label| label.names(&self).len() == 1)
- .find(|label| range.contains(self[label.parent].range().start))
- }
-
- pub fn find_label_by_environment(&self, env: Environment) -> Option<&Label> {
- self.labels
- .iter()
- .filter(|label| label.kind == LatexLabelKind::Definition)
- .filter(|label| label.names(&self.tree).len() == 1)
- .find(|label| self.is_direct_child(env, self.tree[label.parent].start()))
- }
-}
-
-impl Deref for SymbolTable {
- type Target = Tree;
-
- fn deref(&self) -> &Self::Target {
- &self.tree
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub struct SymbolContext<'a> {
- tree: &'a Tree,
- commands: &'a [AstNodeIndex],
- uri: &'a Uri,
- resolver: &'a Resolver,
- options: &'a Options,
- current_dir: &'a Path,
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct EnvironmentDelimiter {
- pub parent: AstNodeIndex,
-}
-
-impl EnvironmentDelimiter {
- pub fn name(self, tree: &Tree) -> Option<&Token> {
- tree.extract_word(self.parent, GroupKind::Group, 0)
- }
-
- pub fn is_math(self, tree: &Tree) -> bool {
- self.is_special(tree, LANGUAGE_DATA.math_environments.iter())
- }
-
- pub fn is_enum(self, tree: &Tree) -> bool {
- self.is_special(tree, LANGUAGE_DATA.enum_environments.iter())
- }
-
- fn is_special<'a, I: Iterator<Item = &'a String>>(self, tree: &Tree, mut values: I) -> bool {
- match self.name(tree) {
- Some(name) => values.any(|env| env == name.text()),
- None => false,
- }
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Environment {
- pub left: EnvironmentDelimiter,
- pub right: EnvironmentDelimiter,
-}
-
-impl Environment {
- pub fn is_root(self, tree: &Tree) -> bool {
- self.left
- .name(tree)
- .iter()
- .chain(self.right.name(tree).iter())
- .any(|name| name.text() == "document")
- }
-
- pub fn range(self, tree: &Tree) -> Range {
- let start = tree[self.left.parent].start();
- let end = tree[self.right.parent].end();
- Range::new(start, end)
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- let mut stack = Vec::new();
- let mut envs = Vec::new();
- for parent in ctx.commands {
- if let Some((delim, delim_cmd)) = Self::parse_delimiter(ctx.tree, *parent) {
- if delim_cmd.name.text() == "\\begin" {
- stack.push(delim);
- } else if let Some(left) = stack.pop() {
- envs.push(Self { left, right: delim });
- }
- }
- }
- envs
- }
-
- fn parse_delimiter(
- tree: &Tree,
- parent: AstNodeIndex,
- ) -> Option<(EnvironmentDelimiter, &Command)> {
- let cmd = tree.as_command(parent)?;
- if cmd.name.text() != "\\begin" && cmd.name.text() != "\\end" {
- return None;
- }
-
- let group = tree.extract_group(parent, GroupKind::Group, 0)?;
- if tree.extract_word(parent, GroupKind::Group, 0).is_some()
- || tree.children(group).next().is_none()
- || tree.as_group(group)?.right.is_none()
- {
- Some((EnvironmentDelimiter { parent }, cmd))
- } else {
- None
- }
- }
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Include {
- pub parent: AstNodeIndex,
- pub arg_index: usize,
- pub kind: LatexIncludeKind,
- pub all_targets: Vec<Vec<Uri>>,
- pub include_extension: bool,
-}
-
-impl Include {
- pub fn paths<'a>(&self, tree: &'a Tree) -> Vec<&'a Token> {
- tree.extract_comma_separated_words(self.parent, GroupKind::Group, self.arg_index)
- .unwrap()
- }
-
- pub fn components<'a>(&self, tree: &'a Tree) -> impl Iterator<Item = String> + 'a {
- let kind = self.kind;
- self.paths(tree)
- .into_iter()
- .filter_map(move |path| match kind {
- LatexIncludeKind::Package => Some(format!("{}.sty", path.text())),
- LatexIncludeKind::Class => Some(format!("{}.cls", path.text())),
- LatexIncludeKind::Latex
- | LatexIncludeKind::Bibliography
- | LatexIncludeKind::Image
- | LatexIncludeKind::Svg
- | LatexIncludeKind::Pdf
- | LatexIncludeKind::Everything => None,
- })
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- iproduct!(ctx.commands, LANGUAGE_DATA.include_commands.iter())
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexIncludeCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- let mut all_targets = Vec::new();
- let paths = ctx
- .tree
- .extract_comma_separated_words(parent, GroupKind::Group, desc.index)?;
- for path in paths {
- let mut targets = Vec::new();
- let base_url = base_url(ctx)?;
- targets.push(base_url.join(path.text()).ok()?.into());
-
- if let Some(extensions) = desc.kind.extensions() {
- for extension in extensions {
- let path = format!("{}.{}", path.text(), extension);
- targets.push(base_url.join(&path).ok()?.into());
- }
- }
-
- if let Some(target) = Self::resolve_distro_file(ctx, desc, path.text()) {
- targets.push(target);
- }
- all_targets.push(targets);
- }
-
- let include = Self {
- parent,
- arg_index: desc.index,
- kind: desc.kind,
- all_targets,
- include_extension: desc.include_extension,
- };
- Some(include)
- }
-
- fn resolve_distro_file(
- ctx: SymbolContext,
- desc: &LatexIncludeCommand,
- name: &str,
- ) -> Option<Uri> {
- let mut path = ctx.resolver.files_by_name.get(name);
- if let Some(extensions) = desc.kind.extensions() {
- for extension in extensions {
- path = path.or_else(|| {
- let full_name = format!("{}.{}", name, extension);
- ctx.resolver.files_by_name.get(&full_name)
- });
- }
- }
- path.and_then(|p| Uri::from_file_path(p).ok())
- }
-}
-
-fn base_url(ctx: SymbolContext) -> Option<Uri> {
- if let Some(root_directory) = ctx
- .options
- .latex
- .as_ref()
- .and_then(|opts| opts.root_directory.as_ref())
- {
- let file_name = ctx.uri.path_segments()?.last()?;
- let path = ctx.current_dir.join(root_directory).join(file_name);
- Uri::from_file_path(path).ok()
- } else {
- Some(ctx.uri.clone())
- }
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Import {
- pub parent: AstNodeIndex,
- pub targets: Vec<Uri>,
-}
-
-impl Import {
- pub fn dir<'a>(&self, tree: &'a Tree) -> &'a Token {
- tree.extract_word(self.parent, GroupKind::Group, 0).unwrap()
- }
-
- pub fn file<'a>(&self, tree: &'a Tree) -> &'a Token {
- tree.extract_word(self.parent, GroupKind::Group, 1).unwrap()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- ctx.commands
- .iter()
- .filter_map(|parent| Self::parse_single(ctx, *parent))
- .collect()
- }
-
- fn parse_single(ctx: SymbolContext, parent: AstNodeIndex) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != "\\import" && cmd.name.text() != "\\subimport" {
- return None;
- }
-
- let dir = ctx.tree.extract_word(parent, GroupKind::Group, 0)?;
- let file = ctx.tree.extract_word(parent, GroupKind::Group, 1)?;
-
- let mut targets = Vec::new();
- let base_url = base_url(ctx)?.join(dir.text()).ok()?;
- targets.push(base_url.join(file.text()).ok()?.into());
- targets.push(base_url.join(&format!("{}.tex", file.text())).ok()?.into());
- Some(Self { parent, targets })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Citation {
- parent: AstNodeIndex,
- arg_index: usize,
-}
-
-impl Citation {
- pub fn keys(self, tree: &Tree) -> Vec<&Token> {
- tree.extract_comma_separated_words(self.parent, GroupKind::Group, self.arg_index)
- .unwrap()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- iproduct!(ctx.commands, LANGUAGE_DATA.citation_commands.iter())
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexCitationCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- ctx.tree
- .extract_comma_separated_words(parent, GroupKind::Group, desc.index)?;
-
- Some(Self {
- parent,
- arg_index: desc.index,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct CommandDefinition {
- pub parent: AstNodeIndex,
- pub definition: AstNodeIndex,
- pub definition_index: usize,
- pub implementation: AstNodeIndex,
- pub implementation_index: usize,
- pub arg_count_index: usize,
-}
-
-impl CommandDefinition {
- pub fn definition_name(self, tree: &Tree) -> &str {
- tree.as_command(self.definition).unwrap().name.text()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- let def = LANGUAGE_DATA.command_definition_commands.iter();
- iproduct!(ctx.commands, def)
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexCommandDefinitionCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- let group_kind = GroupKind::Group;
- let implementation =
- ctx.tree
- .extract_group(parent, group_kind, desc.implementation_index)?;
-
- let def_group = ctx
- .tree
- .extract_group(parent, group_kind, desc.definition_index)?;
-
- let mut def_children = ctx.tree.children(def_group);
- let definition = def_children.next()?;
- ctx.tree.as_command(definition)?;
- Some(Self {
- parent,
- definition,
- definition_index: desc.definition_index,
- implementation,
- implementation_index: desc.implementation_index,
- arg_count_index: desc.arg_count_index,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct GlossaryEntry {
- pub parent: AstNodeIndex,
- pub label_index: usize,
- pub kind: LatexGlossaryEntryKind,
-}
-
-impl GlossaryEntry {
- pub fn label(self, tree: &Tree) -> &Token {
- tree.extract_word(self.parent, GroupKind::Group, self.label_index)
- .unwrap()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- let entry = LANGUAGE_DATA.glossary_entry_definition_commands.iter();
- iproduct!(ctx.commands, entry)
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexGlossaryEntryDefinitionCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- ctx.tree
- .extract_word(parent, GroupKind::Group, desc.label_index)?;
-
- Some(Self {
- parent,
- label_index: desc.label_index,
- kind: desc.kind,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Equation {
- pub left: AstNodeIndex,
- pub right: AstNodeIndex,
-}
-
-impl Equation {
- pub fn range(self, tree: &Tree) -> Range {
- let start = tree[self.left].start();
- let end = tree[self.right].end();
- Range::new(start, end)
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- let mut equations = Vec::new();
- let mut left = None;
- for node in ctx.commands {
- let cmd = ctx.tree.as_command(*node).unwrap();
- let name = cmd.name.text();
- if name == "\\[" || name == "\\(" {
- left = Some(node);
- } else if name == "\\]" || name == "\\)" {
- if let Some(begin) = left {
- equations.push(Self {
- left: *begin,
- right: *node,
- });
- left = None;
- }
- }
- }
- equations
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Inline {
- pub left: AstNodeIndex,
- pub right: AstNodeIndex,
-}
-
-impl Inline {
- pub fn range(self, tree: &Tree) -> Range {
- let start = tree[self.left].start();
- let end = tree[self.right].end();
- Range::new(start, end)
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- let mut inlines = Vec::new();
- let mut left = None;
- for node in ctx
- .tree
- .nodes()
- .into_iter()
- .filter(|node| ctx.tree.as_math(*node).is_some())
- .sorted_by_key(|node| ctx.tree[*node].start())
- {
- if let Some(l) = left {
- inlines.push(Inline {
- left: l,
- right: node,
- });
- left = None;
- } else {
- left = Some(node);
- }
- }
- inlines
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct MathOperator {
- pub parent: AstNodeIndex,
- pub definition: AstNodeIndex,
- pub definition_index: usize,
- pub implementation: AstNodeIndex,
- pub implementation_index: usize,
-}
-
-impl MathOperator {
- pub fn definition_name(self, tree: &Tree) -> &str {
- tree.as_command(self.definition).unwrap().name.text()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- iproduct!(ctx.commands, LANGUAGE_DATA.math_operator_commands.iter())
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexMathOperatorCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- let group_kind = GroupKind::Group;
- let def_group = ctx
- .tree
- .extract_group(parent, group_kind, desc.definition_index)?;
- let implementation =
- ctx.tree
- .extract_group(parent, group_kind, desc.implementation_index)?;
-
- let mut def_children = ctx.tree.children(def_group);
- let definition = def_children.next()?;
- Some(Self {
- parent,
- definition,
- definition_index: desc.definition_index,
- implementation,
- implementation_index: desc.implementation_index,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct TheoremDefinition {
- pub parent: AstNodeIndex,
- pub arg_index: usize,
-}
-
-impl TheoremDefinition {
- pub fn name(self, tree: &Tree) -> &Token {
- tree.extract_word(self.parent, GroupKind::Group, self.arg_index)
- .unwrap()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- let thm = LANGUAGE_DATA.theorem_definition_commands.iter();
- iproduct!(ctx.commands, thm)
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexTheoremDefinitionCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- let group_kind = GroupKind::Group;
- ctx.tree.extract_word(parent, group_kind, desc.index)?;
-
- Some(Self {
- parent,
- arg_index: desc.index,
- })
- }
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Section {
- pub parent: AstNodeIndex,
- pub arg_index: usize,
- pub level: i32,
- pub prefix: Cow<'static, str>,
-}
-
-impl Section {
- pub fn print(&self, tree: &Tree) -> Option<String> {
- tree.print_group_content(self.parent, GroupKind::Group, self.arg_index)
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- iproduct!(ctx.commands, LANGUAGE_DATA.section_commands.iter())
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &'static LatexSectionCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- let group_kind = GroupKind::Group;
- ctx.tree.extract_group(parent, group_kind, desc.index)?;
-
- Some(Self {
- parent,
- arg_index: desc.index,
- level: desc.level,
- prefix: Cow::from(&desc.prefix),
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Label {
- pub parent: AstNodeIndex,
- pub arg_index: usize,
- pub kind: LatexLabelKind,
-}
-
-impl Label {
- pub fn names(self, tree: &Tree) -> Vec<&Token> {
- tree.extract_comma_separated_words(self.parent, GroupKind::Group, self.arg_index)
- .unwrap()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- iproduct!(ctx.commands, LANGUAGE_DATA.label_commands.iter())
- .filter_map(|(parent, desc)| Self::parse_single(ctx, *parent, desc))
- .collect()
- }
-
- fn parse_single(
- ctx: SymbolContext,
- parent: AstNodeIndex,
- desc: &LatexLabelCommand,
- ) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != desc.name {
- return None;
- }
-
- ctx.tree
- .extract_comma_separated_words(parent, GroupKind::Group, desc.index)?;
-
- Some(Self {
- parent,
- arg_index: desc.index,
- kind: desc.kind,
- })
- }
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct LabelNumbering {
- pub parent: AstNodeIndex,
- pub number: String,
-}
-
-impl LabelNumbering {
- pub fn name<'a>(&self, tree: &'a Tree) -> &'a Token {
- tree.extract_word(self.parent, GroupKind::Group, 0).unwrap()
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- ctx.commands
- .iter()
- .filter_map(|parent| Self::parse_single(ctx, *parent))
- .collect()
- }
-
- fn parse_single(ctx: SymbolContext, parent: AstNodeIndex) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != "\\newlabel" {
- return None;
- }
-
- ctx.tree.extract_word(parent, GroupKind::Group, 0)?;
-
- let arg = ctx.tree.extract_group(parent, GroupKind::Group, 1)?;
- let mut analyzer = FirstText::default();
- analyzer.visit(ctx.tree, arg);
- Some(Self {
- parent,
- number: analyzer.text?,
- })
- }
-}
-
-#[derive(Debug, Default)]
-struct FirstText {
- text: Option<String>,
-}
-
-impl Visitor for FirstText {
- fn visit(&mut self, tree: &Tree, node: AstNodeIndex) {
- if let Some(text) = tree.as_text(node) {
- self.text = Some(text.words.iter().map(Token::text).join(" "));
- }
-
- if self.text.is_none() {
- tree.walk(self, node);
- }
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Caption {
- pub parent: AstNodeIndex,
- pub arg_index: usize,
-}
-
-impl Caption {
- pub fn print(self, tree: &Tree) -> Option<String> {
- tree.print_group_content(self.parent, GroupKind::Group, self.arg_index)
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- ctx.commands
- .iter()
- .flat_map(|parent| Self::parse_single(ctx, *parent))
- .collect()
- }
-
- fn parse_single(ctx: SymbolContext, parent: AstNodeIndex) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != "\\caption" {
- return None;
- }
-
- ctx.tree.extract_group(parent, GroupKind::Group, 0)?;
- Some(Self {
- parent,
- arg_index: 0,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
-pub struct Item {
- pub parent: AstNodeIndex,
-}
-
-impl Item {
- pub fn name(self, tree: &Tree) -> Option<String> {
- tree.print_group_content(self.parent, GroupKind::Options, 0)
- }
-
- fn parse(ctx: SymbolContext) -> Vec<Self> {
- ctx.commands
- .iter()
- .filter_map(|parent| Self::parse_single(ctx, *parent))
- .collect()
- }
-
- fn parse_single(ctx: SymbolContext, parent: AstNodeIndex) -> Option<Self> {
- let cmd = ctx.tree.as_command(parent)?;
- if cmd.name.text() != "\\item" {
- return None;
- }
-
- Some(Self { parent })
- }
+pub fn analyze(context: &mut LatexAnalyzerContext, root: &latex::SyntaxNode) {
+ analyze_implicit_links(context);
+ for node in root.descendants() {
+ analyze_command(context, node)
+ .or_else(|| analyze_begin(context, node))
+ .or_else(|| analyze_include(context, node))
+ .or_else(|| analyze_import(context, node))
+ .or_else(|| analyze_label_name(context, node))
+ .or_else(|| analyze_label_number(context, node))
+ .or_else(|| analyze_theorem_definition(context, node));
+ }
+ context.extras.has_document_environment = context.extras.environment_names.contains("document");
}
diff --git a/support/texlab/src/syntax/latex/analysis/command.rs b/support/texlab/src/syntax/latex/analysis/command.rs
new file mode 100644
index 0000000000..9dea4d84ee
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/command.rs
@@ -0,0 +1,12 @@
+use crate::syntax::{latex, CstNode};
+
+use super::LatexAnalyzerContext;
+
+pub fn analyze_command(context: &mut LatexAnalyzerContext, node: &latex::SyntaxNode) -> Option<()> {
+ let command = latex::GenericCommand::cast(node)?;
+ context
+ .extras
+ .command_names
+ .insert(command.name()?.text().into());
+ Some(())
+}
diff --git a/support/texlab/src/syntax/latex/analysis/distro_file.rs b/support/texlab/src/syntax/latex/analysis/distro_file.rs
new file mode 100644
index 0000000000..4c747ce760
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/distro_file.rs
@@ -0,0 +1,71 @@
+use crate::{distro::Resolver, Uri};
+
+pub fn resolve_distro_file(resolver: &Resolver, stem: &str, extensions: &[&str]) -> Option<Uri> {
+ let mut document = resolver.files_by_name.get(stem);
+ for extension in extensions {
+ document = document.or_else(|| {
+ let full_name = format!("{}.{}", stem, extension);
+ resolver.files_by_name.get(full_name.as_str())
+ });
+ }
+ document.and_then(|path| Uri::from_file_path(path).ok())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ #[cfg(windows)]
+ fn test() {
+ let mut resolver = Resolver::default();
+ resolver
+ .files_by_name
+ .insert("foo.tex".into(), "C:/distro/foo.tex".into());
+ resolver
+ .files_by_name
+ .insert("foo.sty".into(), "C:/distro/foo.sty".into());
+ resolver
+ .files_by_name
+ .insert("bar.tex".into(), "C:/distro/bar.tex".into());
+
+ assert_eq!(
+ resolve_distro_file(&resolver, "foo", &["tex"]),
+ Some(Uri::from_file_path("C:/distro/foo.tex").unwrap())
+ );
+
+ assert_eq!(
+ resolve_distro_file(&resolver, "foo", &["sty"]),
+ Some(Uri::from_file_path("C:/distro/foo.sty").unwrap())
+ );
+
+ assert_eq!(resolve_distro_file(&resolver, "foo", &["cls"]), None);
+ }
+
+ #[test]
+ #[cfg(unix)]
+ fn test() {
+ let mut resolver = Resolver::default();
+ resolver
+ .files_by_name
+ .insert("foo.tex".into(), "/distro/foo.tex".into());
+ resolver
+ .files_by_name
+ .insert("foo.sty".into(), "/distro/foo.sty".into());
+ resolver
+ .files_by_name
+ .insert("bar.tex".into(), "/distro/bar.tex".into());
+
+ assert_eq!(
+ resolve_distro_file(&resolver, "foo", &["tex"]),
+ Some(Uri::from_file_path("/distro/foo.tex").unwrap())
+ );
+
+ assert_eq!(
+ resolve_distro_file(&resolver, "foo", &["sty"]),
+ Some(Uri::from_file_path("/distro/foo.sty").unwrap())
+ );
+
+ assert_eq!(resolve_distro_file(&resolver, "foo", &["cls"]), None);
+ }
+}
diff --git a/support/texlab/src/syntax/latex/analysis/environment.rs b/support/texlab/src/syntax/latex/analysis/environment.rs
new file mode 100644
index 0000000000..3b83b40b2f
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/environment.rs
@@ -0,0 +1,11 @@
+use crate::syntax::{latex, CstNode};
+
+use super::LatexAnalyzerContext;
+
+pub fn analyze_begin(context: &mut LatexAnalyzerContext, node: &latex::SyntaxNode) -> Option<()> {
+ let begin = latex::Begin::cast(node)?;
+ let name = begin.name()?.word()?.text();
+ let extras = &mut context.extras;
+ extras.environment_names.insert(name.into());
+ Some(())
+}
diff --git a/support/texlab/src/syntax/latex/analysis/explicit_link.rs b/support/texlab/src/syntax/latex/analysis/explicit_link.rs
new file mode 100644
index 0000000000..363a576aaa
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/explicit_link.rs
@@ -0,0 +1,72 @@
+use std::sync::Arc;
+
+use crate::syntax::{latex, CstNode};
+
+use super::{
+ distro_file::resolve_distro_file, ExplicitLink, ExplicitLinkKind, LatexAnalyzerContext,
+};
+
+pub fn analyze_include(context: &mut LatexAnalyzerContext, node: &latex::SyntaxNode) -> Option<()> {
+ let include = latex::Include::cast(node)?;
+ let kind = match include.syntax().kind() {
+ latex::LATEX_INCLUDE => ExplicitLinkKind::Latex,
+ latex::BIBLATEX_INCLUDE | latex::BIBTEX_INCLUDE => ExplicitLinkKind::Bibtex,
+ latex::PACKAGE_INCLUDE => ExplicitLinkKind::Package,
+ latex::CLASS_INCLUDE => ExplicitLinkKind::Class,
+ _ => return None,
+ };
+
+ let extensions = match kind {
+ ExplicitLinkKind::Latex => &["tex"],
+ ExplicitLinkKind::Bibtex => &["bib"],
+ ExplicitLinkKind::Package => &["sty"],
+ ExplicitLinkKind::Class => &["cls"],
+ };
+
+ for path in include.path_list()?.words() {
+ let stem = path.text();
+ let mut targets = vec![Arc::new(context.base_uri.join(stem).ok()?.into())];
+ for extension in extensions {
+ let path = format!("{}.{}", stem, extension);
+ targets.push(Arc::new(context.base_uri.join(&path).ok()?.into()));
+ }
+
+ resolve_distro_file(&context.inner.resolver.lock().unwrap(), stem, extensions)
+ .into_iter()
+ .for_each(|target| targets.push(Arc::new(target)));
+
+ context.extras.explicit_links.push(ExplicitLink {
+ kind,
+ stem: stem.into(),
+ stem_range: path.text_range(),
+ targets,
+ });
+ }
+
+ Some(())
+}
+
+pub fn analyze_import(context: &mut LatexAnalyzerContext, node: &latex::SyntaxNode) -> Option<()> {
+ let import = latex::Import::cast(node)?;
+
+ let mut targets = Vec::new();
+ let directory = context
+ .base_uri
+ .join(import.directory()?.word()?.text())
+ .ok()?;
+
+ let file = import.file()?.word()?;
+ let stem = file.text();
+ targets.push(Arc::new(directory.join(stem).ok()?.into()));
+ targets.push(Arc::new(
+ directory.join(&format!("{}.tex", stem)).ok()?.into(),
+ ));
+
+ context.extras.explicit_links.push(ExplicitLink {
+ stem: stem.into(),
+ stem_range: file.text_range(),
+ targets,
+ kind: ExplicitLinkKind::Latex,
+ });
+ Some(())
+}
diff --git a/support/texlab/src/syntax/latex/analysis/implicit_link.rs b/support/texlab/src/syntax/latex/analysis/implicit_link.rs
new file mode 100644
index 0000000000..74055b3e31
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/implicit_link.rs
@@ -0,0 +1,41 @@
+use std::sync::Arc;
+
+use crate::Uri;
+
+use super::LatexAnalyzerContext;
+
+pub fn analyze_implicit_links(context: &mut LatexAnalyzerContext) {
+ context.extras.implicit_links.aux = find_by_extension(context, "aux").unwrap_or_default();
+ context.extras.implicit_links.log = find_by_extension(context, "log").unwrap_or_default();
+ context.extras.implicit_links.pdf = find_by_extension(context, "pdf").unwrap_or_default();
+}
+
+fn find_by_extension(context: &LatexAnalyzerContext, extension: &str) -> Option<Vec<Arc<Uri>>> {
+ let mut targets: Vec<Arc<Uri>> = Vec::new();
+ targets.push(Arc::new(context.document_uri.with_extension(extension)?));
+ if context.document_uri.scheme() == "file" {
+ let file_path = context.document_uri.to_file_path().ok()?;
+ let file_stem = file_path.file_stem()?;
+ let aux_name = format!("{}.{}", file_stem.to_str()?, extension);
+
+ let options = context.inner.options.read().unwrap();
+ if let Some(root_dir) = options.root_directory.as_ref() {
+ let path = context
+ .inner
+ .current_directory
+ .join(root_dir)
+ .join(&aux_name);
+ targets.push(Arc::new(Uri::from_file_path(path).ok()?));
+ }
+
+ if let Some(build_dir) = options.aux_directory.as_ref() {
+ let path = context
+ .inner
+ .current_directory
+ .join(build_dir)
+ .join(&aux_name);
+ targets.push(Arc::new(Uri::from_file_path(path).ok()?));
+ }
+ }
+ Some(targets)
+}
diff --git a/support/texlab/src/syntax/latex/analysis/label_name.rs b/support/texlab/src/syntax/latex/analysis/label_name.rs
new file mode 100644
index 0000000000..d0410b953c
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/label_name.rs
@@ -0,0 +1,66 @@
+use latex::LabelReferenceRange;
+
+use crate::syntax::{latex, CstNode};
+
+use super::{LabelName, LatexAnalyzerContext};
+
+pub fn analyze_label_name(
+ context: &mut LatexAnalyzerContext,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ analyze_label_definition_name(context, node)
+ .or_else(|| analyze_label_reference_name(context, node))
+ .or_else(|| analyze_label_reference_range_name(context, node))
+}
+
+fn analyze_label_definition_name(
+ context: &mut LatexAnalyzerContext,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ let label = latex::LabelDefinition::cast(node)?;
+ let name = label.name()?.word()?;
+ context.extras.label_names.push(LabelName {
+ text: name.text().into(),
+ range: name.text_range(),
+ is_definition: true,
+ });
+ Some(())
+}
+
+fn analyze_label_reference_name(
+ context: &mut LatexAnalyzerContext,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ let label = latex::LabelReference::cast(node)?;
+ for name in label.name_list()?.words() {
+ context.extras.label_names.push(LabelName {
+ text: name.text().into(),
+ range: name.text_range(),
+ is_definition: false,
+ });
+ }
+ Some(())
+}
+
+fn analyze_label_reference_range_name(
+ context: &mut LatexAnalyzerContext,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ let label = LabelReferenceRange::cast(node)?;
+ if let Some(name1) = label.from().and_then(|name| name.word()) {
+ context.extras.label_names.push(LabelName {
+ text: name1.text().into(),
+ range: name1.text_range(),
+ is_definition: false,
+ });
+ }
+
+ if let Some(name2) = label.to().and_then(|name| name.word()) {
+ context.extras.label_names.push(LabelName {
+ text: name2.text().into(),
+ range: name2.text_range(),
+ is_definition: false,
+ });
+ }
+ Some(())
+}
diff --git a/support/texlab/src/syntax/latex/analysis/label_number.rs b/support/texlab/src/syntax/latex/analysis/label_number.rs
new file mode 100644
index 0000000000..de8d0dc1e1
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/label_number.rs
@@ -0,0 +1,22 @@
+use crate::syntax::{latex, CstNode};
+
+use super::LatexAnalyzerContext;
+
+pub fn analyze_label_number(
+ context: &mut LatexAnalyzerContext,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ let number = latex::LabelNumber::cast(node)?;
+ let name = number.name()?.word()?.text().into();
+ let text = number
+ .text()?
+ .syntax()
+ .descendants_with_tokens()
+ .filter_map(|element| element.into_node())
+ .find(|node| node.kind() == latex::TEXT || node.kind() == latex::MIXED_GROUP)?
+ .text()
+ .to_string();
+
+ context.extras.label_numbers_by_name.insert(name, text);
+ Some(())
+}
diff --git a/support/texlab/src/syntax/latex/analysis/theorem.rs b/support/texlab/src/syntax/latex/analysis/theorem.rs
new file mode 100644
index 0000000000..0c365f0ef5
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/theorem.rs
@@ -0,0 +1,23 @@
+use crate::syntax::{
+ latex::{self, HasCurly},
+ CstNode,
+};
+
+use super::{LatexAnalyzerContext, TheoremEnvironment};
+
+pub fn analyze_theorem_definition(
+ context: &mut LatexAnalyzerContext,
+ node: &latex::SyntaxNode,
+) -> Option<()> {
+ let theorem = latex::TheoremDefinition::cast(node)?;
+ let name = theorem.name()?.word()?.text().into();
+ let description = theorem.description()?;
+ let description = description.content_text()?;
+
+ context
+ .extras
+ .theorem_environments
+ .push(TheoremEnvironment { name, description });
+
+ Some(())
+}
diff --git a/support/texlab/src/syntax/latex/analysis/types.rs b/support/texlab/src/syntax/latex/analysis/types.rs
new file mode 100644
index 0000000000..f089721397
--- /dev/null
+++ b/support/texlab/src/syntax/latex/analysis/types.rs
@@ -0,0 +1,73 @@
+use std::sync::Arc;
+
+use cstree::TextRange;
+use rustc_hash::{FxHashMap, FxHashSet};
+use smol_str::SmolStr;
+
+use crate::{ServerContext, Uri};
+
+#[derive(Debug)]
+pub struct LatexAnalyzerContext {
+ pub inner: Arc<ServerContext>,
+ pub document_uri: Arc<Uri>,
+ pub base_uri: Arc<Uri>,
+ pub extras: Extras,
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct Extras {
+ pub implicit_links: ImplicitLinks,
+ pub explicit_links: Vec<ExplicitLink>,
+ pub has_document_environment: bool,
+ pub command_names: FxHashSet<SmolStr>,
+ pub environment_names: FxHashSet<SmolStr>,
+ pub label_names: Vec<LabelName>,
+ pub label_numbers_by_name: FxHashMap<SmolStr, String>,
+ pub theorem_environments: Vec<TheoremEnvironment>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
+pub struct ImplicitLinks {
+ pub aux: Vec<Arc<Uri>>,
+ pub log: Vec<Arc<Uri>>,
+ pub pdf: Vec<Arc<Uri>>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
+pub enum ExplicitLinkKind {
+ Package,
+ Class,
+ Latex,
+ Bibtex,
+}
+
+#[derive(Debug, Clone)]
+pub struct ExplicitLink {
+ pub stem: SmolStr,
+ pub stem_range: TextRange,
+ pub targets: Vec<Arc<Uri>>,
+ pub kind: ExplicitLinkKind,
+}
+
+impl ExplicitLink {
+ pub fn as_component_name(&self) -> Option<String> {
+ match self.kind {
+ ExplicitLinkKind::Package => Some(format!("{}.sty", self.stem)),
+ ExplicitLinkKind::Class => Some(format!("{}.cls", self.stem)),
+ ExplicitLinkKind::Latex | ExplicitLinkKind::Bibtex => None,
+ }
+ }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
+pub struct TheoremEnvironment {
+ pub name: SmolStr,
+ pub description: String,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
+pub struct LabelName {
+ pub text: SmolStr,
+ pub range: TextRange,
+ pub is_definition: bool,
+}
diff --git a/support/texlab/src/syntax/latex/ast.rs b/support/texlab/src/syntax/latex/ast.rs
deleted file mode 100644
index ab7c6863e1..0000000000
--- a/support/texlab/src/syntax/latex/ast.rs
+++ /dev/null
@@ -1,414 +0,0 @@
-use crate::{
- protocol::{Position, Range, RangeExt},
- syntax::{
- generic_ast::{Ast, AstNodeIndex},
- text::{Span, SyntaxNode},
- },
-};
-use serde::{Deserialize, Serialize};
-use std::ops::Deref;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-pub enum TokenKind {
- Word,
- Command,
- Math,
- Comma,
- BeginGroup,
- EndGroup,
- BeginOptions,
- EndOptions,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Token {
- pub span: Span,
- pub kind: TokenKind,
-}
-
-impl Token {
- pub fn new(span: Span, kind: TokenKind) -> Self {
- Self { span, kind }
- }
-
- pub fn text(&self) -> &str {
- &self.span.text
- }
-}
-
-impl SyntaxNode for Token {
- fn range(&self) -> Range {
- self.span.range()
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-pub struct Root {
- pub range: Range,
-}
-
-impl SyntaxNode for Root {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-pub enum GroupKind {
- Group,
- Options,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Group {
- pub range: Range,
- pub left: Token,
- pub right: Option<Token>,
- pub kind: GroupKind,
-}
-
-impl SyntaxNode for Group {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Command {
- pub range: Range,
- pub name: Token,
-}
-
-impl Command {
- pub fn short_name_range(&self) -> Range {
- Range::new_simple(
- self.name.start().line,
- self.name.start().character + 1,
- self.name.end().line,
- self.name.end().character,
- )
- }
-}
-
-impl SyntaxNode for Command {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Text {
- pub range: Range,
- pub words: Vec<Token>,
-}
-
-impl SyntaxNode for Text {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Comma {
- pub range: Range,
- pub token: Token,
-}
-
-impl SyntaxNode for Comma {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct Math {
- pub range: Range,
- pub token: Token,
-}
-
-impl SyntaxNode for Math {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub enum Node {
- Root(Root),
- Group(Group),
- Command(Command),
- Text(Text),
- Comma(Comma),
- Math(Math),
-}
-
-impl SyntaxNode for Node {
- fn range(&self) -> Range {
- match self {
- Self::Root(root) => root.range(),
- Self::Group(group) => group.range(),
- Self::Command(cmd) => cmd.range(),
- Self::Text(text) => text.range(),
- Self::Comma(comma) => comma.range(),
- Self::Math(math) => math.range(),
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct Tree {
- pub inner: Ast<Node>,
- pub root: AstNodeIndex,
-}
-
-impl Deref for Tree {
- type Target = Ast<Node>;
-
- fn deref(&self) -> &Self::Target {
- &self.inner
- }
-}
-
-impl Tree {
- pub fn walk<V: Visitor>(&self, visitor: &mut V, parent: AstNodeIndex) {
- for child in self.children(parent) {
- visitor.visit(self, child);
- }
- }
-
- pub fn find(&self, pos: Position) -> Vec<AstNodeIndex> {
- let mut finder = Finder::new(pos);
- finder.visit(self, self.root);
- finder.results
- }
-
- pub fn find_command_by_short_name_range(&self, pos: Position) -> Option<AstNodeIndex> {
- self.find(pos).into_iter().find(|node| {
- self.as_command(*node)
- .filter(|cmd| {
- cmd.name.range().contains(pos) && cmd.name.start().character != pos.character
- })
- .is_some()
- })
- }
-
- pub fn print(&self, node: AstNodeIndex) -> String {
- let start_position = self[node].start();
- let mut printer = Printer::new(start_position);
- printer.visit(self, node);
- printer.output
- }
-
- pub fn commands<'a>(&'a self) -> impl Iterator<Item = AstNodeIndex> + 'a {
- self.inner
- .nodes()
- .into_iter()
- .filter(move |node| self.as_command(*node).is_some())
- }
-
- pub fn as_group(&self, node: AstNodeIndex) -> Option<&Group> {
- if let Node::Group(group) = &self[node] {
- Some(group)
- } else {
- None
- }
- }
-
- pub fn as_command(&self, node: AstNodeIndex) -> Option<&Command> {
- if let Node::Command(cmd) = &self[node] {
- Some(cmd)
- } else {
- None
- }
- }
-
- pub fn as_text(&self, node: AstNodeIndex) -> Option<&Text> {
- if let Node::Text(text) = &self[node] {
- Some(text)
- } else {
- None
- }
- }
-
- pub fn as_math(&self, node: AstNodeIndex) -> Option<&Math> {
- if let Node::Math(math) = &self[node] {
- Some(math)
- } else {
- None
- }
- }
-
- pub fn extract_group(
- &self,
- parent: AstNodeIndex,
- group_kind: GroupKind,
- index: usize,
- ) -> Option<AstNodeIndex> {
- self.children(parent)
- .filter(|child| {
- self.as_group(*child)
- .filter(|group| group.kind == group_kind)
- .is_some()
- })
- .nth(index)
- }
-
- pub fn extract_text(
- &self,
- parent: AstNodeIndex,
- group_kind: GroupKind,
- index: usize,
- ) -> Option<&Text> {
- let group = self.extract_group(parent, group_kind, index)?;
- let mut contents = self.children(group);
- let text = self.as_text(contents.next()?);
- if contents.next().is_none() {
- text
- } else {
- None
- }
- }
-
- pub fn extract_word(
- &self,
- parent: AstNodeIndex,
- group_kind: GroupKind,
- index: usize,
- ) -> Option<&Token> {
- let text = self.extract_text(parent, group_kind, index)?;
- if text.words.len() == 1 {
- Some(&text.words[0])
- } else {
- None
- }
- }
-
- pub fn extract_comma_separated_words(
- &self,
- parent: AstNodeIndex,
- group_kind: GroupKind,
- index: usize,
- ) -> Option<Vec<&Token>> {
- let group = self.extract_group(parent, group_kind, index)?;
- let mut words = Vec::new();
- for child in self.children(group) {
- match &self[child] {
- Node::Root(_) | Node::Group(_) | Node::Command(_) | Node::Math(_) => return None,
- Node::Text(text) => {
- for word in &text.words {
- words.push(word);
- }
- }
- Node::Comma(_) => (),
- }
- }
- Some(words)
- }
-
- pub fn print_group_content(
- &self,
- parent: AstNodeIndex,
- group_kind: GroupKind,
- index: usize,
- ) -> Option<String> {
- let arg = self.extract_group(parent, group_kind, index)?;
- let text = self.print(arg);
- self.as_group(arg)?.right.as_ref()?;
- Some(text[1..text.len() - 1].trim().into())
- }
-}
-
-pub trait Visitor {
- fn visit(&mut self, tree: &Tree, node: AstNodeIndex);
-}
-
-#[derive(Debug)]
-struct Finder {
- position: Position,
- results: Vec<AstNodeIndex>,
-}
-
-impl Finder {
- fn new(position: Position) -> Self {
- Self {
- position,
- results: Vec::new(),
- }
- }
-}
-
-impl Visitor for Finder {
- fn visit(&mut self, tree: &Tree, node: AstNodeIndex) {
- if tree[node].range().contains(self.position) {
- self.results.push(node);
- tree.walk(self, node);
- }
- }
-}
-
-#[derive(Debug)]
-struct Printer {
- output: String,
- position: Position,
-}
-
-impl Printer {
- fn new(start_position: Position) -> Self {
- Self {
- output: String::new(),
- position: start_position,
- }
- }
-
- fn synchronize(&mut self, position: Position) {
- while self.position.line < position.line {
- self.output.push('\n');
- self.position.line += 1;
- self.position.character = 0;
- }
-
- while self.position.character < position.character {
- self.output.push(' ');
- self.position.character += 1;
- }
-
- assert_eq!(self.position, position);
- }
-
- fn print_token(&mut self, token: &Token) {
- self.synchronize(token.start());
- self.output.push_str(token.text());
- self.position.character += token.end().character - token.start().character;
- self.synchronize(token.end());
- }
-}
-
-impl Visitor for Printer {
- fn visit(&mut self, tree: &Tree, node: AstNodeIndex) {
- match &tree[node] {
- Node::Root(_) => tree.walk(self, node),
- Node::Group(group) => {
- self.print_token(&group.left);
- tree.walk(self, node);
- if let Some(right) = &group.right {
- self.print_token(right);
- }
- }
- Node::Command(cmd) => {
- self.print_token(&cmd.name);
- tree.walk(self, node);
- }
- Node::Text(text) => {
- for word in &text.words {
- self.print_token(word);
- }
- }
- Node::Comma(comma) => {
- self.print_token(&comma.token);
- }
- Node::Math(math) => {
- self.print_token(&math.token);
- }
- }
- }
-}
diff --git a/support/texlab/src/syntax/latex/cst.rs b/support/texlab/src/syntax/latex/cst.rs
new file mode 100644
index 0000000000..0b839b706d
--- /dev/null
+++ b/support/texlab/src/syntax/latex/cst.rs
@@ -0,0 +1,639 @@
+use cstree::TextRange;
+
+use crate::syntax::CstNode;
+
+use super::{Language, SyntaxKind::*, SyntaxNode, SyntaxToken};
+
+macro_rules! cst_node {
+ ($name:ident, $($kind:pat),+) => {
+ #[derive(Clone)]
+ #[repr(transparent)]
+ pub struct $name<'a>(&'a SyntaxNode);
+
+ impl<'a> CstNode<'a> for $name<'a> {
+ type Lang = Language;
+
+ fn cast(node: &'a cstree::ResolvedNode<Self::Lang>) -> Option<Self>
+ where
+ Self: Sized,
+ {
+ match node.kind() {
+ $($kind => Some(Self(node)),)+
+ _ => None,
+ }
+ }
+
+ fn syntax(&self) -> &'a cstree::ResolvedNode<Self::Lang> {
+ &self.0
+ }
+
+ fn small_range(&self) -> TextRange {
+ let full_range = self.syntax().text_range();
+ let start = full_range.start();
+ let mut token = self.syntax().last_token();
+ while let Some(current) = token {
+ if !matches!(current.kind(), WHITESPACE | COMMENT) {
+ return TextRange::new(start, current.text_range().end());
+ }
+ token = current.prev_token();
+ }
+ TextRange::new(start, start)
+ }
+ }
+ };
+}
+
+cst_node!(Text, TEXT);
+
+pub trait HasCurly<'a>: CstNode<'a, Lang = Language> {
+ fn left_curly(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == L_CURLY)
+ }
+
+ fn right_curly(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == R_CURLY)
+ }
+
+ fn content_text(&self) -> Option<String> {
+ self.left_curly()?;
+ self.right_curly()?;
+ let mut text = String::new();
+ for child in self
+ .syntax()
+ .descendants_with_tokens()
+ .filter_map(|child| child.into_token())
+ .filter(|token| !matches!(token.kind(), COMMENT))
+ {
+ text.push_str(child.text());
+ }
+ let text = text.trim_end();
+ let text = text[1..text.len() - 1].trim().to_string();
+
+ Some(text)
+ }
+}
+
+cst_node!(CurlyGroup, CURLY_GROUP);
+
+impl<'a> HasCurly<'a> for CurlyGroup<'a> {}
+
+impl<'a> CurlyGroup<'a> {}
+
+pub trait HasBrack<'a>: CstNode<'a, Lang = Language> {
+ fn left_brack(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == L_BRACK)
+ }
+
+ fn right_brack(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == R_BRACK)
+ }
+
+ fn content_text(&self) -> Option<String> {
+ self.left_brack()?;
+ self.right_brack()?;
+ let mut text = String::new();
+ for child in self
+ .syntax()
+ .descendants_with_tokens()
+ .filter_map(|child| child.into_token())
+ .filter(|token| !matches!(token.kind(), COMMENT))
+ {
+ text.push_str(child.text());
+ }
+ let text = text.trim_end();
+ let text = text[1..text.len() - 1].trim().to_string();
+
+ Some(text)
+ }
+}
+
+cst_node!(BrackGroup, BRACK_GROUP);
+
+impl<'a> BrackGroup<'a> {}
+
+impl<'a> HasBrack<'a> for BrackGroup<'a> {}
+
+pub trait HasParen<'a>: CstNode<'a, Lang = Language> {
+ fn left_paren(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == L_PAREN)
+ }
+
+ fn right_paren(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == R_PAREN)
+ }
+}
+
+cst_node!(ParenGroup, PAREN_GROUP);
+
+impl<'a> HasParen<'a> for ParenGroup<'a> {}
+
+cst_node!(MixedGroup, MIXED_GROUP);
+
+impl<'a> MixedGroup<'a> {
+ pub fn left_delim(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| matches!(node.kind().into(), L_BRACK | L_PAREN))
+ }
+
+ pub fn right_delim(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| matches!(node.kind().into(), R_BRACK | R_PAREN))
+ }
+}
+
+cst_node!(CurlyGroupWord, CURLY_GROUP_WORD);
+
+impl<'a> HasCurly<'a> for CurlyGroupWord<'a> {}
+
+impl<'a> CurlyGroupWord<'a> {
+ pub fn word(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == WORD)
+ }
+}
+
+cst_node!(BrackGroupWord, BRACK_GROUP_WORD);
+
+impl<'a> HasBrack<'a> for BrackGroupWord<'a> {}
+
+impl<'a> BrackGroupWord<'a> {
+ pub fn word(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == WORD)
+ }
+}
+
+cst_node!(CurlyGroupWordList, CURLY_GROUP_WORD_LIST);
+
+impl<'a> HasCurly<'a> for CurlyGroupWordList<'a> {}
+
+impl<'a> CurlyGroupWordList<'a> {
+ pub fn words(&self) -> impl Iterator<Item = &'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .filter(|node| node.kind() == WORD)
+ }
+}
+
+cst_node!(CurlyGroupCommand, CURLY_GROUP_COMMAND);
+
+impl<'a> HasCurly<'a> for CurlyGroupCommand<'a> {}
+
+impl<'a> CurlyGroupCommand<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == GENERIC_COMMAND_NAME)
+ }
+}
+
+cst_node!(Key, KEY);
+
+impl<'a> Key<'a> {
+ pub fn words(&self) -> impl Iterator<Item = &'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .filter(|node| node.kind() == WORD)
+ }
+}
+
+cst_node!(Value, VALUE);
+
+cst_node!(KeyValuePair, KEY_VALUE_PAIR);
+
+impl<'a> KeyValuePair<'a> {
+ pub fn key(&self) -> Option<Key<'a>> {
+ self.syntax().children().find_map(Key::cast)
+ }
+
+ pub fn value(&self) -> Option<Value<'a>> {
+ self.syntax().children().find_map(Value::cast)
+ }
+}
+
+cst_node!(KeyValueBody, KEY_VALUE_BODY);
+
+impl<'a> KeyValueBody<'a> {
+ pub fn pairs(&self) -> impl Iterator<Item = KeyValuePair<'a>> {
+ self.syntax().children().filter_map(KeyValuePair::cast)
+ }
+}
+
+pub trait HasKeyValueBody<'a>: CstNode<'a, Lang = Language> {
+ fn body(&self) -> Option<KeyValueBody<'a>> {
+ self.syntax().children().find_map(KeyValueBody::cast)
+ }
+}
+
+cst_node!(CurlyGroupKeyValue, CURLY_GROUP_KEY_VALUE);
+
+impl<'a> HasCurly<'a> for CurlyGroupKeyValue<'a> {}
+
+impl<'a> HasKeyValueBody<'a> for CurlyGroupKeyValue<'a> {}
+
+cst_node!(BrackGroupKeyValue, BRACK_GROUP_KEY_VALUE);
+
+impl<'a> HasBrack<'a> for BrackGroupKeyValue<'a> {}
+
+impl<'a> HasKeyValueBody<'a> for BrackGroupKeyValue<'a> {}
+
+cst_node!(Formula, FORMULA);
+
+cst_node!(GenericCommand, GENERIC_COMMAND);
+
+impl<'a> GenericCommand<'a> {
+ pub fn name(&self) -> Option<&'a SyntaxToken> {
+ self.syntax()
+ .children_with_tokens()
+ .filter_map(|node| node.into_token())
+ .find(|node| node.kind() == GENERIC_COMMAND_NAME)
+ }
+}
+
+cst_node!(Equation, EQUATION);
+
+cst_node!(Begin, BEGIN);
+
+impl<'a> Begin<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+
+ pub fn options(&self) -> Option<BrackGroup<'a>> {
+ self.syntax().children().find_map(BrackGroup::cast)
+ }
+}
+
+cst_node!(End, END);
+
+impl<'a> End<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(Environment, ENVIRONMENT);
+
+impl<'a> Environment<'a> {
+ pub fn begin(&self) -> Option<Begin<'a>> {
+ self.syntax().children().find_map(Begin::cast)
+ }
+
+ pub fn end(&self) -> Option<End<'a>> {
+ self.syntax().children().find_map(End::cast)
+ }
+}
+
+cst_node!(
+ Section,
+ PART,
+ CHAPTER,
+ SECTION,
+ SUBSECTION,
+ SUBSUBSECTION,
+ PARAGRAPH,
+ SUBPARAGRAPH
+);
+
+impl<'a> Section<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroup<'a>> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
+
+cst_node!(EnumItem, ENUM_ITEM);
+
+impl<'a> EnumItem<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn label(&self) -> Option<BrackGroup<'a>> {
+ self.syntax().children().find_map(BrackGroup::cast)
+ }
+}
+
+cst_node!(Caption, CAPTION);
+
+impl<'a> Caption<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn short(&self) -> Option<BrackGroup<'a>> {
+ self.syntax().children().find_map(BrackGroup::cast)
+ }
+
+ pub fn long(&self) -> Option<CurlyGroup<'a>> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
+
+cst_node!(Citation, CITATION);
+
+impl<'a> Citation<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn prenote(&self) -> Option<BrackGroup<'a>> {
+ self.syntax().children().find_map(BrackGroup::cast)
+ }
+
+ pub fn postnote(&self) -> Option<BrackGroup<'a>> {
+ self.syntax().children().filter_map(BrackGroup::cast).nth(1)
+ }
+
+ pub fn key_list(&self) -> Option<CurlyGroupWordList<'a>> {
+ self.syntax().children().find_map(CurlyGroupWordList::cast)
+ }
+}
+
+cst_node!(
+ Include,
+ PACKAGE_INCLUDE,
+ CLASS_INCLUDE,
+ LATEX_INCLUDE,
+ BIBLATEX_INCLUDE,
+ BIBTEX_INCLUDE,
+ GRAPHICS_INCLUDE,
+ SVG_INCLUDE,
+ INKSCAPE_INCLUDE,
+ VERBATIM_INCLUDE
+);
+
+impl<'a> Include<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn path_list(&self) -> Option<CurlyGroupWordList<'a>> {
+ self.syntax().children().find_map(CurlyGroupWordList::cast)
+ }
+}
+
+cst_node!(Import, IMPORT);
+
+impl<'a> Import<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn directory(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+
+ pub fn file(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax()
+ .children()
+ .filter_map(CurlyGroupWord::cast)
+ .nth(1)
+ }
+}
+
+cst_node!(LabelDefinition, LABEL_DEFINITION);
+
+impl<'a> LabelDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(LabelReference, LABEL_REFERENCE);
+
+impl<'a> LabelReference<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name_list(&self) -> Option<CurlyGroupWordList<'a>> {
+ self.syntax().children().find_map(CurlyGroupWordList::cast)
+ }
+}
+
+cst_node!(LabelReferenceRange, LABEL_REFERENCE_RANGE);
+
+impl<'a> LabelReferenceRange<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn from(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+
+ pub fn to(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax()
+ .children()
+ .filter_map(CurlyGroupWord::cast)
+ .nth(1)
+ }
+}
+
+cst_node!(LabelNumber, LABEL_NUMBER);
+
+impl<'a> LabelNumber<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+
+ pub fn text(&self) -> Option<CurlyGroup<'a>> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
+
+cst_node!(TheoremDefinition, THEOREM_DEFINITION);
+
+impl<'a> TheoremDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+
+ pub fn description(&self) -> Option<CurlyGroup<'a>> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
+
+cst_node!(CommandDefinition, COMMAND_DEFINITION, MATH_OPERATOR);
+
+impl<'a> CommandDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupCommand<'a>> {
+ self.syntax().children().find_map(CurlyGroupCommand::cast)
+ }
+
+ pub fn implementation(&self) -> Option<CurlyGroup<'a>> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
+
+cst_node!(AcronymReference, ACRONYM_REFERENCE);
+
+impl<'a> AcronymReference<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+}
+
+cst_node!(AcronymDefinition, ACRONYM_DEFINITION);
+
+impl<'a> AcronymDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(AcronymDeclaration, ACRONYM_DECLARATION);
+
+impl<'a> AcronymDeclaration<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(ColorDefinition, COLOR_DEFINITION);
+
+impl<'a> ColorDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+
+ pub fn model(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax()
+ .children()
+ .filter_map(CurlyGroupWord::cast)
+ .nth(1)
+ }
+
+ pub fn spec(&self) -> Option<CurlyGroup<'a>> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
+
+cst_node!(ColorSetDefinition, COLOR_SET_DEFINITION);
+
+impl<'a> ColorSetDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn model_list(&self) -> Option<CurlyGroupWordList<'a>> {
+ self.syntax().children().find_map(CurlyGroupWordList::cast)
+ }
+}
+
+cst_node!(ColorReference, COLOR_REFERENCE);
+
+impl<'a> ColorReference<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(GlossaryEntryReference, GLOSSARY_ENTRY_REFERENCE);
+
+impl<'a> GlossaryEntryReference<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(GlossaryEntryDefinition, GLOSSARY_ENTRY_DEFINITION);
+
+impl<'a> GlossaryEntryDefinition<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord<'a>> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(TikzLibraryImport, TIKZ_LIBRARY_IMPORT);
+
+impl<'a> TikzLibraryImport<'a> {
+ pub fn command(&self) -> Option<&'a SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name_list(&self) -> Option<CurlyGroupWordList<'a>> {
+ self.syntax().children().find_map(CurlyGroupWordList::cast)
+ }
+}
diff --git a/support/texlab/src/syntax/latex/kind.rs b/support/texlab/src/syntax/latex/kind.rs
new file mode 100644
index 0000000000..fcab393380
--- /dev/null
+++ b/support/texlab/src/syntax/latex/kind.rs
@@ -0,0 +1,180 @@
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
+#[allow(non_camel_case_types)]
+#[repr(u16)]
+pub enum SyntaxKind {
+ ERROR = 0,
+ MISSING,
+
+ WHITESPACE,
+ COMMENT,
+ L_CURLY,
+ R_CURLY,
+ L_BRACK,
+ R_BRACK,
+ L_PAREN,
+ R_PAREN,
+ PARAMETER,
+ COMMA,
+ EQUALITY_SIGN,
+ WORD,
+ DOLLAR,
+ GENERIC_COMMAND_NAME,
+ BEGIN_ENVIRONMENT_NAME,
+ END_ENVIRONMENT_NAME,
+ BEGIN_EQUATION_NAME,
+ END_EQUATION_NAME,
+ PART_NAME,
+ CHAPTER_NAME,
+ SECTION_NAME,
+ SUBSECTION_NAME,
+ SUBSUBSECTION_NAME,
+ PARAGRAPH_NAME,
+ SUBPARAGRAPH_NAME,
+ ENUM_ITEM_NAME,
+ CAPTION_NAME,
+ CITATION_NAME,
+ PACKAGE_INCLUDE_NAME,
+ CLASS_INCLUDE_NAME,
+ LATEX_INCLUDE_NAME,
+ BIBLATEX_INCLUDE_NAME,
+ BIBTEX_INCLUDE_NAME,
+ GRAPHICS_INCLUDE_NAME,
+ SVG_INCLUDE_NAME,
+ INKSCAPE_INCLUDE_NAME,
+ VERBATIM_INCLUDE_NAME,
+ IMPORT_NAME,
+ LABEL_DEFINITION_NAME,
+ LABEL_REFERENCE_NAME,
+ LABEL_REFERENCE_RANGE_NAME,
+ LABEL_NUMBER_NAME,
+ COMMAND_DEFINITION_NAME,
+ MATH_OPERATOR_NAME,
+ GLOSSARY_ENTRY_DEFINITION_NAME,
+ GLOSSARY_ENTRY_REFERENCE_NAME,
+ ACRONYM_DEFINITION_NAME,
+ ACRONYM_DECLARATION_NAME,
+ ACRONYM_REFERENCE_NAME,
+ THEOREM_DEFINITION_NAME,
+ COLOR_REFERENCE_NAME,
+ COLOR_DEFINITION_NAME,
+ COLOR_SET_DEFINITION_NAME,
+ TIKZ_LIBRARY_IMPORT_NAME,
+ ENVIRONMENT_DEFINIITION_NAME,
+
+ PREAMBLE,
+ TEXT,
+ KEY,
+ VALUE,
+ KEY_VALUE_PAIR,
+ KEY_VALUE_BODY,
+ CURLY_GROUP,
+ CURLY_GROUP_WORD,
+ CURLY_GROUP_WORD_LIST,
+ CURLY_GROUP_COMMAND,
+ CURLY_GROUP_KEY_VALUE,
+ BRACK_GROUP,
+ BRACK_GROUP_WORD,
+ BRACK_GROUP_KEY_VALUE,
+ PAREN_GROUP,
+ MIXED_GROUP,
+ GENERIC_COMMAND,
+ ENVIRONMENT,
+ BEGIN,
+ END,
+ EQUATION,
+ PART,
+ CHAPTER,
+ SECTION,
+ SUBSECTION,
+ SUBSUBSECTION,
+ PARAGRAPH,
+ SUBPARAGRAPH,
+ ENUM_ITEM,
+ FORMULA,
+ CAPTION,
+ CITATION,
+ PACKAGE_INCLUDE,
+ CLASS_INCLUDE,
+ LATEX_INCLUDE,
+ BIBLATEX_INCLUDE,
+ BIBTEX_INCLUDE,
+ GRAPHICS_INCLUDE,
+ SVG_INCLUDE,
+ INKSCAPE_INCLUDE,
+ VERBATIM_INCLUDE,
+ IMPORT,
+ LABEL_DEFINITION,
+ LABEL_REFERENCE,
+ LABEL_REFERENCE_RANGE,
+ LABEL_NUMBER,
+ COMMAND_DEFINITION,
+ MATH_OPERATOR,
+ GLOSSARY_ENTRY_DEFINITION,
+ GLOSSARY_ENTRY_REFERENCE,
+ ACRONYM_DEFINITION,
+ ACRONYM_DECLARATION,
+ ACRONYM_REFERENCE,
+ THEOREM_DEFINITION,
+ COLOR_REFERENCE,
+ COLOR_DEFINITION,
+ COLOR_SET_DEFINITION,
+ TIKZ_LIBRARY_IMPORT,
+ ENVIRONMENT_DEFINITION,
+ ROOT,
+}
+
+impl SyntaxKind {
+ pub fn is_command_name(&self) -> bool {
+ use SyntaxKind::*;
+ matches!(
+ self,
+ GENERIC_COMMAND_NAME
+ | BEGIN_ENVIRONMENT_NAME
+ | END_ENVIRONMENT_NAME
+ | BEGIN_EQUATION_NAME
+ | END_EQUATION_NAME
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | SUBSUBSECTION_NAME
+ | PARAGRAPH_NAME
+ | SUBPARAGRAPH_NAME
+ | ENUM_ITEM_NAME
+ | CAPTION_NAME
+ | CITATION_NAME
+ | PACKAGE_INCLUDE_NAME
+ | CLASS_INCLUDE_NAME
+ | LATEX_INCLUDE_NAME
+ | BIBLATEX_INCLUDE_NAME
+ | BIBTEX_INCLUDE_NAME
+ | GRAPHICS_INCLUDE_NAME
+ | SVG_INCLUDE_NAME
+ | INKSCAPE_INCLUDE_NAME
+ | VERBATIM_INCLUDE_NAME
+ | IMPORT_NAME
+ | LABEL_DEFINITION_NAME
+ | LABEL_REFERENCE_NAME
+ | LABEL_REFERENCE_RANGE_NAME
+ | LABEL_NUMBER_NAME
+ | COMMAND_DEFINITION_NAME
+ | MATH_OPERATOR_NAME
+ | GLOSSARY_ENTRY_DEFINITION_NAME
+ | GLOSSARY_ENTRY_REFERENCE_NAME
+ | ACRONYM_DEFINITION_NAME
+ | ACRONYM_DECLARATION_NAME
+ | ACRONYM_REFERENCE_NAME
+ | THEOREM_DEFINITION_NAME
+ | COLOR_REFERENCE_NAME
+ | COLOR_DEFINITION_NAME
+ | COLOR_SET_DEFINITION_NAME
+ | TIKZ_LIBRARY_IMPORT_NAME
+ )
+ }
+}
+
+impl From<SyntaxKind> for cstree::SyntaxKind {
+ fn from(kind: SyntaxKind) -> Self {
+ Self(kind as u16)
+ }
+}
diff --git a/support/texlab/src/syntax/latex/lexer.rs b/support/texlab/src/syntax/latex/lexer.rs
index e14f1f6d85..7cd94ec897 100644
--- a/support/texlab/src/syntax/latex/lexer.rs
+++ b/support/texlab/src/syntax/latex/lexer.rs
@@ -1,176 +1,255 @@
-use super::ast::{Token, TokenKind};
-use crate::syntax::text::CharStream;
+use logos::Logos;
-#[derive(Debug)]
+use super::kind::SyntaxKind;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord, Logos)]
+#[allow(non_camel_case_types)]
+#[repr(u16)]
+enum Token {
+ #[regex(r"\s+")]
+ WHITESPACE = 2,
+
+ #[regex(r"%[^\r\n]*")]
+ COMMENT,
+
+ #[token("{")]
+ L_CURLY,
+
+ #[token("}")]
+ R_CURLY,
+
+ #[token("[")]
+ L_BRACK,
+
+ #[token("]")]
+ R_BRACK,
+
+ #[token("(")]
+ L_PAREN,
+
+ #[token(")")]
+ R_PAREN,
+
+ #[regex(r"#\d?")]
+ PARAMETER,
+
+ #[token(",")]
+ COMMA,
+
+ #[token("=")]
+ EQUALITY_SIGN,
+
+ #[regex(r"[^\s\\%\{\},\$\[\]\(\)=\#]+")]
+ #[error]
+ WORD,
+
+ #[regex(r"\$\$?")]
+ DOLLAR,
+
+ #[regex(r"\\([^\r\n]|[@a-zA-Z:_]+\*?)?")]
+ GENERIC_COMMAND_NAME,
+
+ #[regex(r"\\begin")]
+ BEGIN_ENVIRONMENT_NAME,
+
+ #[regex(r"\\end")]
+ END_ENVIRONMENT_NAME,
+
+ #[regex(r"\\\[")]
+ BEGIN_EQUATION_NAME,
+
+ #[regex(r"\\\]")]
+ END_EQUATION_NAME,
+
+ #[regex(r"\\part\*?")]
+ PART_NAME,
+
+ #[regex(r"\\chapter\*?")]
+ CHAPTER_NAME,
+
+ #[regex(r"\\section\*?")]
+ SECTION_NAME,
+
+ #[regex(r"\\subsection\*?")]
+ SUBSECTION_NAME,
+
+ #[regex(r"\\subsubsection\*?")]
+ SUBSUBSECTION_NAME,
+
+ #[regex(r"\\paragraph\*?")]
+ PARAGRAPH_NAME,
+
+ #[regex(r"\\subparagraph\*?")]
+ SUBPARAGRAPH_NAME,
+
+ #[regex(r"\\item")]
+ ENUM_ITEM_NAME,
+
+ #[regex(r"\\caption")]
+ CAPTION_NAME,
+
+ #[regex(r"\\cite|\\cite\*|\\Cite|\\nocite|\\citet|\\citep|\\citet\*|\\citep\*|\\citeauthor|\\citeauthor\*|\\Citeauthor|\\Citeauthor\*|\\citetitle|\\citetitle\*|\\citeyear|\\citeyear\*|\\citedate|\\citedate\*|\\citeurl|\\fullcite|\\citeyearpar|\\citealt|\\citealp|\\citetext|\\parencite|\\parencite\*|\\Parencite|\\footcite|\\footfullcite|\\footcitetext|\\textcite|\\Textcite|\\smartcite|\\Smartcite|\\supercite|\\autocite|\\Autocite|\\autocite\*|\\Autocite\*|\\volcite|\\Volcite|\\pvolcite|\\Pvolcite|\\fvolcite|\\ftvolcite|\\svolcite|\\Svolcite|\\tvolcite|\\Tvolcite|\\avolcite|\\Avolcite|\\notecite|\\notecite|\\pnotecite|\\Pnotecite|\\fnotecite|\\citeA|\\citeA\*")]
+ CITATION_NAME,
+
+ #[regex(r"\\usepackage|\\RequirePackage")]
+ PACKAGE_INCLUDE_NAME,
+
+ #[regex(r"\\documentclass")]
+ CLASS_INCLUDE_NAME,
+
+ #[regex(r"\\include|\\subfileinclude|\\input|\\subfile")]
+ LATEX_INCLUDE_NAME,
+
+ #[regex(r"\\addbibresource")]
+ BIBLATEX_INCLUDE_NAME,
+
+ #[regex(r"\\bibliography")]
+ BIBTEX_INCLUDE_NAME,
+
+ #[regex(r"\\includegraphics")]
+ GRAPHICS_INCLUDE_NAME,
+
+ #[regex(r"\\includesvg")]
+ SVG_INCLUDE_NAME,
+
+ #[regex(r"\\includeinkscape")]
+ INKSCAPE_INCLUDE_NAME,
+
+ #[regex(r"\\verbatiminput|\\VerbatimInput")]
+ VERBATIM_INCLUDE_NAME,
+
+ #[regex(r"\\import|\\subimport|\\inputfrom|\\subimportfrom|\\includefrom|\\subincludefrom")]
+ IMPORT_NAME,
+
+ #[regex(r"\\label")]
+ LABEL_DEFINITION_NAME,
+
+ #[regex(r"\\ref|\\vref|\\Vref|\\autoref|\\pageref|\\cref|\\Cref|\\cref*|\\Cref*|\\namecref|\\nameCref|\\lcnamecref|\\namecrefs|\\nameCrefs|\\lcnamecrefs|\\labelcref|\\labelcpageref|\\eqref")]
+ LABEL_REFERENCE_NAME,
+
+ #[regex(r"\\crefrange\*?|\\Crefrange\*?")]
+ LABEL_REFERENCE_RANGE_NAME,
+
+ #[regex(r"\\newlabel")]
+ LABEL_NUMBER_NAME,
+
+ #[regex(r"\\newcommand\*?|\\renewcommand|\\DeclareRobustCommand")]
+ COMMAND_DEFINITION_NAME,
+
+ #[regex(r"\\DeclareMathOperator\*?")]
+ MATH_OPERATOR_NAME,
+
+ #[regex(r"\\newglossaryentry")]
+ GLOSSARY_ENTRY_DEFINITION_NAME,
+
+ #[regex(r"\\gls|\\Gls|\\GLS|\\glspl|\\Glspl|\\GLSpl|\\glsdisp|\\glslink|\\glstext|\\Glstext|\\GLStext|\\glsfirst|\\Glsfirst|\\GLSfirst|\\glsplural|\\Glsplural|\\GLSplural|\\glsfirstplural|\\Glsfirstplural|\\GLSfirstplural|\\glsname|\\Glsname|\\GLSname|\\glssymbol|\\Glssymbol|\\glsdesc|\\Glsdesc|\\GLSdesc|\\glsuseri|\\Glsuseri|\\GLSuseri|\\glsuserii|\\Glsuserii|\\GLSuserii|\\glsuseriii|\\Glsuseriii|\\GLSuseriii|\\glsuseriv|\\Glsuseriv|\\GLSuseriv|\\glsuserv|\\Glsuserv|\\GLSuserv|\\glsuservi|\\Glsuservi|\\GLSuservi")]
+ GLOSSARY_ENTRY_REFERENCE_NAME,
+
+ #[regex(r"\\newacronym")]
+ ACRONYM_DEFINITION_NAME,
+
+ #[regex(r"\\DeclareAcronym")]
+ ACRONYM_DECLARATION_NAME,
+
+ #[regex(r"\\acrshort|\\Acrshort|\\ACRshort|\\acrshortpl|\\Acrshortpl|\\ACRshortpl|\\acrlong|\\Acrlong|\\ACRlong|\\acrlongpl|\\Acrlongpl|\\ACRlongpl|\\acrfull|\\Acrfull|\\ACRfull|\\acrfullpl|\\Acrfullpl|\\ACRfullpl|\\acs|\\Acs|\\acsp|\\Acsp|\\acl|\\Acl|\\aclp|\\Aclp|\\acf|\\Acf|\\acfp|\\Acfp|\\ac|\\Ac|\\acp|\\glsentrylong|\\Glsentrylong|\\glsentrylongpl|\\Glsentrylongpl|\\glsentryshort|\\Glsentryshort|\\glsentryshortpl|\\Glsentryshortpl|\\glsentryfullpl|\\Glsentryfullpl")]
+ ACRONYM_REFERENCE_NAME,
+
+ #[regex(r"\\newtheorem|\\declaretheorem")]
+ THEOREM_DEFINITION_NAME,
+
+ #[regex(r"\\color|\\colorbox|\\textcolor|\\pagecolor")]
+ COLOR_REFERENCE_NAME,
+
+ #[regex(r"\\definecolor")]
+ COLOR_DEFINITION_NAME,
+
+ #[regex(r"\\definecolorset")]
+ COLOR_SET_DEFINITION_NAME,
+
+ #[regex(r"\\usepgflibrary|\\usetikzlibrary")]
+ TIKZ_LIBRARY_IMPORT_NAME,
+
+ #[regex(r"\\newenvironment|\\newenvironment*")]
+ ENVIRONMENT_DEFINITION_NAME,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Lexer<'a> {
- stream: CharStream<'a>,
+ tokens: Vec<(SyntaxKind, &'a str)>,
}
impl<'a> Lexer<'a> {
pub fn new(text: &'a str) -> Self {
- Self {
- stream: CharStream::new(text),
+ let mut tokens = Vec::new();
+ let mut lexer = Token::lexer(text);
+ while let Some(kind) = lexer.next() {
+ tokens.push((
+ unsafe { std::mem::transmute::<Token, SyntaxKind>(kind) },
+ lexer.slice(),
+ ));
}
+ tokens.reverse();
+ Self { tokens }
}
- fn single_char(&mut self, kind: TokenKind) -> Token {
- self.stream.start_span();
- self.stream.next();
- let span = self.stream.end_span();
- Token::new(span, kind)
+ pub fn peek(&self) -> Option<SyntaxKind> {
+ self.tokens.last().map(|(kind, _)| *kind)
}
- fn math(&mut self) -> Token {
- self.stream.start_span();
- self.stream.next();
- if self.stream.satifies(|c| *c == '$') {
- self.stream.next();
- }
- let span = self.stream.end_span();
- Token::new(span, TokenKind::Math)
+ pub fn eat(&mut self) -> Option<(SyntaxKind, &'a str)> {
+ self.tokens.pop()
}
+}
- fn command(&mut self) -> Token {
- let span = self.stream.command();
- Token::new(span, TokenKind::Command)
- }
+#[cfg(test)]
+mod tests {
+ use insta::assert_debug_snapshot;
- fn word(&mut self) -> Token {
- self.stream.start_span();
- self.stream.next();
- while self.stream.satifies(|c| is_word_char(*c)) {
- self.stream.next();
- }
+ use super::*;
- let span = self.stream.end_span();
- Token::new(span, TokenKind::Word)
+ fn verify(text: &str) -> Vec<(SyntaxKind, &str)> {
+ let mut tokens = Lexer::new(text).tokens;
+ tokens.reverse();
+ tokens
}
-}
-impl<'a> Iterator for Lexer<'a> {
- type Item = Token;
-
- fn next(&mut self) -> Option<Token> {
- loop {
- match self.stream.peek() {
- Some('%') => {
- self.stream.skip_rest_of_line();
- }
- Some('{') => {
- return Some(self.single_char(TokenKind::BeginGroup));
- }
- Some('}') => {
- return Some(self.single_char(TokenKind::EndGroup));
- }
- Some('[') => {
- return Some(self.single_char(TokenKind::BeginOptions));
- }
- Some(']') => {
- return Some(self.single_char(TokenKind::EndOptions));
- }
- Some('$') => {
- return Some(self.math());
- }
- Some(',') => {
- return Some(self.single_char(TokenKind::Comma));
- }
- Some('\\') => {
- return Some(self.command());
- }
- Some(c) => {
- if c.is_whitespace() {
- self.stream.next();
- } else {
- return Some(self.word());
- }
- }
- None => {
- return None;
- }
- }
- }
+ #[test]
+ fn test_empty() {
+ assert_debug_snapshot!(verify(r#""#));
}
-}
-
-fn is_word_char(c: char) -> bool {
- !c.is_whitespace()
- && c != '%'
- && c != '{'
- && c != '}'
- && c != '['
- && c != ']'
- && c != '\\'
- && c != '$'
- && c != ','
-}
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- protocol::{Position, Range},
- syntax::text::Span,
- };
-
- fn verify<'a>(lexer: &mut Lexer<'a>, line: u64, character: u64, text: &str, kind: TokenKind) {
- let start = Position::new(line, character);
- let end = Position::new(line, character + text.chars().count() as u64);
- let range = Range::new(start, end);
- let span = Span::new(range, text.to_owned());
- let token = Token::new(span, kind);
- assert_eq!(Some(token), lexer.next());
+ #[test]
+ fn test_delimiters() {
+ assert_debug_snapshot!(verify(r#"{foo} (bar) [baz, qux = foo-bar]"#));
}
#[test]
- fn word() {
- let mut lexer = Lexer::new("foo bar baz");
- verify(&mut lexer, 0, 0, "foo", TokenKind::Word);
- verify(&mut lexer, 0, 4, "bar", TokenKind::Word);
- verify(&mut lexer, 0, 8, "baz", TokenKind::Word);
- assert_eq!(None, lexer.next());
+ fn test_command_with_parameter() {
+ assert_debug_snapshot!(verify(r#"\newcommand{\id}[1]{#1}"#));
}
#[test]
- fn command() {
- let mut lexer = Lexer::new("\\foo\\bar@baz\n\\foo*");
- verify(&mut lexer, 0, 0, "\\foo", TokenKind::Command);
- verify(&mut lexer, 0, 4, "\\bar@baz", TokenKind::Command);
- verify(&mut lexer, 1, 0, "\\foo*", TokenKind::Command);
- assert_eq!(None, lexer.next());
+ fn test_command_with_star() {
+ assert_debug_snapshot!(verify(r#"\section*{Foo}"#));
}
#[test]
- fn escape_sequence() {
- let mut lexer = Lexer::new("\\%\\**");
- verify(&mut lexer, 0, 0, "\\%", TokenKind::Command);
- verify(&mut lexer, 0, 2, "\\*", TokenKind::Command);
- verify(&mut lexer, 0, 4, "*", TokenKind::Word);
- assert_eq!(None, lexer.next());
+ fn test_escape_sequence() {
+ assert_debug_snapshot!(verify(r#"\% hello"#));
}
#[test]
- fn group_delimiter() {
- let mut lexer = Lexer::new("{}[]");
- verify(&mut lexer, 0, 0, "{", TokenKind::BeginGroup);
- verify(&mut lexer, 0, 1, "}", TokenKind::EndGroup);
- verify(&mut lexer, 0, 2, "[", TokenKind::BeginOptions);
- verify(&mut lexer, 0, 3, "]", TokenKind::EndOptions);
- assert_eq!(None, lexer.next());
+ fn test_formula() {
+ assert_debug_snapshot!(verify(r#"$ f(x) = y $$"#));
}
#[test]
- fn math() {
- let mut lexer = Lexer::new("$$ $ $");
- verify(&mut lexer, 0, 0, "$$", TokenKind::Math);
- verify(&mut lexer, 0, 3, "$", TokenKind::Math);
- verify(&mut lexer, 0, 5, "$", TokenKind::Math);
- assert_eq!(None, lexer.next());
+ fn test_comment() {
+ assert_debug_snapshot!(verify("hello %world\r\ntest %test"));
}
#[test]
- fn line_comment() {
- let mut lexer = Lexer::new(" %foo \nfoo");
- verify(&mut lexer, 1, 0, "foo", TokenKind::Word);
- assert_eq!(None, lexer.next());
+ fn test_invalid_parameter() {
+ assert_debug_snapshot!(verify(r#"#"#))
}
}
diff --git a/support/texlab/src/syntax/latex/mod.rs b/support/texlab/src/syntax/latex/mod.rs
deleted file mode 100644
index cee83ab04e..0000000000
--- a/support/texlab/src/syntax/latex/mod.rs
+++ /dev/null
@@ -1,686 +0,0 @@
-mod analysis;
-mod ast;
-mod lexer;
-mod parser;
-
-pub use self::{analysis::*, ast::*};
-
-use self::{lexer::Lexer, parser::Parser};
-use crate::{
- protocol::{Options, Uri},
- tex::Resolver,
-};
-use std::path::Path;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct OpenParams<'a> {
- pub text: &'a str,
- pub uri: &'a Uri,
- pub resolver: &'a Resolver,
- pub options: &'a Options,
- pub current_dir: &'a Path,
-}
-
-pub fn open(params: OpenParams) -> SymbolTable {
- let OpenParams {
- text,
- uri,
- resolver,
- options,
- current_dir,
- } = params;
-
- let lexer = Lexer::new(text);
- let parser = Parser::new(lexer);
- let tree = parser.parse();
-
- let params = SymbolTableParams {
- tree,
- uri,
- resolver,
- options,
- current_dir,
- };
- SymbolTable::analyze(params)
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{
- protocol::{Options, Range, RangeExt, Uri},
- syntax::{generic_ast::AstNodeIndex, text::SyntaxNode},
- tex::Resolver,
- };
- use indoc::indoc;
- use std::env;
-
- fn open_simple(text: &str) -> SymbolTable {
- open(OpenParams {
- text: text.trim(),
- uri: &Uri::parse("http://www.foo.com/bar.tex").unwrap(),
- resolver: &Resolver::default(),
- options: &Options::default(),
- current_dir: &env::current_dir().unwrap(),
- })
- }
-
- #[derive(Debug, Default)]
- struct TreeTraversal {
- nodes: Vec<AstNodeIndex>,
- }
-
- impl Visitor for TreeTraversal {
- fn visit(&mut self, tree: &Tree, node: AstNodeIndex) {
- self.nodes.push(node);
- tree.walk(self, node);
- }
- }
-
- mod range {
- use super::*;
-
- fn verify(expected_ranges: Vec<Range>, text: &str) {
- let table = open_simple(text);
-
- let mut traversal = TreeTraversal::default();
- traversal.visit(&table.tree, table.tree.root);
- let actual_ranges: Vec<_> = traversal
- .nodes
- .into_iter()
- .map(|node| table[node].range())
- .collect();
- assert_eq!(actual_ranges, expected_ranges);
- }
-
- #[test]
- fn command() {
- verify(
- vec![
- Range::new_simple(0, 0, 2, 14),
- Range::new_simple(0, 0, 0, 23),
- Range::new_simple(0, 14, 0, 23),
- Range::new_simple(0, 15, 0, 22),
- Range::new_simple(1, 0, 1, 20),
- Range::new_simple(1, 11, 1, 20),
- Range::new_simple(1, 12, 1, 19),
- Range::new_simple(2, 0, 2, 14),
- Range::new_simple(2, 4, 2, 9),
- Range::new_simple(2, 5, 2, 8),
- Range::new_simple(2, 9, 2, 14),
- Range::new_simple(2, 10, 2, 13),
- ],
- indoc!(
- r#"
- \documentclass{article}
- \usepackage{amsmath}
- \foo[bar]{baz}
- "#
- ),
- );
- }
-
- #[test]
- fn text() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 11),
- Range::new_simple(0, 0, 0, 11),
- ],
- indoc!(
- r#"
- foo bar baz
- "#
- ),
- );
- }
-
- #[test]
- fn text_bracket() {
- verify(
- vec![Range::new_simple(0, 0, 0, 5), Range::new_simple(0, 0, 0, 5)],
- indoc!(
- r#"
- ]foo[
- "#
- ),
- );
- }
-
- #[test]
- fn group() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 15),
- Range::new_simple(0, 0, 0, 15),
- Range::new_simple(0, 2, 0, 5),
- Range::new_simple(0, 6, 0, 13),
- Range::new_simple(0, 8, 0, 11),
- ],
- indoc!(
- r#"
- { foo { bar } }
- "#
- ),
- );
- }
-
- #[test]
- fn group_incomplete() {
- verify(
- vec![Range::new_simple(0, 1, 0, 2), Range::new_simple(0, 1, 0, 2)],
- indoc!(
- r#"
- }{
- "#
- ),
- );
- }
-
- #[test]
- fn math() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 9),
- Range::new_simple(0, 0, 0, 1),
- Range::new_simple(0, 2, 0, 7),
- Range::new_simple(0, 8, 0, 9),
- ],
- indoc!(
- r#"
- $ x = 1 $
- "#
- ),
- );
- }
-
- #[test]
- fn comma() {
- verify(
- vec![
- Range::new_simple(0, 0, 0, 8),
- Range::new_simple(0, 0, 0, 3),
- Range::new_simple(0, 3, 0, 4),
- Range::new_simple(0, 5, 0, 8),
- ],
- indoc!(
- r#"
- foo, bar
- "#
- ),
- );
- }
- }
-
- mod command {
- use super::*;
-
- fn verify(expected_names: Vec<&str>, text: &str) {
- let table = open(OpenParams {
- text,
- uri: &Uri::parse("http://www.foo.com/bar.tex").unwrap(),
- resolver: &Resolver::default(),
- options: &Options::default(),
- current_dir: &env::current_dir().unwrap(),
- });
-
- let actual_names: Vec<_> = table
- .commands
- .iter()
- .map(|node| table.tree.as_command(*node).unwrap().name.text())
- .collect();
-
- assert_eq!(actual_names, expected_names);
- }
-
- #[test]
- fn basic() {
- verify(
- vec!["\\documentclass", "\\usepackage", "\\begin", "\\end"],
- indoc!(
- r#"
- \documentclass{article}
- \usepackage{amsmath}
- \begin{document}
- Hello World
- \end{document}
- "#
- ),
- );
- }
-
- #[test]
- fn star() {
- verify(
- vec!["\\section*", "\\subsection*"],
- indoc!(
- r#"
- \section*{Foo}
- \subsection**{Bar}
- "#
- ),
- );
- }
-
- #[test]
- fn at() {
- verify(vec!["\\foo@bar"], indoc!(r#"\foo@bar"#));
- }
-
- #[test]
- fn escape() {
- verify(vec!["\\%"], indoc!(r#"\%foo"#))
- }
- }
-
- mod environment {
- use super::*;
-
- fn verify(expected_names: Vec<(&str, &str)>, text: &str) {
- let table = open_simple(text);
- let actual_names: Vec<_> = table
- .environments
- .iter()
- .map(|env| {
- (
- env.left
- .name(&table.tree)
- .map(Token::text)
- .unwrap_or_default(),
- env.right
- .name(&table.tree)
- .map(Token::text)
- .unwrap_or_default(),
- )
- })
- .collect();
-
- assert_eq!(actual_names, expected_names);
- }
-
- #[test]
- fn nested() {
- verify(
- vec![("b", "b"), ("a", "a")],
- indoc!(
- r#"
- \begin{a}
- \begin{b}
- \end{b}
- \end{a}
- "#
- ),
- );
- }
-
- #[test]
- fn empty_name() {
- verify(
- vec![("a", ""), ("", "b")],
- indoc!(
- r#"
- \begin{a}
- \end{}
- \begin{}
- \end{b}
- "#
- ),
- );
- }
-
- #[test]
- fn incomplete() {
- verify(
- Vec::new(),
- indoc!(
- r#"
- \end{a}
- \begin{a}
- "#
- ),
- );
- }
-
- #[test]
- fn standalone_true() {
- let table = open_simple(r#"\begin{document}\end{document}"#);
- assert!(table.is_standalone);
- }
-
- #[test]
- fn standalone_false() {
- let table = open_simple(r#"\begin{doc}\end{doc}"#);
- assert!(!table.is_standalone);
- }
- }
-
- mod include {
- use super::*;
-
- fn verify(expected_targets: Vec<Vec<&str>>, resolver: Resolver, text: &str) {
- let table = open(OpenParams {
- text,
- uri: &Uri::parse("http://www.foo.com/dir1/dir2/foo.tex").unwrap(),
- resolver: &resolver,
- options: &Options::default(),
- current_dir: &env::current_dir().unwrap(),
- });
-
- assert_eq!(table.includes.len(), 1);
- let include = &table.includes[0];
- let actual_targets: Vec<Vec<&str>> = include
- .all_targets
- .iter()
- .map(|targets| targets.iter().map(|target| target.as_str()).collect())
- .collect();
-
- assert_eq!(actual_targets, expected_targets);
- }
-
- #[test]
- fn same_directory() {
- verify(
- vec![vec![
- "http://www.foo.com/dir1/dir2/bar",
- "http://www.foo.com/dir1/dir2/bar.tex",
- ]],
- Resolver::default(),
- indoc!(r#"\include{bar}"#),
- );
- }
-
- #[test]
- fn two_paths() {
- verify(
- vec![
- vec![
- "http://www.foo.com/dir1/dir2/bar.tex",
- "http://www.foo.com/dir1/dir2/bar.tex.tex",
- ],
- vec![
- "http://www.foo.com/dir1/dir2/baz.tex",
- "http://www.foo.com/dir1/dir2/baz.tex.tex",
- ],
- ],
- Resolver::default(),
- indoc!(r#"\input{bar.tex, ./baz.tex}"#),
- );
- }
-
- #[test]
- fn sub_directory() {
- verify(
- vec![vec![
- "http://www.foo.com/dir1/dir2/dir3/bar",
- "http://www.foo.com/dir1/dir2/dir3/bar.tex",
- ]],
- Resolver::default(),
- indoc!(r#"\include{dir3/bar}"#),
- );
- }
-
- #[test]
- fn parent_directory() {
- verify(
- vec![vec![
- "http://www.foo.com/dir1/bar",
- "http://www.foo.com/dir1/bar.tex",
- ]],
- Resolver::default(),
- indoc!(r#"\include{../bar}"#),
- );
- }
-
- #[test]
- fn distro_file() {
- let mut resolver = Resolver::default();
- let path = env::current_dir().unwrap().join("biblatex-examples.bib");
- resolver
- .files_by_name
- .insert("biblatex-examples.bib".into(), path.clone());
- verify(
- vec![vec![
- "http://www.foo.com/dir1/dir2/biblatex-examples.bib",
- "http://www.foo.com/dir1/dir2/biblatex-examples.bib.bib",
- Uri::from_file_path(&path).unwrap().as_str(),
- ]],
- resolver,
- indoc!(r#"\addbibresource{biblatex-examples.bib}"#),
- );
- }
-
- #[test]
- fn component() {
- let table = open(OpenParams {
- text: indoc!(
- r#"
- \documentclass{article}
- \usepackage{amsmath}
- \usepackage{geometry, lipsum}
- "#
- ),
- uri: &Uri::parse("http://www.foo.com/bar.tex").unwrap(),
- resolver: &Resolver::default(),
- options: &Options::default(),
- current_dir: &env::current_dir().unwrap(),
- });
- assert_eq!(
- table.components,
- vec!["article.cls", "amsmath.sty", "geometry.sty", "lipsum.sty"]
- );
- }
- }
-
- #[test]
- fn citation() {
- let table = open_simple(indoc!(
- r#"
- \cite{key1}
- \cite{key2, key3}
- \nocite{*}
- "#
- ));
-
- let expected_keys = vec![vec!["key1"], vec!["key2", "key3"], vec!["*"]];
-
- let actual_keys: Vec<Vec<&str>> = table
- .citations
- .iter()
- .map(|cit| cit.keys(&table.tree).into_iter().map(Token::text).collect())
- .collect();
-
- assert_eq!(actual_keys, expected_keys);
- }
-
- #[test]
- fn command_definition() {
- let table = open_simple(indoc!(
- r#"
- \newcommand{\foo}{Foo}
- \newcommand[2]{\bar}{Bar}
- \renewcommand{\baz}{Baz}
- \qux
- "#
- ));
-
- let expected_cmds = vec!["\\foo", "\\bar", "\\baz"];
-
- let actual_cmds: Vec<&str> = table
- .command_definitions
- .iter()
- .map(|def| def.definition_name(&table.tree))
- .collect();
-
- assert_eq!(actual_cmds, expected_cmds);
- }
-
- #[test]
- fn glossary_entry() {
- let table = open_simple(indoc!(
- r#"
- \newglossaryentry{foo}{...}
- \newacronym{bar}{...}
- "#
- ));
-
- let expected_entries = vec!["foo", "bar"];
-
- let actual_entries: Vec<&str> = table
- .glossary_entries
- .iter()
- .map(|entry| entry.label(&table.tree).text())
- .collect();
-
- assert_eq!(actual_entries, expected_entries);
- }
-
- #[test]
- fn equation() {
- let table = open_simple(indoc!(
- r#"
- \[
- e^{i \pi} + 1 = 0
- \]
- \] \[
- "#
- ));
-
- assert_eq!(table.equations.len(), 1);
- }
-
- #[test]
- fn inline() {
- let table = open_simple(indoc!(
- r#"
- $ x $
- $
- "#
- ));
-
- assert_eq!(table.inlines.len(), 1);
- }
-
- #[test]
- fn math_operator() {
- let table = open_simple(indoc!(
- r#"
- \DeclareMathOperator{\foo}{foo}
- "#
- ));
-
- assert_eq!(table.math_operators.len(), 1);
- assert_eq!(
- table.math_operators[0].definition_name(&table.tree),
- "\\foo"
- );
- }
-
- #[test]
- fn theorem_definition() {
- let table = open_simple(indoc!(
- r#"
- \newtheorem{lemma}{Lemma}
- "#
- ));
-
- assert_eq!(table.theorem_definitions.len(), 1);
- assert_eq!(
- table.theorem_definitions[0].name(&table.tree).text(),
- "lemma"
- );
- }
-
- #[test]
- fn section() {
- let table = open_simple(indoc!(
- r#"
- \section{Introduction to \LaTeX}
- \subsection*{Foo
- "#
- ));
- assert_eq!(table.sections.len(), 2);
- assert_eq!(
- table.sections[0].print(&table.tree).unwrap(),
- "Introduction to \\LaTeX"
- );
- assert_eq!(table.sections[1].print(&table.tree), None);
- }
-
- #[test]
- fn label() {
- let table = open_simple(indoc!(
- r#"
- \label{foo}
- \ref{bar, baz}
- "#
- ));
-
- let expected_names = vec![vec!["foo"], vec!["bar", "baz"]];
-
- let actual_names: Vec<Vec<&str>> = table
- .labels
- .iter()
- .map(|label| {
- label
- .names(&table.tree)
- .into_iter()
- .map(Token::text)
- .collect()
- })
- .collect();
-
- assert_eq!(actual_names, expected_names);
- }
-
- #[test]
- fn label_numbering() {
- let table = open_simple(indoc!(
- r#"
- \newlabel{foo}{{1}{1}}
- "#
- ));
-
- assert_eq!(table.label_numberings.len(), 1);
- assert_eq!(table.label_numberings[0].name(&table.tree).text(), "foo");
- assert_eq!(table.label_numberings[0].number, "1");
- }
-
- #[test]
- fn caption() {
- let table = open_simple(indoc!(
- r#"
- \caption{Foo \LaTeX Bar}
- "#
- ));
-
- assert_eq!(table.captions.len(), 1);
- assert_eq!(
- table.captions[0].print(&table.tree).unwrap(),
- "Foo \\LaTeX Bar"
- );
- }
-
- #[test]
- fn item_without_name() {
- let table = open_simple(indoc!(
- r#"
- \item
- "#
- ));
-
- assert_eq!(table.items.len(), 1);
- assert_eq!(table.items[0].name(&table.tree), None);
- }
-
- #[test]
- fn item_with_name() {
- let table = open_simple(indoc!(
- r#"
- \item[foo bar]
- "#
- ));
-
- assert_eq!(table.items.len(), 1);
- assert_eq!(table.items[0].name(&table.tree).unwrap(), "foo bar");
- }
-}
diff --git a/support/texlab/src/syntax/latex/parser.rs b/support/texlab/src/syntax/latex/parser.rs
index 4ace4fbcd6..4333235ba5 100644
--- a/support/texlab/src/syntax/latex/parser.rs
+++ b/support/texlab/src/syntax/latex/parser.rs
@@ -1,186 +1,1709 @@
-use super::ast::*;
-use crate::{
- protocol::{Range, RangeExt},
- syntax::{
- generic_ast::{Ast, AstNodeIndex},
- text::SyntaxNode,
- },
+use cstree::GreenNodeBuilder;
+
+use super::{
+ lexer::Lexer,
+ SyntaxKind::{self, *},
+ SyntaxNode,
};
-use std::iter::Peekable;
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-enum Scope {
- Root,
- Group,
- Options,
+#[derive(Clone)]
+pub struct Parse {
+ pub root: SyntaxNode,
+}
+
+#[derive(Debug, Clone, Copy)]
+struct ParserContext {
+ allow_environment: bool,
+ allow_comma: bool,
+}
+
+impl Default for ParserContext {
+ fn default() -> Self {
+ Self {
+ allow_environment: true,
+ allow_comma: true,
+ }
+ }
}
#[derive(Debug)]
-pub struct Parser<I: Iterator<Item = Token>> {
- tree: Ast<Node>,
- tokens: Peekable<I>,
+struct Parser<'a> {
+ lexer: Lexer<'a>,
+ builder: GreenNodeBuilder<'static, 'static>,
}
-impl<I: Iterator<Item = Token>> Parser<I> {
- pub fn new(tokens: I) -> Self {
+impl<'a> Parser<'a> {
+ pub fn new(text: &'a str) -> Self {
Self {
- tree: Ast::new(),
- tokens: tokens.peekable(),
+ lexer: Lexer::new(text),
+ builder: GreenNodeBuilder::new(),
}
}
- pub fn parse(mut self) -> Tree {
- let children = self.content(Scope::Root);
+ fn eat(&mut self) {
+ let (kind, text) = self.lexer.eat().unwrap();
+ self.builder.token(kind.into(), text);
+ }
- let range = if children.is_empty() {
- Range::new_simple(0, 0, 0, 0)
+ fn peek(&self) -> Option<SyntaxKind> {
+ self.lexer.peek()
+ }
+
+ fn expect(&mut self, kind: SyntaxKind) {
+ if self.peek() == Some(kind) {
+ self.eat();
+ self.trivia();
} else {
- let start = self.tree[children[0]].start();
- let end = self.tree[children[children.len() - 1]].end();
- Range::new(start, end)
- };
+ self.builder.token(MISSING.into(), "");
+ }
+ }
- let root = self.tree.add_node(Node::Root(Root { range }));
- self.connect(root, &children);
- Tree {
- inner: self.tree,
- root,
+ fn expect2(&mut self, kind1: SyntaxKind, kind2: SyntaxKind) {
+ if self
+ .peek()
+ .filter(|&kind| kind == kind1 || kind == kind2)
+ .is_some()
+ {
+ self.eat();
+ self.trivia();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
}
- fn content(&mut self, scope: Scope) -> Vec<AstNodeIndex> {
- let mut children = Vec::new();
- while let Some(ref token) = self.tokens.peek() {
- match token.kind {
- TokenKind::Word | TokenKind::BeginOptions => {
- children.push(self.text(scope));
- }
- TokenKind::Command => {
- children.push(self.command());
- }
- TokenKind::Comma => {
- children.push(self.comma());
- }
- TokenKind::Math => {
- children.push(self.math());
- }
- TokenKind::BeginGroup => {
- children.push(self.group(GroupKind::Group));
- }
- TokenKind::EndGroup => {
- if scope == Scope::Root {
- self.tokens.next();
- } else {
- return children;
- }
- }
- TokenKind::EndOptions => {
- if scope == Scope::Options {
- return children;
+ fn trivia(&mut self) {
+ while self
+ .peek()
+ .filter(|&kind| matches!(kind, WHITESPACE | COMMENT))
+ .is_some()
+ {
+ self.eat();
+ }
+ }
+
+ pub fn parse(mut self) -> Parse {
+ self.builder.start_node(ROOT.into());
+ self.preamble();
+ while self.peek().is_some() {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ let (green_node, interner) = self.builder.finish();
+ Parse {
+ root: SyntaxNode::new_root_with_resolver(green_node, interner.unwrap()),
+ }
+ }
+
+ fn content(&mut self, context: ParserContext) {
+ match self.peek().unwrap() {
+ WHITESPACE | COMMENT => self.eat(),
+ L_CURLY if context.allow_environment => self.curly_group(),
+ L_CURLY => self.curly_group_without_environments(),
+ L_BRACK | L_PAREN => self.mixed_group(),
+ R_CURLY | R_BRACK | R_PAREN => {
+ self.builder.start_node(ERROR.into());
+ self.eat();
+ self.builder.finish_node();
+ }
+ PARAMETER => self.eat(),
+ WORD | COMMA => self.text(context),
+ EQUALITY_SIGN => self.eat(),
+ DOLLAR => self.formula(),
+ GENERIC_COMMAND_NAME => self.generic_command(),
+ BEGIN_ENVIRONMENT_NAME if context.allow_environment => self.environment(),
+ BEGIN_ENVIRONMENT_NAME => self.generic_command(),
+ END_ENVIRONMENT_NAME => self.generic_command(),
+ BEGIN_EQUATION_NAME => self.equation(),
+ END_EQUATION_NAME => self.generic_command(),
+ MISSING | ERROR => self.eat(),
+ PART_NAME => self.part(),
+ CHAPTER_NAME => self.chapter(),
+ SECTION_NAME => self.section(),
+ SUBSECTION_NAME => self.subsection(),
+ SUBSUBSECTION_NAME => self.subsubsection(),
+ PARAGRAPH_NAME => self.paragraph(),
+ SUBPARAGRAPH_NAME => self.subparagraph(),
+ ENUM_ITEM_NAME => self.enum_item(),
+ CAPTION_NAME => self.caption(),
+ CITATION_NAME => self.citation(),
+ PACKAGE_INCLUDE_NAME => self.package_include(),
+ CLASS_INCLUDE_NAME => self.class_include(),
+ LATEX_INCLUDE_NAME => self.latex_include(),
+ BIBLATEX_INCLUDE_NAME => self.biblatex_include(),
+ BIBTEX_INCLUDE_NAME => self.bibtex_include(),
+ GRAPHICS_INCLUDE_NAME => self.graphics_include(),
+ SVG_INCLUDE_NAME => self.svg_include(),
+ INKSCAPE_INCLUDE_NAME => self.inkscape_include(),
+ VERBATIM_INCLUDE_NAME => self.verbatim_include(),
+ IMPORT_NAME => self.import(),
+ LABEL_DEFINITION_NAME => self.label_definition(),
+ LABEL_REFERENCE_NAME => self.label_reference(),
+ LABEL_REFERENCE_RANGE_NAME => self.label_reference_range(),
+ LABEL_NUMBER_NAME => self.label_number(),
+ COMMAND_DEFINITION_NAME => self.command_definition(),
+ MATH_OPERATOR_NAME => self.math_operator(),
+ GLOSSARY_ENTRY_DEFINITION_NAME => self.glossary_entry_definition(),
+ GLOSSARY_ENTRY_REFERENCE_NAME => self.glossary_entry_reference(),
+ ACRONYM_DEFINITION_NAME => self.acronym_definition(),
+ ACRONYM_DECLARATION_NAME => self.acronym_declaration(),
+ ACRONYM_REFERENCE_NAME => self.acronym_reference(),
+ THEOREM_DEFINITION_NAME => self.theorem_definition(),
+ COLOR_REFERENCE_NAME => self.color_reference(),
+ COLOR_DEFINITION_NAME => self.color_definition(),
+ COLOR_SET_DEFINITION_NAME => self.color_set_definition(),
+ TIKZ_LIBRARY_IMPORT_NAME => self.tikz_library_import(),
+ ENVIRONMENT_DEFINIITION_NAME => self.environment_definition(),
+ _ => unreachable!(),
+ }
+ }
+
+ fn text(&mut self, context: ParserContext) {
+ self.builder.start_node(TEXT.into());
+ self.eat();
+ while self
+ .peek()
+ .filter(|&kind| {
+ matches!(kind, WHITESPACE | COMMENT | WORD | COMMA)
+ && (context.allow_comma || kind != COMMA)
+ })
+ .is_some()
+ {
+ self.eat();
+ }
+ self.builder.finish_node();
+ }
+
+ fn group_with_token(
+ &mut self,
+ node_kind: SyntaxKind,
+ content_kind: SyntaxKind,
+ right_kind: SyntaxKind,
+ ) {
+ self.builder.start_node(node_kind.into());
+ self.eat();
+ self.trivia();
+ self.expect(content_kind);
+ self.expect(right_kind);
+ self.builder.finish_node();
+ }
+
+ fn curly_group(&mut self) {
+ self.builder.start_node(CURLY_GROUP.into());
+ self.eat();
+ while self
+ .peek()
+ .filter(|&kind| !matches!(kind, R_CURLY | END_ENVIRONMENT_NAME))
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.expect(R_CURLY);
+ self.builder.finish_node();
+ }
+
+ fn curly_group_without_environments(&mut self) {
+ self.builder.start_node(CURLY_GROUP.into());
+ self.eat();
+ while self
+ .peek()
+ .filter(|&kind| !matches!(kind, R_CURLY))
+ .is_some()
+ {
+ self.content(ParserContext {
+ allow_environment: false,
+ allow_comma: true,
+ });
+ }
+ self.expect(R_CURLY);
+ self.builder.finish_node();
+ }
+
+ fn curly_group_word(&mut self) {
+ self.group_with_token(CURLY_GROUP_WORD, WORD, R_CURLY);
+ }
+
+ fn curly_group_word_list(&mut self) {
+ self.builder.start_node(CURLY_GROUP_WORD_LIST.into());
+ self.eat();
+
+ while self
+ .peek()
+ .filter(|&kind| matches!(kind, WHITESPACE | COMMENT | WORD | COMMA))
+ .is_some()
+ {
+ self.eat();
+ }
+
+ self.expect(R_CURLY);
+ self.builder.finish_node();
+ }
+
+ fn curly_group_command(&mut self) {
+ self.group_with_token(CURLY_GROUP_COMMAND, GENERIC_COMMAND_NAME, R_CURLY);
+ }
+
+ fn brack_group(&mut self) {
+ self.builder.start_node(BRACK_GROUP.into());
+ self.eat();
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ R_CURLY
+ | R_BRACK
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | PARAGRAPH_NAME
+ | SUBPARAGRAPH_NAME
+ | ENUM_ITEM_NAME
+ | END_ENVIRONMENT_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.expect(R_BRACK);
+ self.builder.finish_node();
+ }
+
+ fn brack_group_word(&mut self) {
+ self.group_with_token(BRACK_GROUP_WORD, WORD, R_BRACK);
+ }
+
+ // fn paren_group(&mut self) {
+ // self.builder.start_node(PAREN_GROUP.into());
+ // self.eat();
+ // while self
+ // .peek()
+ // .filter(|&kind| {
+ // !matches!(
+ // kind,
+ // R_CURLY
+ // | R_BRACK
+ // | R_PAREN
+ // | PART_NAME
+ // | CHAPTER_NAME
+ // | SECTION_NAME
+ // | SUBSECTION_NAME
+ // | PARAGRAPH_NAME
+ // | SUBPARAGRAPH_NAME
+ // | ENUM_ITEM_NAME
+ // | END_ENVIRONMENT_NAME
+ // )
+ // })
+ // .is_some()
+ // {
+ // self.content();
+ // }
+ // self.expect(R_PAREN);
+ // self.builder.finish_node();
+ // }
+
+ fn mixed_group(&mut self) {
+ self.builder.start_node(MIXED_GROUP.into());
+ self.eat();
+ self.trivia();
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ R_CURLY
+ | R_BRACK
+ | R_PAREN
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | PARAGRAPH_NAME
+ | SUBPARAGRAPH_NAME
+ | ENUM_ITEM_NAME
+ | END_ENVIRONMENT_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.expect2(R_BRACK, R_PAREN);
+ self.builder.finish_node();
+ }
+
+ fn key(&mut self) {
+ self.builder.start_node(KEY.into());
+ self.eat();
+ while self
+ .peek()
+ .filter(|&kind| matches!(kind, WHITESPACE | COMMENT | WORD))
+ .is_some()
+ {
+ self.eat();
+ }
+ self.builder.finish_node();
+ }
+
+ fn value(&mut self) {
+ self.builder.start_node(VALUE.into());
+ self.content(ParserContext {
+ allow_environment: true,
+ allow_comma: false,
+ });
+ self.builder.finish_node();
+ }
+
+ fn key_value_pair(&mut self) {
+ self.builder.start_node(KEY_VALUE_PAIR.into());
+ self.key();
+ if self.peek() == Some(EQUALITY_SIGN) {
+ self.eat();
+ self.trivia();
+ if self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME | R_CURLY | R_BRACK | R_PAREN | COMMA
+ )
+ })
+ .is_some()
+ {
+ self.value();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn key_value_body(&mut self) {
+ self.builder.start_node(KEY_VALUE_BODY.into());
+ while let Some(kind) = self.peek() {
+ match kind {
+ WHITESPACE | COMMENT => self.eat(),
+ WORD => {
+ self.key_value_pair();
+ if self.peek() == Some(COMMA) {
+ self.eat();
} else {
- children.push(self.text(scope));
+ break;
}
}
+ _ => break,
}
}
- children
- }
-
- fn group(&mut self, kind: GroupKind) -> AstNodeIndex {
- let left = self.tokens.next().unwrap();
- let scope = match kind {
- GroupKind::Group => Scope::Group,
- GroupKind::Options => Scope::Options,
- };
-
- let children = self.content(scope);
- let right_kind = match kind {
- GroupKind::Group => TokenKind::EndGroup,
- GroupKind::Options => TokenKind::EndOptions,
- };
-
- let right = if self.next_of_kind(right_kind) {
- self.tokens.next()
- } else {
- None
- };
-
- let end = right
- .as_ref()
- .map(SyntaxNode::end)
- .or_else(|| children.last().map(|child| self.tree[*child].end()))
- .unwrap_or_else(|| left.end());
- let range = Range::new(left.start(), end);
-
- let node = self.tree.add_node(Node::Group(Group {
- range,
- left,
- kind,
- right,
- }));
- self.connect(node, &children);
- node
- }
-
- fn command(&mut self) -> AstNodeIndex {
- let name = self.tokens.next().unwrap();
- let mut children = Vec::new();
- while let Some(token) = self.tokens.peek() {
- match token.kind {
- TokenKind::BeginGroup => children.push(self.group(GroupKind::Group)),
- TokenKind::BeginOptions => children.push(self.group(GroupKind::Options)),
+ self.builder.finish_node();
+ }
+
+ fn group_key_value(&mut self, node_kind: SyntaxKind, right_kind: SyntaxKind) {
+ self.builder.start_node(node_kind.into());
+ self.eat();
+ self.trivia();
+ self.key_value_body();
+ self.expect(right_kind);
+ self.builder.finish_node();
+ }
+
+ fn curly_group_key_value(&mut self) {
+ self.group_key_value(CURLY_GROUP_KEY_VALUE, R_CURLY);
+ }
+
+ fn brack_group_key_value(&mut self) {
+ self.group_key_value(BRACK_GROUP_KEY_VALUE, R_BRACK);
+ }
+
+ fn formula(&mut self) {
+ self.builder.start_node(FORMULA.into());
+ self.eat();
+ self.trivia();
+ while self
+ .peek()
+ .filter(|&kind| !matches!(kind, R_CURLY | END_ENVIRONMENT_NAME | DOLLAR))
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.expect(DOLLAR);
+ self.builder.finish_node();
+ }
+
+ fn generic_command(&mut self) {
+ self.builder.start_node(GENERIC_COMMAND.into());
+ self.eat();
+ while let Some(kind) = self.peek() {
+ match kind {
+ WHITESPACE | COMMENT => self.eat(),
+ L_CURLY => self.curly_group(),
+ L_BRACK | L_PAREN => self.mixed_group(),
_ => break,
}
}
+ self.builder.finish_node();
+ }
+
+ fn equation(&mut self) {
+ self.builder.start_node(EQUATION.into());
+ self.eat();
+ while self
+ .peek()
+ .filter(|&kind| !matches!(kind, END_ENVIRONMENT_NAME | R_CURLY | END_EQUATION_NAME))
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.expect(END_EQUATION_NAME);
+ self.builder.finish_node();
+ }
- let end = children
- .last()
- .map(|child| self.tree[*child].end())
- .unwrap_or_else(|| name.end());
- let range = Range::new(name.start(), end);
+ fn begin(&mut self) {
+ self.builder.start_node(BEGIN.into());
+ self.eat();
+ self.trivia();
- let node = self.tree.add_node(Node::Command(Command { range, name }));
- self.connect(node, &children);
- node
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.peek() == Some(L_BRACK) {
+ self.brack_group();
+ }
+ self.builder.finish_node();
}
- fn text(&mut self, scope: Scope) -> AstNodeIndex {
- let mut words = Vec::new();
- while let Some(ref token) = self.tokens.peek() {
- let kind = token.kind;
- let opts = kind == TokenKind::EndOptions && scope != Scope::Options;
- if kind == TokenKind::Word || kind == TokenKind::BeginOptions || opts {
- words.push(self.tokens.next().unwrap());
- } else {
- break;
- }
+ fn end(&mut self) {
+ self.builder.start_node(END.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
- let range = Range::new(words[0].start(), words[words.len() - 1].end());
- self.tree.add_node(Node::Text(Text { range, words }))
+
+ self.builder.finish_node();
}
- fn comma(&mut self) -> AstNodeIndex {
- let token = self.tokens.next().unwrap();
- let range = token.range();
- self.tree.add_node(Node::Comma(Comma { range, token }))
+ fn environment(&mut self) {
+ self.builder.start_node(ENVIRONMENT.into());
+ self.begin();
+
+ while self
+ .peek()
+ .filter(|&kind| kind != END_ENVIRONMENT_NAME)
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+
+ if self.peek() == Some(END_ENVIRONMENT_NAME) {
+ self.end();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ self.builder.finish_node();
}
- fn math(&mut self) -> AstNodeIndex {
- let token = self.tokens.next().unwrap();
- let range = token.range();
- self.tree.add_node(Node::Math(Math { range, token }))
+ fn preamble(&mut self) {
+ self.builder.start_node(PREAMBLE.into());
+ while self
+ .peek()
+ .filter(|&kind| kind != END_ENVIRONMENT_NAME)
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
}
- fn connect(&mut self, parent: AstNodeIndex, children: &[AstNodeIndex]) {
- for child in children {
- self.tree.add_edge(parent, *child);
+ fn part(&mut self) {
+ self.builder.start_node(PART.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
}
+
+ while self
+ .peek()
+ .filter(|&kind| !matches!(kind, END_ENVIRONMENT_NAME | R_CURLY | PART_NAME))
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
}
- fn next_of_kind(&mut self, kind: TokenKind) -> bool {
- self.tokens
+ fn chapter(&mut self) {
+ self.builder.start_node(CHAPTER.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ while self
.peek()
- .filter(|token| token.kind == kind)
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME | R_CURLY | PART_NAME | CHAPTER_NAME
+ )
+ })
.is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn section(&mut self) {
+ self.builder.start_node(SECTION.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME | R_CURLY | PART_NAME | CHAPTER_NAME | SECTION_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn subsection(&mut self) {
+ self.builder.start_node(SUBSECTION.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME
+ | R_CURLY
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn subsubsection(&mut self) {
+ self.builder.start_node(SUBSUBSECTION.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME
+ | R_CURLY
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | SUBSUBSECTION_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn paragraph(&mut self) {
+ self.builder.start_node(PARAGRAPH.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME
+ | R_CURLY
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | SUBSUBSECTION_NAME
+ | PARAGRAPH_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn subparagraph(&mut self) {
+ self.builder.start_node(SUBPARAGRAPH.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME
+ | R_CURLY
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | SUBSUBSECTION_NAME
+ | PARAGRAPH_NAME
+ | SUBPARAGRAPH_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn enum_item(&mut self) {
+ self.builder.start_node(ENUM_ITEM.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_BRACK) {
+ self.brack_group();
+ }
+
+ while self
+ .peek()
+ .filter(|&kind| {
+ !matches!(
+ kind,
+ END_ENVIRONMENT_NAME
+ | R_CURLY
+ | PART_NAME
+ | CHAPTER_NAME
+ | SECTION_NAME
+ | SUBSECTION_NAME
+ | SUBSUBSECTION_NAME
+ | PARAGRAPH_NAME
+ | SUBPARAGRAPH_NAME
+ | ENUM_ITEM_NAME
+ )
+ })
+ .is_some()
+ {
+ self.content(ParserContext::default());
+ }
+ self.builder.finish_node();
+ }
+
+ fn caption(&mut self) {
+ self.builder.start_node(CAPTION.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(L_BRACK) {
+ self.brack_group();
+ }
+
+ if self.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn citation(&mut self) {
+ self.builder.start_node(CITATION.into());
+ self.eat();
+ self.trivia();
+ for _ in 0..2 {
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group();
+ }
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word_list();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn generic_include(&mut self, kind: SyntaxKind, options: bool) {
+ self.builder.start_node(kind.into());
+ self.eat();
+ self.trivia();
+ if options && self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_key_value();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word_list();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn package_include(&mut self) {
+ self.generic_include(PACKAGE_INCLUDE, true);
+ }
+
+ fn class_include(&mut self) {
+ self.generic_include(CLASS_INCLUDE, true);
+ }
+
+ fn latex_include(&mut self) {
+ self.generic_include(LATEX_INCLUDE, false);
+ }
+
+ fn biblatex_include(&mut self) {
+ self.generic_include(BIBLATEX_INCLUDE, true);
+ }
+
+ fn bibtex_include(&mut self) {
+ self.generic_include(BIBTEX_INCLUDE, false);
+ }
+
+ fn graphics_include(&mut self) {
+ self.generic_include(GRAPHICS_INCLUDE, true);
+ }
+
+ fn svg_include(&mut self) {
+ self.generic_include(SVG_INCLUDE, true);
+ }
+
+ fn inkscape_include(&mut self) {
+ self.generic_include(INKSCAPE_INCLUDE, true);
+ }
+
+ fn verbatim_include(&mut self) {
+ self.generic_include(VERBATIM_INCLUDE, false);
+ }
+
+ fn import(&mut self) {
+ self.builder.start_node(IMPORT.into());
+ self.eat();
+ self.trivia();
+
+ for _ in 0..2 {
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn label_definition(&mut self) {
+ self.builder.start_node(LABEL_DEFINITION.into());
+ self.eat();
+ self.trivia();
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ self.builder.finish_node();
+ }
+
+ fn label_reference(&mut self) {
+ self.builder.start_node(LABEL_REFERENCE.into());
+ self.eat();
+ self.trivia();
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word_list();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ self.builder.finish_node();
+ }
+
+ fn label_reference_range(&mut self) {
+ self.builder.start_node(LABEL_REFERENCE_RANGE.into());
+ self.eat();
+ self.trivia();
+
+ for _ in 0..2 {
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn label_number(&mut self) {
+ self.builder.start_node(LABEL_NUMBER.into());
+ self.eat();
+ self.trivia();
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group();
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn command_definition(&mut self) {
+ self.builder.start_node(COMMAND_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_command();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_word();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn math_operator(&mut self) {
+ self.builder.start_node(MATH_OPERATOR.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_command();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn glossary_entry_definition(&mut self) {
+ self.builder.start_node(GLOSSARY_ENTRY_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_key_value();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn glossary_entry_reference(&mut self) {
+ self.builder.start_node(GLOSSARY_ENTRY_REFERENCE.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_key_value();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn acronym_definition(&mut self) {
+ self.builder.start_node(ACRONYM_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_key_value();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ for _ in 0..2 {
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn acronym_declaration(&mut self) {
+ self.builder.start_node(ACRONYM_DECLARATION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_key_value();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn acronym_reference(&mut self) {
+ self.builder.start_node(ACRONYM_REFERENCE.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_key_value();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn theorem_definition(&mut self) {
+ self.builder.start_node(THEOREM_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_word();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_word();
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn color_reference(&mut self) {
+ self.builder.start_node(COLOR_REFERENCE.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn color_definition(&mut self) {
+ self.builder.start_node(COLOR_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn color_set_definition(&mut self) {
+ self.builder.start_node(COLOR_SET_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_word();
+ }
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word_list();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ for _ in 0..3 {
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn tikz_library_import(&mut self) {
+ self.builder.start_node(TIKZ_LIBRARY_IMPORT.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word_list();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn environment_definition(&mut self) {
+ self.builder.start_node(ENVIRONMENT_DEFINITION.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_word();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+
+ if self.lexer.peek() == Some(L_BRACK) {
+ self.brack_group_word();
+ }
+
+ for _ in 0..2 {
+ if self.lexer.peek() == Some(L_CURLY) {
+ self.curly_group_without_environments();
+ } else {
+ self.builder.token(MISSING.into(), "");
+ }
+ }
+
+ self.builder.finish_node();
+ }
+}
+
+pub fn parse(text: &str) -> Parse {
+ Parser::new(text).parse()
+}
+
+#[cfg(test)]
+mod tests {
+ use insta::assert_debug_snapshot;
+
+ use super::*;
+
+ fn setup(text: &str) -> SyntaxNode {
+ parse(&text.trim().replace("\r", "")).root
+ }
+
+ #[test]
+ fn test_empty() {
+ assert_debug_snapshot!(setup(r#""#));
+ }
+
+ #[test]
+ fn test_hello_world() {
+ assert_debug_snapshot!(setup(r#"Hello World!"#));
+ }
+
+ #[test]
+ fn test_generic_command_empty() {
+ assert_debug_snapshot!(setup(r#"\foo"#));
+ }
+
+ #[test]
+ fn test_generic_command_escape() {
+ assert_debug_snapshot!(setup(r#"\#"#));
+ }
+
+ #[test]
+ fn test_generic_command_args() {
+ assert_debug_snapshot!(setup(r#"\foo{bar}[qux]"#));
+ }
+
+ #[test]
+ fn test_inline() {
+ assert_debug_snapshot!(setup(r#"$x \in [0, \infty)$"#));
+ }
+
+ #[test]
+ fn test_inline_double_dollar() {
+ assert_debug_snapshot!(setup(r#"$$x \in [0, \infty)$$"#));
+ }
+
+ #[test]
+ fn test_brace_group_simple() {
+ assert_debug_snapshot!(setup(r#"{hello world}"#));
+ }
+
+ #[test]
+ fn test_brace_group_missing_end() {
+ assert_debug_snapshot!(setup(r#"{hello world"#));
+ }
+
+ #[test]
+ fn test_unmatched_braces() {
+ assert_debug_snapshot!(setup(r#"}{"#));
+ }
+
+ #[test]
+ fn test_unmatched_brackets() {
+ assert_debug_snapshot!(setup(r#"]["#));
+ }
+
+ #[test]
+ fn test_unmatched_brackets_with_group() {
+ assert_debug_snapshot!(setup(r#"{][}"#));
+ }
+
+ #[test]
+ fn test_escaped_brackets() {
+ assert_debug_snapshot!(setup(r#"{[}{]}"#));
+ }
+
+ #[test]
+ fn test_parameter() {
+ assert_debug_snapshot!(setup(r#"#1"#));
+ }
+
+ #[test]
+ fn test_parameter_error() {
+ assert_debug_snapshot!(setup(r#"#"#));
+ }
+
+ #[test]
+ fn test_environment_simple() {
+ assert_debug_snapshot!(setup(r#"\begin{foo} Hello World \end{bar}"#));
+ }
+
+ #[test]
+ fn test_environment_nested() {
+ assert_debug_snapshot!(setup(r#"\begin{foo} \begin{qux} \end{baz} \end{bar}"#));
+ }
+
+ #[test]
+ fn test_environment_nested_missing_braces() {
+ assert_debug_snapshot!(setup(
+ r#"\begin{foo \begin{qux Hello World \end{baz} \end{bar"#
+ ));
+ }
+
+ #[test]
+ fn test_structure_siblings() {
+ assert_debug_snapshot!(setup(r#"\section{Foo} Foo \section{Bar} Bar"#));
+ }
+
+ #[test]
+ fn test_structure_nested() {
+ assert_debug_snapshot!(setup(
+ r#"\part{1}\chapter{2}\section{3}\subsection{4}\subsubsection{5}\paragraph{6}\subparagraph{7}"#
+ ));
+ }
+
+ #[test]
+ fn test_structure_enum_item() {
+ assert_debug_snapshot!(setup(
+ r#"\begin{enumerate} \item 1 \item[2] 2 \item 3 \end{enumerate}"#
+ ));
+ }
+
+ #[test]
+ fn test_structure_invalid_nesting() {
+ assert_debug_snapshot!(setup(r#"\section{Foo} \chapter{Bar}"#));
+ }
+
+ #[test]
+ fn test_equation() {
+ assert_debug_snapshot!(setup(r#"\[ foo bar \]"#));
+ }
+
+ #[test]
+ fn test_equation_missing_end() {
+ assert_debug_snapshot!(setup(r#"\begin{a} \[ foo bar \end{b}"#));
+ }
+
+ #[test]
+ fn test_equation_missing_begin() {
+ assert_debug_snapshot!(setup(r#"\begin{a} foo bar \] \end{b}"#));
+ }
+
+ #[test]
+ fn test_caption_minimal() {
+ assert_debug_snapshot!(setup(r#"\caption{Foo \Bar Baz}"#));
+ }
+
+ #[test]
+ fn test_caption_minimal_error() {
+ assert_debug_snapshot!(setup(r#"\caption{Foo \Bar Baz"#));
+ }
+
+ #[test]
+ fn test_caption() {
+ assert_debug_snapshot!(setup(r#"\caption[qux]{Foo \Bar Baz}"#));
+ }
+
+ #[test]
+ fn test_caption_error() {
+ assert_debug_snapshot!(setup(r#"\caption[qux]{Foo \Bar Baz"#));
+ }
+
+ #[test]
+ fn test_caption_figure() {
+ assert_debug_snapshot!(setup(r#"\begin{figure}\caption{Foo}\end{figure}"#));
+ }
+
+ #[test]
+ fn test_citation_empty() {
+ assert_debug_snapshot!(setup(r#"\cite{}"#));
+ }
+
+ #[test]
+ fn test_citation_simple() {
+ assert_debug_snapshot!(setup(r#"\cite{foo}"#));
+ }
+
+ #[test]
+ fn test_citation_multiple_keys() {
+ assert_debug_snapshot!(setup(r#"\cite{foo, bar}"#));
+ }
+
+ #[test]
+ fn test_citation_star() {
+ assert_debug_snapshot!(setup(r#"\nocite{*}"#));
+ }
+
+ #[test]
+ fn test_citation_prenote() {
+ assert_debug_snapshot!(setup(r#"\cite[foo]{bar}"#));
+ }
+
+ #[test]
+ fn test_citation_prenote_postnote() {
+ assert_debug_snapshot!(setup(r#"\cite[foo][bar]{baz}"#));
+ }
+
+ #[test]
+ fn test_citation_missing_brace() {
+ assert_debug_snapshot!(setup(r#"\cite{foo"#));
+ }
+
+ #[test]
+ fn test_citation_redundant_comma() {
+ assert_debug_snapshot!(setup(r#"\cite{,foo,}"#));
+ }
+
+ #[test]
+ fn test_package_include_empty() {
+ assert_debug_snapshot!(setup(r#"\usepackage{}"#));
+ }
+
+ #[test]
+ fn test_package_include_simple() {
+ assert_debug_snapshot!(setup(r#"\usepackage{amsmath}"#));
+ }
+
+ #[test]
+ fn test_package_include_multiple() {
+ assert_debug_snapshot!(setup(r#"\usepackage{amsmath, lipsum}"#));
+ }
+
+ #[test]
+ fn test_package_include_options() {
+ assert_debug_snapshot!(setup(r#"\usepackage[foo = bar, baz, qux]{amsmath}"#));
+ }
+
+ #[test]
+ fn test_class_include_empty() {
+ assert_debug_snapshot!(setup(r#"\documentclass{}"#));
+ }
+
+ #[test]
+ fn test_class_include_simple() {
+ assert_debug_snapshot!(setup(r#"\documentclass{article}"#));
+ }
+
+ #[test]
+ fn test_class_include_options() {
+ assert_debug_snapshot!(setup(r#"\documentclass[foo = bar, baz, qux]{article}"#));
+ }
+
+ #[test]
+ fn test_latex_include_simple() {
+ assert_debug_snapshot!(setup(r#"\include{foo/bar}"#));
+ }
+
+ #[test]
+ fn test_latex_input_simple() {
+ assert_debug_snapshot!(setup(r#"\input{foo/bar.tex}"#));
+ }
+
+ #[test]
+ fn test_biblatex_include_simple() {
+ assert_debug_snapshot!(setup(r#"\addbibresource{foo/bar.bib}"#));
+ }
+
+ #[test]
+ fn test_biblatex_include_options() {
+ assert_debug_snapshot!(setup(r#"\addbibresource[foo=bar, baz]{foo/bar.bib}"#));
+ }
+
+ #[test]
+ fn test_bibtex_include_simple() {
+ assert_debug_snapshot!(setup(r#"\bibliography{foo/bar}"#));
+ }
+
+ #[test]
+ fn test_graphics_include_simple() {
+ assert_debug_snapshot!(setup(r#"\includegraphics{foo/bar.pdf}"#));
+ }
+
+ #[test]
+ fn test_graphics_include_options() {
+ assert_debug_snapshot!(setup(r#"\includegraphics[scale=.5]{foo/bar.pdf}"#));
+ }
+
+ #[test]
+ fn test_svg_include_simple() {
+ assert_debug_snapshot!(setup(r#"\includesvg{foo/bar.svg}"#));
+ }
+
+ #[test]
+ fn test_svg_include_options() {
+ assert_debug_snapshot!(setup(r#"\includesvg[scale=.5]{foo/bar.svg}"#));
+ }
+
+ #[test]
+ fn test_inkscape_include_simple() {
+ assert_debug_snapshot!(setup(r#"\includesvg{foo/bar}"#));
+ }
+
+ #[test]
+ fn test_inkscape_include_options() {
+ assert_debug_snapshot!(setup(r#"\includesvg[scale=.5]{foo/bar}"#));
+ }
+
+ #[test]
+ fn test_verbatim_include_simple() {
+ assert_debug_snapshot!(setup(r#"\verbatiminput{foo/bar.txt}"#));
+ }
+
+ #[test]
+ fn test_import_simple() {
+ assert_debug_snapshot!(setup(r#"\import{foo}{bar}"#));
+ }
+
+ #[test]
+ fn test_import_incomplete() {
+ assert_debug_snapshot!(setup(r#"\import{foo"#));
+ }
+
+ #[test]
+ fn test_label_definition_simple() {
+ assert_debug_snapshot!(setup(r#"\label{foo}"#));
+ }
+
+ #[test]
+ fn test_label_reference_simple() {
+ assert_debug_snapshot!(setup(r#"\ref{foo}"#));
+ }
+
+ #[test]
+ fn test_label_reference_multiple() {
+ assert_debug_snapshot!(setup(r#"\ref{foo, bar}"#));
+ }
+
+ #[test]
+ fn test_equation_label_reference_simple() {
+ assert_debug_snapshot!(setup(r#"\eqref{foo}"#));
+ }
+
+ #[test]
+ fn test_label_reference_range_simple() {
+ assert_debug_snapshot!(setup(r#"\crefrange{foo}{bar}"#));
+ }
+
+ #[test]
+ fn test_label_reference_range_incomplete() {
+ assert_debug_snapshot!(setup(r#"\crefrange{foo}"#));
+ }
+
+ #[test]
+ fn test_label_reference_range_error() {
+ assert_debug_snapshot!(setup(r#"\crefrange{foo{bar}"#));
+ }
+
+ #[test]
+ fn test_label_number() {
+ assert_debug_snapshot!(setup(r#"\newlabel{foo}{{1.1}}"#));
+ }
+
+ #[test]
+ fn test_command_definition_simple() {
+ assert_debug_snapshot!(setup(r#"\newcommand[1]{\id}{#1}"#));
+ }
+
+ #[test]
+ fn test_command_definition_no_argc() {
+ assert_debug_snapshot!(setup(r#"\newcommand{\foo}{foo}"#));
+ }
+
+ #[test]
+ fn test_command_definition_no_impl() {
+ assert_debug_snapshot!(setup(r#"\newcommand{\foo}"#));
+ }
+
+ #[test]
+ fn test_command_definition_no_impl_error() {
+ assert_debug_snapshot!(setup(r#"\newcommand{\foo"#));
+ }
+
+ #[test]
+ fn test_math_operator_simple() {
+ assert_debug_snapshot!(setup(r#"\DeclareMathOperator{\foo}{foo}"#));
+ }
+
+ #[test]
+ fn test_math_operator_no_impl() {
+ assert_debug_snapshot!(setup(r#"\DeclareMathOperator{\foo}"#));
+ }
+
+ #[test]
+ fn test_glossary_entry_definition_simple() {
+ assert_debug_snapshot!(setup(r#"\newglossaryentry{foo}{bar = baz, qux,}"#));
+ }
+
+ #[test]
+ fn test_glossary_entry_reference_simple() {
+ assert_debug_snapshot!(setup(r#"\gls{foo}"#));
+ }
+
+ #[test]
+ fn test_glossary_entry_reference_options() {
+ assert_debug_snapshot!(setup(r#"\gls[foo = bar, qux]{baz}"#));
+ }
+
+ #[test]
+ fn test_acroynm_definition_simple() {
+ assert_debug_snapshot!(setup(r#"\newacronym{fpsLabel}{FPS}{Frame per Second}"#));
+ }
+
+ #[test]
+ fn test_acroynm_definition_options() {
+ assert_debug_snapshot!(setup(
+ r#"\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}"#
+ ));
+ }
+
+ #[test]
+ fn test_acroynm_reference_simple() {
+ assert_debug_snapshot!(setup(r#"\acrshort{fpsLabel}"#));
+ }
+
+ #[test]
+ fn test_acroynm_reference_options() {
+ assert_debug_snapshot!(setup(r#"\acrshort[foo=bar,baz]{fpsLabel}"#));
+ }
+
+ #[test]
+ fn test_theorem_definition_only_name() {
+ assert_debug_snapshot!(setup(r#"\newtheorem{foo}"#));
+ }
+
+ #[test]
+ fn test_theorem_definition_name_with_description() {
+ assert_debug_snapshot!(setup(r#"\newtheorem{foo}{Foo}"#));
+ }
+
+ #[test]
+ fn test_theorem_definition_name_with_description_and_counter() {
+ assert_debug_snapshot!(setup(r#"\newtheorem{foo}[bar]{Foo}"#));
+ }
+
+ #[test]
+ fn test_theorem_definition_name_with_counter() {
+ assert_debug_snapshot!(setup(r#"\newtheorem{foo}[bar]"#));
+ }
+
+ #[test]
+ fn test_theorem_definition_full() {
+ assert_debug_snapshot!(setup(r#"\newtheorem{foo}[bar]{Foo}[baz]"#));
+ }
+
+ #[test]
+ fn test_color_reference_simple() {
+ assert_debug_snapshot!(setup(r#"\color{black}"#));
+ }
+
+ #[test]
+ fn test_color_definition_simple() {
+ assert_debug_snapshot!(setup(r#"\definecolor{foo}{rgb}{255,168,0}"#));
+ }
+
+ #[test]
+ fn test_color_set_definition_simple() {
+ assert_debug_snapshot!(setup(r#"\definecolorset[ty]{rgb,HTML}{foo}{bar}{baz}"#));
+ }
+
+ #[test]
+ fn test_color_set_definition_error1() {
+ assert_debug_snapshot!(setup(r#"\definecolorset[ty]{rgb,HTML}{foo}{bar}"#));
+ }
+
+ #[test]
+ fn test_color_set_definition_error2() {
+ assert_debug_snapshot!(setup(r#"\definecolorset{rgb,HTML}{foo}"#));
+ }
+
+ #[test]
+ fn test_color_set_definition_error3() {
+ assert_debug_snapshot!(setup(r#"\definecolorset{rgb,HTML}"#));
+ }
+
+ #[test]
+ fn test_color_set_definition_error4() {
+ assert_debug_snapshot!(setup(r#"\definecolorset"#));
+ }
+
+ #[test]
+ fn test_pgf_library_import_simple() {
+ assert_debug_snapshot!(setup(r#"\usepgflibrary{foo}"#));
+ }
+
+ #[test]
+ fn test_tikz_library_import_simple() {
+ assert_debug_snapshot!(setup(r#"\usetikzlibrary{foo}"#));
+ }
+
+ #[test]
+ fn test_environment_definition() {
+ assert_debug_snapshot!(setup(r#"\newenvironment{bar}[1]{\begin{foo}}{\end{foo}}"#));
+ }
+
+ #[test]
+ fn test_acronym_declaration() {
+ assert_debug_snapshot!(setup(
+ r#"\DeclareAcronym{eg}{short = e.g,long = for example,tag = abbrev}"#
+ ));
}
}
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_parameter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_parameter.snap
new file mode 100644
index 0000000000..9cff735e99
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_parameter.snap
@@ -0,0 +1,47 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"\\newcommand{\\id}[1]{#1}\"#)"
+
+---
+[
+ (
+ COMMAND_DEFINITION_NAME,
+ "\\newcommand",
+ ),
+ (
+ L_CURLY,
+ "{",
+ ),
+ (
+ GENERIC_COMMAND_NAME,
+ "\\id",
+ ),
+ (
+ R_CURLY,
+ "}",
+ ),
+ (
+ L_BRACK,
+ "[",
+ ),
+ (
+ WORD,
+ "1",
+ ),
+ (
+ R_BRACK,
+ "]",
+ ),
+ (
+ L_CURLY,
+ "{",
+ ),
+ (
+ PARAMETER,
+ "#1",
+ ),
+ (
+ R_CURLY,
+ "}",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_star.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_star.snap
new file mode 100644
index 0000000000..41310edaa1
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__command_with_star.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"\\section*{Foo}\"#)"
+
+---
+[
+ (
+ SECTION_NAME,
+ "\\section*",
+ ),
+ (
+ L_CURLY,
+ "{",
+ ),
+ (
+ WORD,
+ "Foo",
+ ),
+ (
+ R_CURLY,
+ "}",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__comment.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__comment.snap
new file mode 100644
index 0000000000..2186c957c5
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__comment.snap
@@ -0,0 +1,35 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(\"hello %world\\r\\ntest %test\")"
+
+---
+[
+ (
+ WORD,
+ "hello",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ COMMENT,
+ "%world",
+ ),
+ (
+ WHITESPACE,
+ "\r\n",
+ ),
+ (
+ WORD,
+ "test",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ COMMENT,
+ "%test",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__delimiters.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__delimiters.snap
new file mode 100644
index 0000000000..36bec0a276
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__delimiters.snap
@@ -0,0 +1,79 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"{foo} (bar) [baz, qux = foo-bar]\"#)"
+
+---
+[
+ (
+ L_CURLY,
+ "{",
+ ),
+ (
+ WORD,
+ "foo",
+ ),
+ (
+ R_CURLY,
+ "}",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ L_PAREN,
+ "(",
+ ),
+ (
+ WORD,
+ "bar",
+ ),
+ (
+ R_PAREN,
+ ")",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ L_BRACK,
+ "[",
+ ),
+ (
+ WORD,
+ "baz",
+ ),
+ (
+ COMMA,
+ ",",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ WORD,
+ "qux",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ EQUALITY_SIGN,
+ "=",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ WORD,
+ "foo-bar",
+ ),
+ (
+ R_BRACK,
+ "]",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__empty.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__empty.snap
new file mode 100644
index 0000000000..61735b5087
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__empty.snap
@@ -0,0 +1,6 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"\"#)"
+
+---
+[]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__escape_sequence.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__escape_sequence.snap
new file mode 100644
index 0000000000..4dbc1bb8f5
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__escape_sequence.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"\\% hello\"#)"
+
+---
+[
+ (
+ GENERIC_COMMAND_NAME,
+ "\\%",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ WORD,
+ "hello",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__formula.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__formula.snap
new file mode 100644
index 0000000000..3fb7079384
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__formula.snap
@@ -0,0 +1,55 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"$ f(x) = y $$\"#)"
+
+---
+[
+ (
+ DOLLAR,
+ "$",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ WORD,
+ "f",
+ ),
+ (
+ L_PAREN,
+ "(",
+ ),
+ (
+ WORD,
+ "x",
+ ),
+ (
+ R_PAREN,
+ ")",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ EQUALITY_SIGN,
+ "=",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ WORD,
+ "y",
+ ),
+ (
+ WHITESPACE,
+ " ",
+ ),
+ (
+ DOLLAR,
+ "$$",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__invalid_parameter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__invalid_parameter.snap
new file mode 100644
index 0000000000..adadfcf0ef
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__lexer__tests__invalid_parameter.snap
@@ -0,0 +1,11 @@
+---
+source: src/syntax/latex/lexer.rs
+expression: "verify(r#\"#\"#)"
+
+---
+[
+ (
+ PARAMETER,
+ "#",
+ ),
+]
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap
new file mode 100644
index 0000000000..dfd05750d3
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap
@@ -0,0 +1,49 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\DeclareAcronym{eg}{short = e.g,long = for example,tag = abbrev}\"#)"
+
+---
+ROOT@0..64
+ PREAMBLE@0..64
+ ACRONYM_DECLARATION@0..64
+ ACRONYM_DECLARATION_NAME@0..15 "\\DeclareAcronym"
+ CURLY_GROUP_WORD@15..19
+ L_CURLY@15..16 "{"
+ WORD@16..18 "eg"
+ R_CURLY@18..19 "}"
+ CURLY_GROUP_KEY_VALUE@19..64
+ L_CURLY@19..20 "{"
+ KEY_VALUE_BODY@20..63
+ KEY_VALUE_PAIR@20..31
+ KEY@20..26
+ WORD@20..25 "short"
+ WHITESPACE@25..26 " "
+ EQUALITY_SIGN@26..27 "="
+ WHITESPACE@27..28 " "
+ VALUE@28..31
+ TEXT@28..31
+ WORD@28..31 "e.g"
+ COMMA@31..32 ","
+ KEY_VALUE_PAIR@32..50
+ KEY@32..37
+ WORD@32..36 "long"
+ WHITESPACE@36..37 " "
+ EQUALITY_SIGN@37..38 "="
+ WHITESPACE@38..39 " "
+ VALUE@39..50
+ TEXT@39..50
+ WORD@39..42 "for"
+ WHITESPACE@42..43 " "
+ WORD@43..50 "example"
+ COMMA@50..51 ","
+ KEY_VALUE_PAIR@51..63
+ KEY@51..55
+ WORD@51..54 "tag"
+ WHITESPACE@54..55 " "
+ EQUALITY_SIGN@55..56 "="
+ WHITESPACE@56..57 " "
+ VALUE@57..63
+ TEXT@57..63
+ WORD@57..63 "abbrev"
+ R_CURLY@63..64 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap
new file mode 100644
index 0000000000..1838e80f9a
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap
@@ -0,0 +1,46 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newacronym[longplural={Frames per Second}]{fpsLabel}{FPS}{Frame per Second}\"#)"
+
+---
+ROOT@0..76
+ PREAMBLE@0..76
+ ACRONYM_DEFINITION@0..76
+ ACRONYM_DEFINITION_NAME@0..11 "\\newacronym"
+ BRACK_GROUP_KEY_VALUE@11..43
+ L_BRACK@11..12 "["
+ KEY_VALUE_BODY@12..42
+ KEY_VALUE_PAIR@12..42
+ KEY@12..22
+ WORD@12..22 "longplural"
+ EQUALITY_SIGN@22..23 "="
+ VALUE@23..42
+ CURLY_GROUP@23..42
+ L_CURLY@23..24 "{"
+ TEXT@24..41
+ WORD@24..30 "Frames"
+ WHITESPACE@30..31 " "
+ WORD@31..34 "per"
+ WHITESPACE@34..35 " "
+ WORD@35..41 "Second"
+ R_CURLY@41..42 "}"
+ R_BRACK@42..43 "]"
+ CURLY_GROUP_WORD@43..53
+ L_CURLY@43..44 "{"
+ WORD@44..52 "fpsLabel"
+ R_CURLY@52..53 "}"
+ CURLY_GROUP@53..58
+ L_CURLY@53..54 "{"
+ TEXT@54..57
+ WORD@54..57 "FPS"
+ R_CURLY@57..58 "}"
+ CURLY_GROUP@58..76
+ L_CURLY@58..59 "{"
+ TEXT@59..75
+ WORD@59..64 "Frame"
+ WHITESPACE@64..65 " "
+ WORD@65..68 "per"
+ WHITESPACE@68..69 " "
+ WORD@69..75 "Second"
+ R_CURLY@75..76 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap
new file mode 100644
index 0000000000..1d32bed249
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap
@@ -0,0 +1,28 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newacronym{fpsLabel}{FPS}{Frame per Second}\"#)"
+
+---
+ROOT@0..44
+ PREAMBLE@0..44
+ ACRONYM_DEFINITION@0..44
+ ACRONYM_DEFINITION_NAME@0..11 "\\newacronym"
+ CURLY_GROUP_WORD@11..21
+ L_CURLY@11..12 "{"
+ WORD@12..20 "fpsLabel"
+ R_CURLY@20..21 "}"
+ CURLY_GROUP@21..26
+ L_CURLY@21..22 "{"
+ TEXT@22..25
+ WORD@22..25 "FPS"
+ R_CURLY@25..26 "}"
+ CURLY_GROUP@26..44
+ L_CURLY@26..27 "{"
+ TEXT@27..43
+ WORD@27..32 "Frame"
+ WHITESPACE@32..33 " "
+ WORD@33..36 "per"
+ WHITESPACE@36..37 " "
+ WORD@37..43 "Second"
+ R_CURLY@43..44 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap
new file mode 100644
index 0000000000..ce5b85c1cf
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap
@@ -0,0 +1,29 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\acrshort[foo=bar,baz]{fpsLabel}\"#)"
+
+---
+ROOT@0..32
+ PREAMBLE@0..32
+ ACRONYM_REFERENCE@0..32
+ ACRONYM_REFERENCE_NAME@0..9 "\\acrshort"
+ BRACK_GROUP_KEY_VALUE@9..22
+ L_BRACK@9..10 "["
+ KEY_VALUE_BODY@10..21
+ KEY_VALUE_PAIR@10..17
+ KEY@10..13
+ WORD@10..13 "foo"
+ EQUALITY_SIGN@13..14 "="
+ VALUE@14..17
+ TEXT@14..17
+ WORD@14..17 "bar"
+ COMMA@17..18 ","
+ KEY_VALUE_PAIR@18..21
+ KEY@18..21
+ WORD@18..21 "baz"
+ R_BRACK@21..22 "]"
+ CURLY_GROUP_WORD@22..32
+ L_CURLY@22..23 "{"
+ WORD@23..31 "fpsLabel"
+ R_CURLY@31..32 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap
new file mode 100644
index 0000000000..5df8059f1b
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\acrshort{fpsLabel}\"#)"
+
+---
+ROOT@0..19
+ PREAMBLE@0..19
+ ACRONYM_REFERENCE@0..19
+ ACRONYM_REFERENCE_NAME@0..9 "\\acrshort"
+ CURLY_GROUP_WORD@9..19
+ L_CURLY@9..10 "{"
+ WORD@10..18 "fpsLabel"
+ R_CURLY@18..19 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap
new file mode 100644
index 0000000000..c910699363
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap
@@ -0,0 +1,30 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\addbibresource[foo=bar, baz]{foo/bar.bib}\"#)"
+
+---
+ROOT@0..42
+ PREAMBLE@0..42
+ BIBLATEX_INCLUDE@0..42
+ BIBLATEX_INCLUDE_NAME@0..15 "\\addbibresource"
+ BRACK_GROUP_KEY_VALUE@15..29
+ L_BRACK@15..16 "["
+ KEY_VALUE_BODY@16..28
+ KEY_VALUE_PAIR@16..23
+ KEY@16..19
+ WORD@16..19 "foo"
+ EQUALITY_SIGN@19..20 "="
+ VALUE@20..23
+ TEXT@20..23
+ WORD@20..23 "bar"
+ COMMA@23..24 ","
+ WHITESPACE@24..25 " "
+ KEY_VALUE_PAIR@25..28
+ KEY@25..28
+ WORD@25..28 "baz"
+ R_BRACK@28..29 "]"
+ CURLY_GROUP_WORD_LIST@29..42
+ L_CURLY@29..30 "{"
+ WORD@30..41 "foo/bar.bib"
+ R_CURLY@41..42 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap
new file mode 100644
index 0000000000..3549b985c4
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\addbibresource{foo/bar.bib}\"#)"
+
+---
+ROOT@0..28
+ PREAMBLE@0..28
+ BIBLATEX_INCLUDE@0..28
+ BIBLATEX_INCLUDE_NAME@0..15 "\\addbibresource"
+ CURLY_GROUP_WORD_LIST@15..28
+ L_CURLY@15..16 "{"
+ WORD@16..27 "foo/bar.bib"
+ R_CURLY@27..28 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap
new file mode 100644
index 0000000000..f0d30ebfa3
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\bibliography{foo/bar}\"#)"
+
+---
+ROOT@0..22
+ PREAMBLE@0..22
+ BIBTEX_INCLUDE@0..22
+ BIBTEX_INCLUDE_NAME@0..13 "\\bibliography"
+ CURLY_GROUP_WORD_LIST@13..22
+ L_CURLY@13..14 "{"
+ WORD@14..21 "foo/bar"
+ R_CURLY@21..22 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_missing_end.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_missing_end.snap
new file mode 100644
index 0000000000..c5fc46ec4d
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_missing_end.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"{hello world\"#)"
+
+---
+ROOT@0..12
+ PREAMBLE@0..12
+ CURLY_GROUP@0..12
+ L_CURLY@0..1 "{"
+ TEXT@1..12
+ WORD@1..6 "hello"
+ WHITESPACE@6..7 " "
+ WORD@7..12 "world"
+ MISSING@12..12 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_simple.snap
new file mode 100644
index 0000000000..10ebc4418e
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__brace_group_simple.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"{hello world}\"#)"
+
+---
+ROOT@0..13
+ PREAMBLE@0..13
+ CURLY_GROUP@0..13
+ L_CURLY@0..1 "{"
+ TEXT@1..12
+ WORD@1..6 "hello"
+ WHITESPACE@6..7 " "
+ WORD@7..12 "world"
+ R_CURLY@12..13 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption.snap
new file mode 100644
index 0000000000..f598a8f7e9
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption.snap
@@ -0,0 +1,26 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\caption[qux]{Foo \\Bar Baz}\"#)"
+
+---
+ROOT@0..27
+ PREAMBLE@0..27
+ CAPTION@0..27
+ CAPTION_NAME@0..8 "\\caption"
+ BRACK_GROUP@8..13
+ L_BRACK@8..9 "["
+ TEXT@9..12
+ WORD@9..12 "qux"
+ R_BRACK@12..13 "]"
+ CURLY_GROUP@13..27
+ L_CURLY@13..14 "{"
+ TEXT@14..18
+ WORD@14..17 "Foo"
+ WHITESPACE@17..18 " "
+ GENERIC_COMMAND@18..23
+ GENERIC_COMMAND_NAME@18..22 "\\Bar"
+ WHITESPACE@22..23 " "
+ TEXT@23..26
+ WORD@23..26 "Baz"
+ R_CURLY@26..27 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_error.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_error.snap
new file mode 100644
index 0000000000..13697e882b
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_error.snap
@@ -0,0 +1,26 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\caption[qux]{Foo \\Bar Baz\"#)"
+
+---
+ROOT@0..26
+ PREAMBLE@0..26
+ CAPTION@0..26
+ CAPTION_NAME@0..8 "\\caption"
+ BRACK_GROUP@8..13
+ L_BRACK@8..9 "["
+ TEXT@9..12
+ WORD@9..12 "qux"
+ R_BRACK@12..13 "]"
+ CURLY_GROUP@13..26
+ L_CURLY@13..14 "{"
+ TEXT@14..18
+ WORD@14..17 "Foo"
+ WHITESPACE@17..18 " "
+ GENERIC_COMMAND@18..23
+ GENERIC_COMMAND_NAME@18..22 "\\Bar"
+ WHITESPACE@22..23 " "
+ TEXT@23..26
+ WORD@23..26 "Baz"
+ MISSING@26..26 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap
new file mode 100644
index 0000000000..4b963caabd
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap
@@ -0,0 +1,28 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{figure}\\caption{Foo}\\end{figure}\"#)"
+
+---
+ROOT@0..39
+ PREAMBLE@0..39
+ ENVIRONMENT@0..39
+ BEGIN@0..14
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..14
+ L_CURLY@6..7 "{"
+ WORD@7..13 "figure"
+ R_CURLY@13..14 "}"
+ CAPTION@14..27
+ CAPTION_NAME@14..22 "\\caption"
+ CURLY_GROUP@22..27
+ L_CURLY@22..23 "{"
+ TEXT@23..26
+ WORD@23..26 "Foo"
+ R_CURLY@26..27 "}"
+ END@27..39
+ END_ENVIRONMENT_NAME@27..31 "\\end"
+ CURLY_GROUP_WORD@31..39
+ L_CURLY@31..32 "{"
+ WORD@32..38 "figure"
+ R_CURLY@38..39 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal.snap
new file mode 100644
index 0000000000..bf9e795e18
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal.snap
@@ -0,0 +1,21 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\caption{Foo \\Bar Baz}\"#)"
+
+---
+ROOT@0..22
+ PREAMBLE@0..22
+ CAPTION@0..22
+ CAPTION_NAME@0..8 "\\caption"
+ CURLY_GROUP@8..22
+ L_CURLY@8..9 "{"
+ TEXT@9..13
+ WORD@9..12 "Foo"
+ WHITESPACE@12..13 " "
+ GENERIC_COMMAND@13..18
+ GENERIC_COMMAND_NAME@13..17 "\\Bar"
+ WHITESPACE@17..18 " "
+ TEXT@18..21
+ WORD@18..21 "Baz"
+ R_CURLY@21..22 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal_error.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal_error.snap
new file mode 100644
index 0000000000..6c932ce883
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_minimal_error.snap
@@ -0,0 +1,21 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\caption{Foo \\Bar Baz\"#)"
+
+---
+ROOT@0..21
+ PREAMBLE@0..21
+ CAPTION@0..21
+ CAPTION_NAME@0..8 "\\caption"
+ CURLY_GROUP@8..21
+ L_CURLY@8..9 "{"
+ TEXT@9..13
+ WORD@9..12 "Foo"
+ WHITESPACE@12..13 " "
+ GENERIC_COMMAND@13..18
+ GENERIC_COMMAND_NAME@13..17 "\\Bar"
+ WHITESPACE@17..18 " "
+ TEXT@18..21
+ WORD@18..21 "Baz"
+ MISSING@21..21 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_empty.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_empty.snap
new file mode 100644
index 0000000000..faad4c0039
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_empty.snap
@@ -0,0 +1,13 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite{}\"#)"
+
+---
+ROOT@0..7
+ PREAMBLE@0..7
+ CITATION@0..7
+ CITATION_NAME@0..5 "\\cite"
+ CURLY_GROUP_WORD_LIST@5..7
+ L_CURLY@5..6 "{"
+ R_CURLY@6..7 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap
new file mode 100644
index 0000000000..363f8b0142
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite{foo\"#)"
+
+---
+ROOT@0..9
+ PREAMBLE@0..9
+ CITATION@0..9
+ CITATION_NAME@0..5 "\\cite"
+ CURLY_GROUP_WORD_LIST@5..9
+ L_CURLY@5..6 "{"
+ WORD@6..9 "foo"
+ MISSING@9..9 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap
new file mode 100644
index 0000000000..dafc826a97
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap
@@ -0,0 +1,17 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite{foo, bar}\"#)"
+
+---
+ROOT@0..15
+ PREAMBLE@0..15
+ CITATION@0..15
+ CITATION_NAME@0..5 "\\cite"
+ CURLY_GROUP_WORD_LIST@5..15
+ L_CURLY@5..6 "{"
+ WORD@6..9 "foo"
+ COMMA@9..10 ","
+ WHITESPACE@10..11 " "
+ WORD@11..14 "bar"
+ R_CURLY@14..15 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap
new file mode 100644
index 0000000000..93d83bb448
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite[foo]{bar}\"#)"
+
+---
+ROOT@0..15
+ PREAMBLE@0..15
+ CITATION@0..15
+ CITATION_NAME@0..5 "\\cite"
+ BRACK_GROUP@5..10
+ L_BRACK@5..6 "["
+ TEXT@6..9
+ WORD@6..9 "foo"
+ R_BRACK@9..10 "]"
+ CURLY_GROUP_WORD_LIST@10..15
+ L_CURLY@10..11 "{"
+ WORD@11..14 "bar"
+ R_CURLY@14..15 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap
new file mode 100644
index 0000000000..3acaafea3b
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap
@@ -0,0 +1,24 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite[foo][bar]{baz}\"#)"
+
+---
+ROOT@0..20
+ PREAMBLE@0..20
+ CITATION@0..20
+ CITATION_NAME@0..5 "\\cite"
+ BRACK_GROUP@5..10
+ L_BRACK@5..6 "["
+ TEXT@6..9
+ WORD@6..9 "foo"
+ R_BRACK@9..10 "]"
+ BRACK_GROUP@10..15
+ L_BRACK@10..11 "["
+ TEXT@11..14
+ WORD@11..14 "bar"
+ R_BRACK@14..15 "]"
+ CURLY_GROUP_WORD_LIST@15..20
+ L_CURLY@15..16 "{"
+ WORD@16..19 "baz"
+ R_CURLY@19..20 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap
new file mode 100644
index 0000000000..12f34f16ae
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap
@@ -0,0 +1,16 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite{,foo,}\"#)"
+
+---
+ROOT@0..12
+ PREAMBLE@0..12
+ CITATION@0..12
+ CITATION_NAME@0..5 "\\cite"
+ CURLY_GROUP_WORD_LIST@5..12
+ L_CURLY@5..6 "{"
+ COMMA@6..7 ","
+ WORD@7..10 "foo"
+ COMMA@10..11 ","
+ R_CURLY@11..12 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap
new file mode 100644
index 0000000000..a22129f85f
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\cite{foo}\"#)"
+
+---
+ROOT@0..10
+ PREAMBLE@0..10
+ CITATION@0..10
+ CITATION_NAME@0..5 "\\cite"
+ CURLY_GROUP_WORD_LIST@5..10
+ L_CURLY@5..6 "{"
+ WORD@6..9 "foo"
+ R_CURLY@9..10 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap
new file mode 100644
index 0000000000..4388596dfd
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\nocite{*}\"#)"
+
+---
+ROOT@0..10
+ PREAMBLE@0..10
+ CITATION@0..10
+ CITATION_NAME@0..7 "\\nocite"
+ CURLY_GROUP_WORD_LIST@7..10
+ L_CURLY@7..8 "{"
+ WORD@8..9 "*"
+ R_CURLY@9..10 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_empty.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_empty.snap
new file mode 100644
index 0000000000..7d84653225
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_empty.snap
@@ -0,0 +1,13 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\documentclass{}\"#)"
+
+---
+ROOT@0..16
+ PREAMBLE@0..16
+ CLASS_INCLUDE@0..16
+ CLASS_INCLUDE_NAME@0..14 "\\documentclass"
+ CURLY_GROUP_WORD_LIST@14..16
+ L_CURLY@14..15 "{"
+ R_CURLY@15..16 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap
new file mode 100644
index 0000000000..0d0eb1b250
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap
@@ -0,0 +1,37 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\documentclass[foo = bar, baz, qux]{article}\"#)"
+
+---
+ROOT@0..44
+ PREAMBLE@0..44
+ CLASS_INCLUDE@0..44
+ CLASS_INCLUDE_NAME@0..14 "\\documentclass"
+ BRACK_GROUP_KEY_VALUE@14..35
+ L_BRACK@14..15 "["
+ KEY_VALUE_BODY@15..34
+ KEY_VALUE_PAIR@15..24
+ KEY@15..19
+ WORD@15..18 "foo"
+ WHITESPACE@18..19 " "
+ EQUALITY_SIGN@19..20 "="
+ WHITESPACE@20..21 " "
+ VALUE@21..24
+ TEXT@21..24
+ WORD@21..24 "bar"
+ COMMA@24..25 ","
+ WHITESPACE@25..26 " "
+ KEY_VALUE_PAIR@26..29
+ KEY@26..29
+ WORD@26..29 "baz"
+ COMMA@29..30 ","
+ WHITESPACE@30..31 " "
+ KEY_VALUE_PAIR@31..34
+ KEY@31..34
+ WORD@31..34 "qux"
+ R_BRACK@34..35 "]"
+ CURLY_GROUP_WORD_LIST@35..44
+ L_CURLY@35..36 "{"
+ WORD@36..43 "article"
+ R_CURLY@43..44 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap
new file mode 100644
index 0000000000..85e21b47a8
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\documentclass{article}\"#)"
+
+---
+ROOT@0..23
+ PREAMBLE@0..23
+ CLASS_INCLUDE@0..23
+ CLASS_INCLUDE_NAME@0..14 "\\documentclass"
+ CURLY_GROUP_WORD_LIST@14..23
+ L_CURLY@14..15 "{"
+ WORD@15..22 "article"
+ R_CURLY@22..23 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap
new file mode 100644
index 0000000000..e4adfd534c
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap
@@ -0,0 +1,27 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\definecolor{foo}{rgb}{255,168,0}\"#)"
+
+---
+ROOT@0..33
+ PREAMBLE@0..33
+ COLOR_DEFINITION@0..33
+ COLOR_DEFINITION_NAME@0..12 "\\definecolor"
+ CURLY_GROUP_WORD@12..17
+ L_CURLY@12..13 "{"
+ WORD@13..16 "foo"
+ R_CURLY@16..17 "}"
+ CURLY_GROUP_WORD@17..22
+ L_CURLY@17..18 "{"
+ WORD@18..21 "rgb"
+ R_CURLY@21..22 "}"
+ CURLY_GROUP@22..33
+ L_CURLY@22..23 "{"
+ TEXT@23..32
+ WORD@23..26 "255"
+ COMMA@26..27 ","
+ WORD@27..30 "168"
+ COMMA@30..31 ","
+ WORD@31..32 "0"
+ R_CURLY@32..33 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap
new file mode 100644
index 0000000000..41a3700122
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\color{black}\"#)"
+
+---
+ROOT@0..13
+ PREAMBLE@0..13
+ COLOR_REFERENCE@0..13
+ COLOR_REFERENCE_NAME@0..6 "\\color"
+ CURLY_GROUP_WORD@6..13
+ L_CURLY@6..7 "{"
+ WORD@7..12 "black"
+ R_CURLY@12..13 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap
new file mode 100644
index 0000000000..42095ff974
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap
@@ -0,0 +1,29 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\definecolorset[ty]{rgb,HTML}{foo}{bar}\"#)"
+
+---
+ROOT@0..39
+ PREAMBLE@0..39
+ COLOR_SET_DEFINITION@0..39
+ COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset"
+ BRACK_GROUP_WORD@15..19
+ L_BRACK@15..16 "["
+ WORD@16..18 "ty"
+ R_BRACK@18..19 "]"
+ CURLY_GROUP_WORD_LIST@19..29
+ L_CURLY@19..20 "{"
+ WORD@20..23 "rgb"
+ COMMA@23..24 ","
+ WORD@24..28 "HTML"
+ R_CURLY@28..29 "}"
+ CURLY_GROUP_WORD@29..34
+ L_CURLY@29..30 "{"
+ WORD@30..33 "foo"
+ R_CURLY@33..34 "}"
+ CURLY_GROUP_WORD@34..39
+ L_CURLY@34..35 "{"
+ WORD@35..38 "bar"
+ R_CURLY@38..39 "}"
+ MISSING@39..39 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap
new file mode 100644
index 0000000000..718d49a3e3
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap
@@ -0,0 +1,22 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\definecolorset{rgb,HTML}{foo}\"#)"
+
+---
+ROOT@0..30
+ PREAMBLE@0..30
+ COLOR_SET_DEFINITION@0..30
+ COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset"
+ CURLY_GROUP_WORD_LIST@15..25
+ L_CURLY@15..16 "{"
+ WORD@16..19 "rgb"
+ COMMA@19..20 ","
+ WORD@20..24 "HTML"
+ R_CURLY@24..25 "}"
+ CURLY_GROUP_WORD@25..30
+ L_CURLY@25..26 "{"
+ WORD@26..29 "foo"
+ R_CURLY@29..30 "}"
+ MISSING@30..30 ""
+ MISSING@30..30 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap
new file mode 100644
index 0000000000..f92d813123
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\definecolorset{rgb,HTML}\"#)"
+
+---
+ROOT@0..25
+ PREAMBLE@0..25
+ COLOR_SET_DEFINITION@0..25
+ COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset"
+ CURLY_GROUP_WORD_LIST@15..25
+ L_CURLY@15..16 "{"
+ WORD@16..19 "rgb"
+ COMMA@19..20 ","
+ WORD@20..24 "HTML"
+ R_CURLY@24..25 "}"
+ MISSING@25..25 ""
+ MISSING@25..25 ""
+ MISSING@25..25 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error4.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error4.snap
new file mode 100644
index 0000000000..3cafa81bae
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error4.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\definecolorset\"#)"
+
+---
+ROOT@0..15
+ PREAMBLE@0..15
+ COLOR_SET_DEFINITION@0..15
+ COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset"
+ MISSING@15..15 ""
+ MISSING@15..15 ""
+ MISSING@15..15 ""
+ MISSING@15..15 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap
new file mode 100644
index 0000000000..f9a736c65f
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap
@@ -0,0 +1,32 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\definecolorset[ty]{rgb,HTML}{foo}{bar}{baz}\"#)"
+
+---
+ROOT@0..44
+ PREAMBLE@0..44
+ COLOR_SET_DEFINITION@0..44
+ COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset"
+ BRACK_GROUP_WORD@15..19
+ L_BRACK@15..16 "["
+ WORD@16..18 "ty"
+ R_BRACK@18..19 "]"
+ CURLY_GROUP_WORD_LIST@19..29
+ L_CURLY@19..20 "{"
+ WORD@20..23 "rgb"
+ COMMA@23..24 ","
+ WORD@24..28 "HTML"
+ R_CURLY@28..29 "}"
+ CURLY_GROUP_WORD@29..34
+ L_CURLY@29..30 "{"
+ WORD@30..33 "foo"
+ R_CURLY@33..34 "}"
+ CURLY_GROUP_WORD@34..39
+ L_CURLY@34..35 "{"
+ WORD@35..38 "bar"
+ R_CURLY@38..39 "}"
+ CURLY_GROUP_WORD@39..44
+ L_CURLY@39..40 "{"
+ WORD@40..43 "baz"
+ R_CURLY@43..44 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_argc.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_argc.snap
new file mode 100644
index 0000000000..2ff3896080
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_argc.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newcommand{\\foo}{foo}\"#)"
+
+---
+ROOT@0..22
+ PREAMBLE@0..22
+ COMMAND_DEFINITION@0..22
+ COMMAND_DEFINITION_NAME@0..11 "\\newcommand"
+ CURLY_GROUP_COMMAND@11..17
+ L_CURLY@11..12 "{"
+ GENERIC_COMMAND_NAME@12..16 "\\foo"
+ R_CURLY@16..17 "}"
+ CURLY_GROUP@17..22
+ L_CURLY@17..18 "{"
+ TEXT@18..21
+ WORD@18..21 "foo"
+ R_CURLY@21..22 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl.snap
new file mode 100644
index 0000000000..4602a7a688
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newcommand{\\foo}\"#)"
+
+---
+ROOT@0..17
+ PREAMBLE@0..17
+ COMMAND_DEFINITION@0..17
+ COMMAND_DEFINITION_NAME@0..11 "\\newcommand"
+ CURLY_GROUP_COMMAND@11..17
+ L_CURLY@11..12 "{"
+ GENERIC_COMMAND_NAME@12..16 "\\foo"
+ R_CURLY@16..17 "}"
+ MISSING@17..17 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl_error.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl_error.snap
new file mode 100644
index 0000000000..4a20be7d7c
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_no_impl_error.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newcommand{\\foo\"#)"
+
+---
+ROOT@0..16
+ PREAMBLE@0..16
+ COMMAND_DEFINITION@0..16
+ COMMAND_DEFINITION_NAME@0..11 "\\newcommand"
+ CURLY_GROUP_COMMAND@11..16
+ L_CURLY@11..12 "{"
+ GENERIC_COMMAND_NAME@12..16 "\\foo"
+ MISSING@16..16 ""
+ MISSING@16..16 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap
new file mode 100644
index 0000000000..e5f2377fcf
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap
@@ -0,0 +1,24 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newcommand[1]{\\id}{#1}\"#)"
+
+---
+ROOT@0..23
+ PREAMBLE@0..23
+ COMMAND_DEFINITION@0..19
+ COMMAND_DEFINITION_NAME@0..11 "\\newcommand"
+ MISSING@11..11 ""
+ BRACK_GROUP_WORD@11..14
+ L_BRACK@11..12 "["
+ WORD@12..13 "1"
+ R_BRACK@13..14 "]"
+ CURLY_GROUP@14..19
+ L_CURLY@14..15 "{"
+ GENERIC_COMMAND@15..18
+ GENERIC_COMMAND_NAME@15..18 "\\id"
+ R_CURLY@18..19 "}"
+ CURLY_GROUP@19..23
+ L_CURLY@19..20 "{"
+ PARAMETER@20..22 "#1"
+ R_CURLY@22..23 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__empty.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__empty.snap
new file mode 100644
index 0000000000..f01f7f9092
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__empty.snap
@@ -0,0 +1,8 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\"#)"
+
+---
+ROOT@0..0
+ PREAMBLE@0..0
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap
new file mode 100644
index 0000000000..df3c0d56fb
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap
@@ -0,0 +1,38 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newenvironment{bar}[1]{\\begin{foo}}{\\end{foo}}\"#)"
+
+---
+ROOT@0..47
+ PREAMBLE@0..47
+ ENVIRONMENT_DEFINITION@0..47
+ ENVIRONMENT_DEFINIITION_NAME@0..15 "\\newenvironment"
+ CURLY_GROUP_WORD@15..20
+ L_CURLY@15..16 "{"
+ WORD@16..19 "bar"
+ R_CURLY@19..20 "}"
+ BRACK_GROUP_WORD@20..23
+ L_BRACK@20..21 "["
+ WORD@21..22 "1"
+ R_BRACK@22..23 "]"
+ CURLY_GROUP@23..36
+ L_CURLY@23..24 "{"
+ GENERIC_COMMAND@24..35
+ BEGIN_ENVIRONMENT_NAME@24..30 "\\begin"
+ CURLY_GROUP@30..35
+ L_CURLY@30..31 "{"
+ TEXT@31..34
+ WORD@31..34 "foo"
+ R_CURLY@34..35 "}"
+ R_CURLY@35..36 "}"
+ CURLY_GROUP@36..47
+ L_CURLY@36..37 "{"
+ GENERIC_COMMAND@37..46
+ END_ENVIRONMENT_NAME@37..41 "\\end"
+ CURLY_GROUP@41..46
+ L_CURLY@41..42 "{"
+ TEXT@42..45
+ WORD@42..45 "foo"
+ R_CURLY@45..46 "}"
+ R_CURLY@46..47 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap
new file mode 100644
index 0000000000..a5c566f773
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap
@@ -0,0 +1,37 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{foo} \\begin{qux} \\end{baz} \\end{bar}\"#)"
+
+---
+ROOT@0..43
+ PREAMBLE@0..43
+ ENVIRONMENT@0..43
+ BEGIN@0..12
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..12
+ L_CURLY@6..7 "{"
+ WORD@7..10 "foo"
+ R_CURLY@10..11 "}"
+ WHITESPACE@11..12 " "
+ ENVIRONMENT@12..34
+ BEGIN@12..24
+ BEGIN_ENVIRONMENT_NAME@12..18 "\\begin"
+ CURLY_GROUP_WORD@18..24
+ L_CURLY@18..19 "{"
+ WORD@19..22 "qux"
+ R_CURLY@22..23 "}"
+ WHITESPACE@23..24 " "
+ END@24..34
+ END_ENVIRONMENT_NAME@24..28 "\\end"
+ CURLY_GROUP_WORD@28..34
+ L_CURLY@28..29 "{"
+ WORD@29..32 "baz"
+ R_CURLY@32..33 "}"
+ WHITESPACE@33..34 " "
+ END@34..43
+ END_ENVIRONMENT_NAME@34..38 "\\end"
+ CURLY_GROUP_WORD@38..43
+ L_CURLY@38..39 "{"
+ WORD@39..42 "bar"
+ R_CURLY@42..43 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap
new file mode 100644
index 0000000000..9ff76605d6
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap
@@ -0,0 +1,42 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{foo \\begin{qux Hello World \\end{baz} \\end{bar\"#)"
+
+---
+ROOT@0..52
+ PREAMBLE@0..52
+ ENVIRONMENT@0..52
+ BEGIN@0..11
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..11
+ L_CURLY@6..7 "{"
+ WORD@7..10 "foo"
+ WHITESPACE@10..11 " "
+ MISSING@11..11 ""
+ ENVIRONMENT@11..44
+ BEGIN@11..22
+ BEGIN_ENVIRONMENT_NAME@11..17 "\\begin"
+ CURLY_GROUP_WORD@17..22
+ L_CURLY@17..18 "{"
+ WORD@18..21 "qux"
+ WHITESPACE@21..22 " "
+ MISSING@22..22 ""
+ TEXT@22..34
+ WORD@22..27 "Hello"
+ WHITESPACE@27..28 " "
+ WORD@28..33 "World"
+ WHITESPACE@33..34 " "
+ END@34..44
+ END_ENVIRONMENT_NAME@34..38 "\\end"
+ CURLY_GROUP_WORD@38..44
+ L_CURLY@38..39 "{"
+ WORD@39..42 "baz"
+ R_CURLY@42..43 "}"
+ WHITESPACE@43..44 " "
+ END@44..52
+ END_ENVIRONMENT_NAME@44..48 "\\end"
+ CURLY_GROUP_WORD@48..52
+ L_CURLY@48..49 "{"
+ WORD@49..52 "bar"
+ MISSING@52..52 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap
new file mode 100644
index 0000000000..d58f5b26c4
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap
@@ -0,0 +1,27 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{foo} Hello World \\end{bar}\"#)"
+
+---
+ROOT@0..33
+ PREAMBLE@0..33
+ ENVIRONMENT@0..33
+ BEGIN@0..12
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..12
+ L_CURLY@6..7 "{"
+ WORD@7..10 "foo"
+ R_CURLY@10..11 "}"
+ WHITESPACE@11..12 " "
+ TEXT@12..24
+ WORD@12..17 "Hello"
+ WHITESPACE@17..18 " "
+ WORD@18..23 "World"
+ WHITESPACE@23..24 " "
+ END@24..33
+ END_ENVIRONMENT_NAME@24..28 "\\end"
+ CURLY_GROUP_WORD@28..33
+ L_CURLY@28..29 "{"
+ WORD@29..32 "bar"
+ R_CURLY@32..33 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation.snap
new file mode 100644
index 0000000000..e146fcaee6
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation.snap
@@ -0,0 +1,17 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\[ foo bar \\]\"#)"
+
+---
+ROOT@0..13
+ PREAMBLE@0..13
+ EQUATION@0..13
+ BEGIN_EQUATION_NAME@0..2 "\\["
+ WHITESPACE@2..3 " "
+ TEXT@3..11
+ WORD@3..6 "foo"
+ WHITESPACE@6..7 " "
+ WORD@7..10 "bar"
+ WHITESPACE@10..11 " "
+ END_EQUATION_NAME@11..13 "\\]"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap
new file mode 100644
index 0000000000..7a851233ef
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\eqref{foo}\"#)"
+
+---
+ROOT@0..11
+ PREAMBLE@0..11
+ LABEL_REFERENCE@0..11
+ LABEL_REFERENCE_NAME@0..6 "\\eqref"
+ CURLY_GROUP_WORD_LIST@6..11
+ L_CURLY@6..7 "{"
+ WORD@7..10 "foo"
+ R_CURLY@10..11 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap
new file mode 100644
index 0000000000..fe065667c3
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap
@@ -0,0 +1,30 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{a} foo bar \\] \\end{b}\"#)"
+
+---
+ROOT@0..28
+ PREAMBLE@0..28
+ ENVIRONMENT@0..28
+ BEGIN@0..10
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..10
+ L_CURLY@6..7 "{"
+ WORD@7..8 "a"
+ R_CURLY@8..9 "}"
+ WHITESPACE@9..10 " "
+ TEXT@10..18
+ WORD@10..13 "foo"
+ WHITESPACE@13..14 " "
+ WORD@14..17 "bar"
+ WHITESPACE@17..18 " "
+ GENERIC_COMMAND@18..21
+ END_EQUATION_NAME@18..20 "\\]"
+ WHITESPACE@20..21 " "
+ END@21..28
+ END_ENVIRONMENT_NAME@21..25 "\\end"
+ CURLY_GROUP_WORD@25..28
+ L_CURLY@25..26 "{"
+ WORD@26..27 "b"
+ R_CURLY@27..28 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap
new file mode 100644
index 0000000000..f7b6205ffb
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap
@@ -0,0 +1,31 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{a} \\[ foo bar \\end{b}\"#)"
+
+---
+ROOT@0..28
+ PREAMBLE@0..28
+ ENVIRONMENT@0..28
+ BEGIN@0..10
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..10
+ L_CURLY@6..7 "{"
+ WORD@7..8 "a"
+ R_CURLY@8..9 "}"
+ WHITESPACE@9..10 " "
+ EQUATION@10..21
+ BEGIN_EQUATION_NAME@10..12 "\\["
+ WHITESPACE@12..13 " "
+ TEXT@13..21
+ WORD@13..16 "foo"
+ WHITESPACE@16..17 " "
+ WORD@17..20 "bar"
+ WHITESPACE@20..21 " "
+ MISSING@21..21 ""
+ END@21..28
+ END_ENVIRONMENT_NAME@21..25 "\\end"
+ CURLY_GROUP_WORD@25..28
+ L_CURLY@25..26 "{"
+ WORD@26..27 "b"
+ R_CURLY@27..28 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__escaped_brackets.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__escaped_brackets.snap
new file mode 100644
index 0000000000..c595828583
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__escaped_brackets.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"{[}{]}\"#)"
+
+---
+ROOT@0..6
+ PREAMBLE@0..6
+ CURLY_GROUP@0..3
+ L_CURLY@0..1 "{"
+ MIXED_GROUP@1..2
+ L_BRACK@1..2 "["
+ MISSING@2..2 ""
+ R_CURLY@2..3 "}"
+ CURLY_GROUP@3..6
+ L_CURLY@3..4 "{"
+ ERROR@4..5
+ R_BRACK@4..5 "]"
+ R_CURLY@5..6 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_args.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_args.snap
new file mode 100644
index 0000000000..b62c8c2559
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_args.snap
@@ -0,0 +1,20 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\foo{bar}[qux]\"#)"
+
+---
+ROOT@0..14
+ PREAMBLE@0..14
+ GENERIC_COMMAND@0..14
+ GENERIC_COMMAND_NAME@0..4 "\\foo"
+ CURLY_GROUP@4..9
+ L_CURLY@4..5 "{"
+ TEXT@5..8
+ WORD@5..8 "bar"
+ R_CURLY@8..9 "}"
+ MIXED_GROUP@9..14
+ L_BRACK@9..10 "["
+ TEXT@10..13
+ WORD@10..13 "qux"
+ R_BRACK@13..14 "]"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_empty.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_empty.snap
new file mode 100644
index 0000000000..84e62ea81d
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_empty.snap
@@ -0,0 +1,10 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\foo\"#)"
+
+---
+ROOT@0..4
+ PREAMBLE@0..4
+ GENERIC_COMMAND@0..4
+ GENERIC_COMMAND_NAME@0..4 "\\foo"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_escape.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_escape.snap
new file mode 100644
index 0000000000..a0d5d2e29b
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__generic_command_escape.snap
@@ -0,0 +1,10 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\#\"#)"
+
+---
+ROOT@0..2
+ PREAMBLE@0..2
+ GENERIC_COMMAND@0..2
+ GENERIC_COMMAND_NAME@0..2 "\\#"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap
new file mode 100644
index 0000000000..d1b31e275a
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap
@@ -0,0 +1,33 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newglossaryentry{foo}{bar = baz, qux,}\"#)"
+
+---
+ROOT@0..39
+ PREAMBLE@0..39
+ GLOSSARY_ENTRY_DEFINITION@0..39
+ GLOSSARY_ENTRY_DEFINITION_NAME@0..17 "\\newglossaryentry"
+ CURLY_GROUP_WORD@17..22
+ L_CURLY@17..18 "{"
+ WORD@18..21 "foo"
+ R_CURLY@21..22 "}"
+ CURLY_GROUP_KEY_VALUE@22..39
+ L_CURLY@22..23 "{"
+ KEY_VALUE_BODY@23..38
+ KEY_VALUE_PAIR@23..32
+ KEY@23..27
+ WORD@23..26 "bar"
+ WHITESPACE@26..27 " "
+ EQUALITY_SIGN@27..28 "="
+ WHITESPACE@28..29 " "
+ VALUE@29..32
+ TEXT@29..32
+ WORD@29..32 "baz"
+ COMMA@32..33 ","
+ WHITESPACE@33..34 " "
+ KEY_VALUE_PAIR@34..37
+ KEY@34..37
+ WORD@34..37 "qux"
+ COMMA@37..38 ","
+ R_CURLY@38..39 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap
new file mode 100644
index 0000000000..ad5c44885a
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap
@@ -0,0 +1,32 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\gls[foo = bar, qux]{baz}\"#)"
+
+---
+ROOT@0..25
+ PREAMBLE@0..25
+ GLOSSARY_ENTRY_REFERENCE@0..25
+ GLOSSARY_ENTRY_REFERENCE_NAME@0..4 "\\gls"
+ BRACK_GROUP_KEY_VALUE@4..20
+ L_BRACK@4..5 "["
+ KEY_VALUE_BODY@5..19
+ KEY_VALUE_PAIR@5..14
+ KEY@5..9
+ WORD@5..8 "foo"
+ WHITESPACE@8..9 " "
+ EQUALITY_SIGN@9..10 "="
+ WHITESPACE@10..11 " "
+ VALUE@11..14
+ TEXT@11..14
+ WORD@11..14 "bar"
+ COMMA@14..15 ","
+ WHITESPACE@15..16 " "
+ KEY_VALUE_PAIR@16..19
+ KEY@16..19
+ WORD@16..19 "qux"
+ R_BRACK@19..20 "]"
+ CURLY_GROUP_WORD@20..25
+ L_CURLY@20..21 "{"
+ WORD@21..24 "baz"
+ R_CURLY@24..25 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap
new file mode 100644
index 0000000000..2a6b845733
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\gls{foo}\"#)"
+
+---
+ROOT@0..9
+ PREAMBLE@0..9
+ GLOSSARY_ENTRY_REFERENCE@0..9
+ GLOSSARY_ENTRY_REFERENCE_NAME@0..4 "\\gls"
+ CURLY_GROUP_WORD@4..9
+ L_CURLY@4..5 "{"
+ WORD@5..8 "foo"
+ R_CURLY@8..9 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap
new file mode 100644
index 0000000000..910a4848ef
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap
@@ -0,0 +1,25 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\includegraphics[scale=.5]{foo/bar.pdf}\"#)"
+
+---
+ROOT@0..39
+ PREAMBLE@0..39
+ GRAPHICS_INCLUDE@0..39
+ GRAPHICS_INCLUDE_NAME@0..16 "\\includegraphics"
+ BRACK_GROUP_KEY_VALUE@16..26
+ L_BRACK@16..17 "["
+ KEY_VALUE_BODY@17..25
+ KEY_VALUE_PAIR@17..25
+ KEY@17..22
+ WORD@17..22 "scale"
+ EQUALITY_SIGN@22..23 "="
+ VALUE@23..25
+ TEXT@23..25
+ WORD@23..25 ".5"
+ R_BRACK@25..26 "]"
+ CURLY_GROUP_WORD_LIST@26..39
+ L_CURLY@26..27 "{"
+ WORD@27..38 "foo/bar.pdf"
+ R_CURLY@38..39 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap
new file mode 100644
index 0000000000..fa6fbf1a14
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\includegraphics{foo/bar.pdf}\"#)"
+
+---
+ROOT@0..29
+ PREAMBLE@0..29
+ GRAPHICS_INCLUDE@0..29
+ GRAPHICS_INCLUDE_NAME@0..16 "\\includegraphics"
+ CURLY_GROUP_WORD_LIST@16..29
+ L_CURLY@16..17 "{"
+ WORD@17..28 "foo/bar.pdf"
+ R_CURLY@28..29 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__hello_world.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__hello_world.snap
new file mode 100644
index 0000000000..ee25cb5453
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__hello_world.snap
@@ -0,0 +1,12 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"Hello World!\"#)"
+
+---
+ROOT@0..12
+ PREAMBLE@0..12
+ TEXT@0..12
+ WORD@0..5 "Hello"
+ WHITESPACE@5..6 " "
+ WORD@6..12 "World!"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap
new file mode 100644
index 0000000000..3dae1f433a
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\import{foo\"#)"
+
+---
+ROOT@0..11
+ PREAMBLE@0..11
+ IMPORT@0..11
+ IMPORT_NAME@0..7 "\\import"
+ CURLY_GROUP_WORD@7..11
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ MISSING@11..11 ""
+ MISSING@11..11 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap
new file mode 100644
index 0000000000..6e21f65cbf
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap
@@ -0,0 +1,18 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\import{foo}{bar}\"#)"
+
+---
+ROOT@0..17
+ PREAMBLE@0..17
+ IMPORT@0..17
+ IMPORT_NAME@0..7 "\\import"
+ CURLY_GROUP_WORD@7..12
+ L_CURLY@7..8 "{"
+ WORD@8..11 "foo"
+ R_CURLY@11..12 "}"
+ CURLY_GROUP_WORD@12..17
+ L_CURLY@12..13 "{"
+ WORD@13..16 "bar"
+ R_CURLY@16..17 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap
new file mode 100644
index 0000000000..d1fd2df652
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap
@@ -0,0 +1,25 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\includesvg[scale=.5]{foo/bar}\"#)"
+
+---
+ROOT@0..30
+ PREAMBLE@0..30
+ SVG_INCLUDE@0..30
+ SVG_INCLUDE_NAME@0..11 "\\includesvg"
+ BRACK_GROUP_KEY_VALUE@11..21
+ L_BRACK@11..12 "["
+ KEY_VALUE_BODY@12..20
+ KEY_VALUE_PAIR@12..20
+ KEY@12..17
+ WORD@12..17 "scale"
+ EQUALITY_SIGN@17..18 "="
+ VALUE@18..20
+ TEXT@18..20
+ WORD@18..20 ".5"
+ R_BRACK@20..21 "]"
+ CURLY_GROUP_WORD_LIST@21..30
+ L_CURLY@21..22 "{"
+ WORD@22..29 "foo/bar"
+ R_CURLY@29..30 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap
new file mode 100644
index 0000000000..59f50c36d3
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\includesvg{foo/bar}\"#)"
+
+---
+ROOT@0..20
+ PREAMBLE@0..20
+ SVG_INCLUDE@0..20
+ SVG_INCLUDE_NAME@0..11 "\\includesvg"
+ CURLY_GROUP_WORD_LIST@11..20
+ L_CURLY@11..12 "{"
+ WORD@12..19 "foo/bar"
+ R_CURLY@19..20 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline.snap
new file mode 100644
index 0000000000..b430de766e
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline.snap
@@ -0,0 +1,26 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"$x \\in [0, \\infty)$\"#)"
+
+---
+ROOT@0..19
+ PREAMBLE@0..19
+ FORMULA@0..19
+ DOLLAR@0..1 "$"
+ TEXT@1..3
+ WORD@1..2 "x"
+ WHITESPACE@2..3 " "
+ GENERIC_COMMAND@3..18
+ GENERIC_COMMAND_NAME@3..6 "\\in"
+ WHITESPACE@6..7 " "
+ MIXED_GROUP@7..18
+ L_BRACK@7..8 "["
+ TEXT@8..11
+ WORD@8..9 "0"
+ COMMA@9..10 ","
+ WHITESPACE@10..11 " "
+ GENERIC_COMMAND@11..17
+ GENERIC_COMMAND_NAME@11..17 "\\infty"
+ R_PAREN@17..18 ")"
+ DOLLAR@18..19 "$"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline_double_dollar.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline_double_dollar.snap
new file mode 100644
index 0000000000..8da22f3ecb
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inline_double_dollar.snap
@@ -0,0 +1,26 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"$$x \\in [0, \\infty)$$\"#)"
+
+---
+ROOT@0..21
+ PREAMBLE@0..21
+ FORMULA@0..21
+ DOLLAR@0..2 "$$"
+ TEXT@2..4
+ WORD@2..3 "x"
+ WHITESPACE@3..4 " "
+ GENERIC_COMMAND@4..19
+ GENERIC_COMMAND_NAME@4..7 "\\in"
+ WHITESPACE@7..8 " "
+ MIXED_GROUP@8..19
+ L_BRACK@8..9 "["
+ TEXT@9..12
+ WORD@9..10 "0"
+ COMMA@10..11 ","
+ WHITESPACE@11..12 " "
+ GENERIC_COMMAND@12..18
+ GENERIC_COMMAND_NAME@12..18 "\\infty"
+ R_PAREN@18..19 ")"
+ DOLLAR@19..21 "$$"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap
new file mode 100644
index 0000000000..7eacd65c59
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\label{foo}\"#)"
+
+---
+ROOT@0..11
+ PREAMBLE@0..11
+ LABEL_DEFINITION@0..11
+ LABEL_DEFINITION_NAME@0..6 "\\label"
+ CURLY_GROUP_WORD@6..11
+ L_CURLY@6..7 "{"
+ WORD@7..10 "foo"
+ R_CURLY@10..11 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap
new file mode 100644
index 0000000000..46392d7574
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newlabel{foo}{{1.1}}\"#)"
+
+---
+ROOT@0..21
+ PREAMBLE@0..21
+ LABEL_NUMBER@0..21
+ LABEL_NUMBER_NAME@0..9 "\\newlabel"
+ CURLY_GROUP_WORD@9..14
+ L_CURLY@9..10 "{"
+ WORD@10..13 "foo"
+ R_CURLY@13..14 "}"
+ CURLY_GROUP@14..21
+ L_CURLY@14..15 "{"
+ CURLY_GROUP@15..20
+ L_CURLY@15..16 "{"
+ TEXT@16..19
+ WORD@16..19 "1.1"
+ R_CURLY@19..20 "}"
+ R_CURLY@20..21 "}"
+ MISSING@21..21 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap
new file mode 100644
index 0000000000..e399397e09
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap
@@ -0,0 +1,17 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\ref{foo, bar}\"#)"
+
+---
+ROOT@0..14
+ PREAMBLE@0..14
+ LABEL_REFERENCE@0..14
+ LABEL_REFERENCE_NAME@0..4 "\\ref"
+ CURLY_GROUP_WORD_LIST@4..14
+ L_CURLY@4..5 "{"
+ WORD@5..8 "foo"
+ COMMA@8..9 ","
+ WHITESPACE@9..10 " "
+ WORD@10..13 "bar"
+ R_CURLY@13..14 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap
new file mode 100644
index 0000000000..2894a9c2ec
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap
@@ -0,0 +1,18 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\crefrange{foo{bar}\"#)"
+
+---
+ROOT@0..19
+ PREAMBLE@0..19
+ LABEL_REFERENCE_RANGE@0..19
+ LABEL_REFERENCE_RANGE_NAME@0..10 "\\crefrange"
+ CURLY_GROUP_WORD@10..14
+ L_CURLY@10..11 "{"
+ WORD@11..14 "foo"
+ MISSING@14..14 ""
+ CURLY_GROUP_WORD@14..19
+ L_CURLY@14..15 "{"
+ WORD@15..18 "bar"
+ R_CURLY@18..19 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap
new file mode 100644
index 0000000000..0a1753867e
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\crefrange{foo}\"#)"
+
+---
+ROOT@0..15
+ PREAMBLE@0..15
+ LABEL_REFERENCE_RANGE@0..15
+ LABEL_REFERENCE_RANGE_NAME@0..10 "\\crefrange"
+ CURLY_GROUP_WORD@10..15
+ L_CURLY@10..11 "{"
+ WORD@11..14 "foo"
+ R_CURLY@14..15 "}"
+ MISSING@15..15 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap
new file mode 100644
index 0000000000..c06c31c1b7
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap
@@ -0,0 +1,18 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\crefrange{foo}{bar}\"#)"
+
+---
+ROOT@0..20
+ PREAMBLE@0..20
+ LABEL_REFERENCE_RANGE@0..20
+ LABEL_REFERENCE_RANGE_NAME@0..10 "\\crefrange"
+ CURLY_GROUP_WORD@10..15
+ L_CURLY@10..11 "{"
+ WORD@11..14 "foo"
+ R_CURLY@14..15 "}"
+ CURLY_GROUP_WORD@15..20
+ L_CURLY@15..16 "{"
+ WORD@16..19 "bar"
+ R_CURLY@19..20 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap
new file mode 100644
index 0000000000..ed06f5dfc1
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\ref{foo}\"#)"
+
+---
+ROOT@0..9
+ PREAMBLE@0..9
+ LABEL_REFERENCE@0..9
+ LABEL_REFERENCE_NAME@0..4 "\\ref"
+ CURLY_GROUP_WORD_LIST@4..9
+ L_CURLY@4..5 "{"
+ WORD@5..8 "foo"
+ R_CURLY@8..9 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap
new file mode 100644
index 0000000000..34565aa072
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\include{foo/bar}\"#)"
+
+---
+ROOT@0..17
+ PREAMBLE@0..17
+ LATEX_INCLUDE@0..17
+ LATEX_INCLUDE_NAME@0..8 "\\include"
+ CURLY_GROUP_WORD_LIST@8..17
+ L_CURLY@8..9 "{"
+ WORD@9..16 "foo/bar"
+ R_CURLY@16..17 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap
new file mode 100644
index 0000000000..208e898407
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\input{foo/bar.tex}\"#)"
+
+---
+ROOT@0..19
+ PREAMBLE@0..19
+ LATEX_INCLUDE@0..19
+ LATEX_INCLUDE_NAME@0..6 "\\input"
+ CURLY_GROUP_WORD_LIST@6..19
+ L_CURLY@6..7 "{"
+ WORD@7..18 "foo/bar.tex"
+ R_CURLY@18..19 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_no_impl.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_no_impl.snap
new file mode 100644
index 0000000000..2e39ee899c
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_no_impl.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\DeclareMathOperator{\\foo}\"#)"
+
+---
+ROOT@0..26
+ PREAMBLE@0..26
+ MATH_OPERATOR@0..26
+ MATH_OPERATOR_NAME@0..20 "\\DeclareMathOperator"
+ CURLY_GROUP_COMMAND@20..26
+ L_CURLY@20..21 "{"
+ GENERIC_COMMAND_NAME@21..25 "\\foo"
+ R_CURLY@25..26 "}"
+ MISSING@26..26 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_simple.snap
new file mode 100644
index 0000000000..bb44005153
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__math_operator_simple.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\DeclareMathOperator{\\foo}{foo}\"#)"
+
+---
+ROOT@0..31
+ PREAMBLE@0..31
+ MATH_OPERATOR@0..31
+ MATH_OPERATOR_NAME@0..20 "\\DeclareMathOperator"
+ CURLY_GROUP_COMMAND@20..26
+ L_CURLY@20..21 "{"
+ GENERIC_COMMAND_NAME@21..25 "\\foo"
+ R_CURLY@25..26 "}"
+ CURLY_GROUP@26..31
+ L_CURLY@26..27 "{"
+ TEXT@27..30
+ WORD@27..30 "foo"
+ R_CURLY@30..31 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_empty.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_empty.snap
new file mode 100644
index 0000000000..b8851b6e1d
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_empty.snap
@@ -0,0 +1,13 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\usepackage{}\"#)"
+
+---
+ROOT@0..13
+ PREAMBLE@0..13
+ PACKAGE_INCLUDE@0..13
+ PACKAGE_INCLUDE_NAME@0..11 "\\usepackage"
+ CURLY_GROUP_WORD_LIST@11..13
+ L_CURLY@11..12 "{"
+ R_CURLY@12..13 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap
new file mode 100644
index 0000000000..e68b98d1b5
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap
@@ -0,0 +1,17 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\usepackage{amsmath, lipsum}\"#)"
+
+---
+ROOT@0..28
+ PREAMBLE@0..28
+ PACKAGE_INCLUDE@0..28
+ PACKAGE_INCLUDE_NAME@0..11 "\\usepackage"
+ CURLY_GROUP_WORD_LIST@11..28
+ L_CURLY@11..12 "{"
+ WORD@12..19 "amsmath"
+ COMMA@19..20 ","
+ WHITESPACE@20..21 " "
+ WORD@21..27 "lipsum"
+ R_CURLY@27..28 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap
new file mode 100644
index 0000000000..a33c4e0bd7
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap
@@ -0,0 +1,37 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\usepackage[foo = bar, baz, qux]{amsmath}\"#)"
+
+---
+ROOT@0..41
+ PREAMBLE@0..41
+ PACKAGE_INCLUDE@0..41
+ PACKAGE_INCLUDE_NAME@0..11 "\\usepackage"
+ BRACK_GROUP_KEY_VALUE@11..32
+ L_BRACK@11..12 "["
+ KEY_VALUE_BODY@12..31
+ KEY_VALUE_PAIR@12..21
+ KEY@12..16
+ WORD@12..15 "foo"
+ WHITESPACE@15..16 " "
+ EQUALITY_SIGN@16..17 "="
+ WHITESPACE@17..18 " "
+ VALUE@18..21
+ TEXT@18..21
+ WORD@18..21 "bar"
+ COMMA@21..22 ","
+ WHITESPACE@22..23 " "
+ KEY_VALUE_PAIR@23..26
+ KEY@23..26
+ WORD@23..26 "baz"
+ COMMA@26..27 ","
+ WHITESPACE@27..28 " "
+ KEY_VALUE_PAIR@28..31
+ KEY@28..31
+ WORD@28..31 "qux"
+ R_BRACK@31..32 "]"
+ CURLY_GROUP_WORD_LIST@32..41
+ L_CURLY@32..33 "{"
+ WORD@33..40 "amsmath"
+ R_CURLY@40..41 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap
new file mode 100644
index 0000000000..00c075fdfe
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\usepackage{amsmath}\"#)"
+
+---
+ROOT@0..20
+ PREAMBLE@0..20
+ PACKAGE_INCLUDE@0..20
+ PACKAGE_INCLUDE_NAME@0..11 "\\usepackage"
+ CURLY_GROUP_WORD_LIST@11..20
+ L_CURLY@11..12 "{"
+ WORD@12..19 "amsmath"
+ R_CURLY@19..20 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter.snap
new file mode 100644
index 0000000000..8c6bd90cb8
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter.snap
@@ -0,0 +1,9 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"#1\"#)"
+
+---
+ROOT@0..2
+ PREAMBLE@0..2
+ PARAMETER@0..2 "#1"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter_error.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter_error.snap
new file mode 100644
index 0000000000..1a9b68fa2d
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__parameter_error.snap
@@ -0,0 +1,9 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"#\"#)"
+
+---
+ROOT@0..1
+ PREAMBLE@0..1
+ PARAMETER@0..1 "#"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap
new file mode 100644
index 0000000000..8f289f97a4
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\usepgflibrary{foo}\"#)"
+
+---
+ROOT@0..19
+ PREAMBLE@0..19
+ TIKZ_LIBRARY_IMPORT@0..19
+ TIKZ_LIBRARY_IMPORT_NAME@0..14 "\\usepgflibrary"
+ CURLY_GROUP_WORD_LIST@14..19
+ L_CURLY@14..15 "{"
+ WORD@15..18 "foo"
+ R_CURLY@18..19 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap
new file mode 100644
index 0000000000..43dcae1987
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap
@@ -0,0 +1,45 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\begin{enumerate} \\item 1 \\item[2] 2 \\item 3 \\end{enumerate}\"#)"
+
+---
+ROOT@0..60
+ PREAMBLE@0..60
+ ENVIRONMENT@0..60
+ BEGIN@0..18
+ BEGIN_ENVIRONMENT_NAME@0..6 "\\begin"
+ CURLY_GROUP_WORD@6..18
+ L_CURLY@6..7 "{"
+ WORD@7..16 "enumerate"
+ R_CURLY@16..17 "}"
+ WHITESPACE@17..18 " "
+ ENUM_ITEM@18..26
+ ENUM_ITEM_NAME@18..23 "\\item"
+ WHITESPACE@23..24 " "
+ TEXT@24..26
+ WORD@24..25 "1"
+ WHITESPACE@25..26 " "
+ ENUM_ITEM@26..37
+ ENUM_ITEM_NAME@26..31 "\\item"
+ BRACK_GROUP@31..35
+ L_BRACK@31..32 "["
+ TEXT@32..33
+ WORD@32..33 "2"
+ R_BRACK@33..34 "]"
+ WHITESPACE@34..35 " "
+ TEXT@35..37
+ WORD@35..36 "2"
+ WHITESPACE@36..37 " "
+ ENUM_ITEM@37..45
+ ENUM_ITEM_NAME@37..42 "\\item"
+ WHITESPACE@42..43 " "
+ TEXT@43..45
+ WORD@43..44 "3"
+ WHITESPACE@44..45 " "
+ END@45..60
+ END_ENVIRONMENT_NAME@45..49 "\\end"
+ CURLY_GROUP_WORD@49..60
+ L_CURLY@49..50 "{"
+ WORD@50..59 "enumerate"
+ R_CURLY@59..60 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_invalid_nesting.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_invalid_nesting.snap
new file mode 100644
index 0000000000..f999a50e9a
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_invalid_nesting.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\section{Foo} \\chapter{Bar}\"#)"
+
+---
+ROOT@0..27
+ PREAMBLE@0..27
+ SECTION@0..14
+ SECTION_NAME@0..8 "\\section"
+ CURLY_GROUP@8..14
+ L_CURLY@8..9 "{"
+ TEXT@9..12
+ WORD@9..12 "Foo"
+ R_CURLY@12..13 "}"
+ WHITESPACE@13..14 " "
+ CHAPTER@14..27
+ CHAPTER_NAME@14..22 "\\chapter"
+ CURLY_GROUP@22..27
+ L_CURLY@22..23 "{"
+ TEXT@23..26
+ WORD@23..26 "Bar"
+ R_CURLY@26..27 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_nested.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_nested.snap
new file mode 100644
index 0000000000..db5602e591
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_nested.snap
@@ -0,0 +1,57 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\part{1}\\chapter{2}\\section{3}\\subsection{4}\\subsubsection{5}\\paragraph{6}\\subparagraph{7}\"#)"
+
+---
+ROOT@0..90
+ PREAMBLE@0..90
+ PART@0..90
+ PART_NAME@0..5 "\\part"
+ CURLY_GROUP@5..8
+ L_CURLY@5..6 "{"
+ TEXT@6..7
+ WORD@6..7 "1"
+ R_CURLY@7..8 "}"
+ CHAPTER@8..90
+ CHAPTER_NAME@8..16 "\\chapter"
+ CURLY_GROUP@16..19
+ L_CURLY@16..17 "{"
+ TEXT@17..18
+ WORD@17..18 "2"
+ R_CURLY@18..19 "}"
+ SECTION@19..90
+ SECTION_NAME@19..27 "\\section"
+ CURLY_GROUP@27..30
+ L_CURLY@27..28 "{"
+ TEXT@28..29
+ WORD@28..29 "3"
+ R_CURLY@29..30 "}"
+ SUBSECTION@30..90
+ SUBSECTION_NAME@30..41 "\\subsection"
+ CURLY_GROUP@41..44
+ L_CURLY@41..42 "{"
+ TEXT@42..43
+ WORD@42..43 "4"
+ R_CURLY@43..44 "}"
+ SUBSUBSECTION@44..90
+ SUBSUBSECTION_NAME@44..58 "\\subsubsection"
+ CURLY_GROUP@58..61
+ L_CURLY@58..59 "{"
+ TEXT@59..60
+ WORD@59..60 "5"
+ R_CURLY@60..61 "}"
+ PARAGRAPH@61..90
+ PARAGRAPH_NAME@61..71 "\\paragraph"
+ CURLY_GROUP@71..74
+ L_CURLY@71..72 "{"
+ TEXT@72..73
+ WORD@72..73 "6"
+ R_CURLY@73..74 "}"
+ SUBPARAGRAPH@74..90
+ SUBPARAGRAPH_NAME@74..87 "\\subparagraph"
+ CURLY_GROUP@87..90
+ L_CURLY@87..88 "{"
+ TEXT@88..89
+ WORD@88..89 "7"
+ R_CURLY@89..90 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_siblings.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_siblings.snap
new file mode 100644
index 0000000000..94d2ef40bd
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_siblings.snap
@@ -0,0 +1,29 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\section{Foo} Foo \\section{Bar} Bar\"#)"
+
+---
+ROOT@0..35
+ PREAMBLE@0..35
+ SECTION@0..18
+ SECTION_NAME@0..8 "\\section"
+ CURLY_GROUP@8..14
+ L_CURLY@8..9 "{"
+ TEXT@9..12
+ WORD@9..12 "Foo"
+ R_CURLY@12..13 "}"
+ WHITESPACE@13..14 " "
+ TEXT@14..18
+ WORD@14..17 "Foo"
+ WHITESPACE@17..18 " "
+ SECTION@18..35
+ SECTION_NAME@18..26 "\\section"
+ CURLY_GROUP@26..32
+ L_CURLY@26..27 "{"
+ TEXT@27..30
+ WORD@27..30 "Bar"
+ R_CURLY@30..31 "}"
+ WHITESPACE@31..32 " "
+ TEXT@32..35
+ WORD@32..35 "Bar"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap
new file mode 100644
index 0000000000..863f27cf56
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap
@@ -0,0 +1,25 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\includesvg[scale=.5]{foo/bar.svg}\"#)"
+
+---
+ROOT@0..34
+ PREAMBLE@0..34
+ SVG_INCLUDE@0..34
+ SVG_INCLUDE_NAME@0..11 "\\includesvg"
+ BRACK_GROUP_KEY_VALUE@11..21
+ L_BRACK@11..12 "["
+ KEY_VALUE_BODY@12..20
+ KEY_VALUE_PAIR@12..20
+ KEY@12..17
+ WORD@12..17 "scale"
+ EQUALITY_SIGN@17..18 "="
+ VALUE@18..20
+ TEXT@18..20
+ WORD@18..20 ".5"
+ R_BRACK@20..21 "]"
+ CURLY_GROUP_WORD_LIST@21..34
+ L_CURLY@21..22 "{"
+ WORD@22..33 "foo/bar.svg"
+ R_CURLY@33..34 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap
new file mode 100644
index 0000000000..02db942d99
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\includesvg{foo/bar.svg}\"#)"
+
+---
+ROOT@0..24
+ PREAMBLE@0..24
+ SVG_INCLUDE@0..24
+ SVG_INCLUDE_NAME@0..11 "\\includesvg"
+ CURLY_GROUP_WORD_LIST@11..24
+ L_CURLY@11..12 "{"
+ WORD@12..23 "foo/bar.svg"
+ R_CURLY@23..24 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap
new file mode 100644
index 0000000000..d8fe3816ad
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap
@@ -0,0 +1,27 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newtheorem{foo}[bar]{Foo}[baz]\"#)"
+
+---
+ROOT@0..31
+ PREAMBLE@0..31
+ THEOREM_DEFINITION@0..31
+ THEOREM_DEFINITION_NAME@0..11 "\\newtheorem"
+ CURLY_GROUP_WORD@11..16
+ L_CURLY@11..12 "{"
+ WORD@12..15 "foo"
+ R_CURLY@15..16 "}"
+ BRACK_GROUP_WORD@16..21
+ L_BRACK@16..17 "["
+ WORD@17..20 "bar"
+ R_BRACK@20..21 "]"
+ CURLY_GROUP@21..26
+ L_CURLY@21..22 "{"
+ TEXT@22..25
+ WORD@22..25 "Foo"
+ R_CURLY@25..26 "}"
+ BRACK_GROUP_WORD@26..31
+ L_BRACK@26..27 "["
+ WORD@27..30 "baz"
+ R_BRACK@30..31 "]"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap
new file mode 100644
index 0000000000..9e550b19a4
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newtheorem{foo}[bar]\"#)"
+
+---
+ROOT@0..21
+ PREAMBLE@0..21
+ THEOREM_DEFINITION@0..21
+ THEOREM_DEFINITION_NAME@0..11 "\\newtheorem"
+ CURLY_GROUP_WORD@11..16
+ L_CURLY@11..12 "{"
+ WORD@12..15 "foo"
+ R_CURLY@15..16 "}"
+ BRACK_GROUP_WORD@16..21
+ L_BRACK@16..17 "["
+ WORD@17..20 "bar"
+ R_BRACK@20..21 "]"
+ MISSING@21..21 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap
new file mode 100644
index 0000000000..356dc079f1
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap
@@ -0,0 +1,19 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newtheorem{foo}{Foo}\"#)"
+
+---
+ROOT@0..21
+ PREAMBLE@0..21
+ THEOREM_DEFINITION@0..21
+ THEOREM_DEFINITION_NAME@0..11 "\\newtheorem"
+ CURLY_GROUP_WORD@11..16
+ L_CURLY@11..12 "{"
+ WORD@12..15 "foo"
+ R_CURLY@15..16 "}"
+ CURLY_GROUP@16..21
+ L_CURLY@16..17 "{"
+ TEXT@17..20
+ WORD@17..20 "Foo"
+ R_CURLY@20..21 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap
new file mode 100644
index 0000000000..cc6e34d378
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap
@@ -0,0 +1,23 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newtheorem{foo}[bar]{Foo}\"#)"
+
+---
+ROOT@0..26
+ PREAMBLE@0..26
+ THEOREM_DEFINITION@0..26
+ THEOREM_DEFINITION_NAME@0..11 "\\newtheorem"
+ CURLY_GROUP_WORD@11..16
+ L_CURLY@11..12 "{"
+ WORD@12..15 "foo"
+ R_CURLY@15..16 "}"
+ BRACK_GROUP_WORD@16..21
+ L_BRACK@16..17 "["
+ WORD@17..20 "bar"
+ R_BRACK@20..21 "]"
+ CURLY_GROUP@21..26
+ L_CURLY@21..22 "{"
+ TEXT@22..25
+ WORD@22..25 "Foo"
+ R_CURLY@25..26 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap
new file mode 100644
index 0000000000..27a040b7ff
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap
@@ -0,0 +1,15 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\newtheorem{foo}\"#)"
+
+---
+ROOT@0..16
+ PREAMBLE@0..16
+ THEOREM_DEFINITION@0..16
+ THEOREM_DEFINITION_NAME@0..11 "\\newtheorem"
+ CURLY_GROUP_WORD@11..16
+ L_CURLY@11..12 "{"
+ WORD@12..15 "foo"
+ R_CURLY@15..16 "}"
+ MISSING@16..16 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap
new file mode 100644
index 0000000000..4915306c55
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\usetikzlibrary{foo}\"#)"
+
+---
+ROOT@0..20
+ PREAMBLE@0..20
+ TIKZ_LIBRARY_IMPORT@0..20
+ TIKZ_LIBRARY_IMPORT_NAME@0..15 "\\usetikzlibrary"
+ CURLY_GROUP_WORD_LIST@15..20
+ L_CURLY@15..16 "{"
+ WORD@16..19 "foo"
+ R_CURLY@19..20 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_braces.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_braces.snap
new file mode 100644
index 0000000000..df463f501a
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_braces.snap
@@ -0,0 +1,13 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"}{\"#)"
+
+---
+ROOT@0..2
+ PREAMBLE@0..2
+ ERROR@0..1
+ R_CURLY@0..1 "}"
+ CURLY_GROUP@1..2
+ L_CURLY@1..2 "{"
+ MISSING@2..2 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets.snap
new file mode 100644
index 0000000000..578cbf6099
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets.snap
@@ -0,0 +1,13 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"][\"#)"
+
+---
+ROOT@0..2
+ PREAMBLE@0..2
+ ERROR@0..1
+ R_BRACK@0..1 "]"
+ MIXED_GROUP@1..2
+ L_BRACK@1..2 "["
+ MISSING@2..2 ""
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets_with_group.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets_with_group.snap
new file mode 100644
index 0000000000..d929c98c46
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__unmatched_brackets_with_group.snap
@@ -0,0 +1,16 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"{][}\"#)"
+
+---
+ROOT@0..4
+ PREAMBLE@0..4
+ CURLY_GROUP@0..4
+ L_CURLY@0..1 "{"
+ ERROR@1..2
+ R_BRACK@1..2 "]"
+ MIXED_GROUP@2..3
+ L_BRACK@2..3 "["
+ MISSING@3..3 ""
+ R_CURLY@3..4 "}"
+
diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap
new file mode 100644
index 0000000000..399e16d791
--- /dev/null
+++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap
@@ -0,0 +1,14 @@
+---
+source: src/syntax/latex/parser.rs
+expression: "setup(r#\"\\verbatiminput{foo/bar.txt}\"#)"
+
+---
+ROOT@0..27
+ PREAMBLE@0..27
+ VERBATIM_INCLUDE@0..27
+ VERBATIM_INCLUDE_NAME@0..14 "\\verbatiminput"
+ CURLY_GROUP_WORD_LIST@14..27
+ L_CURLY@14..15 "{"
+ WORD@15..26 "foo/bar.txt"
+ R_CURLY@26..27 "}"
+
diff --git a/support/texlab/src/syntax/latexindent.rs b/support/texlab/src/syntax/latexindent.rs
deleted file mode 100644
index c45c95d4e5..0000000000
--- a/support/texlab/src/syntax/latexindent.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use std::{io, process::Stdio};
-use tempfile::tempdir;
-use tokio::{fs, process::Command};
-
-pub async fn format(text: &str, extension: &str) -> io::Result<String> {
- let dir = tempdir()?;
- let input = format!("input.{}", extension);
- let output = format!("output.{}", extension);
- fs::write(dir.path().join(&input), text).await?;
-
- Command::new("latexindent")
- .args(&["-o", &output, &input])
- .current_dir(dir.path())
- .stdin(Stdio::null())
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .spawn()?
- .await?;
-
- fs::read_to_string(dir.path().join(&output)).await
-}
diff --git a/support/texlab/src/syntax/mod.rs b/support/texlab/src/syntax/mod.rs
deleted file mode 100644
index 87b33792df..0000000000
--- a/support/texlab/src/syntax/mod.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-pub mod bibtex;
-mod generic_ast;
-mod lang_data;
-pub mod latex;
-pub mod latexindent;
-mod lsp_kind;
-mod text;
-
-pub use self::{
- generic_ast::{Ast, AstNodeIndex},
- lang_data::*,
- lsp_kind::Structure,
- text::{CharStream, Span, SyntaxNode},
-};
diff --git a/support/texlab/src/syntax/text.rs b/support/texlab/src/syntax/text.rs
deleted file mode 100644
index 17d6876126..0000000000
--- a/support/texlab/src/syntax/text.rs
+++ /dev/null
@@ -1,260 +0,0 @@
-use crate::protocol::{Position, Range};
-use serde::{Deserialize, Serialize};
-use std::{iter::Peekable, str::CharIndices};
-
-pub trait SyntaxNode {
- fn range(&self) -> Range;
-
- fn start(&self) -> Position {
- self.range().start
- }
-
- fn end(&self) -> Position {
- self.range().end
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct Span {
- pub range: Range,
- pub text: String,
-}
-
-impl Span {
- pub fn new(range: Range, text: String) -> Self {
- Self { range, text }
- }
-}
-
-impl SyntaxNode for Span {
- fn range(&self) -> Range {
- self.range
- }
-}
-
-#[derive(Debug)]
-pub struct CharStream<'a> {
- text: &'a str,
- chars: Peekable<CharIndices<'a>>,
- pub current_position: Position,
- pub current_index: usize,
- start_position: Position,
- start_index: usize,
-}
-
-impl<'a> CharStream<'a> {
- pub fn new(text: &'a str) -> Self {
- Self {
- text,
- chars: text.char_indices().peekable(),
- current_position: Position::new(0, 0),
- current_index: 0,
- start_position: Position::new(0, 0),
- start_index: 0,
- }
- }
-
- pub fn peek(&mut self) -> Option<char> {
- self.chars.peek().map(|(_, c)| *c)
- }
-
- pub fn satifies<P: FnOnce(&char) -> bool>(&mut self, predicate: P) -> bool {
- self.peek().filter(predicate).is_some()
- }
-
- pub fn skip_rest_of_line(&mut self) {
- loop {
- match self.peek() {
- Some('\n') => {
- self.next();
- break;
- }
- Some(_) => {
- self.next();
- }
- None => {
- break;
- }
- }
- }
- }
-
- pub fn start_span(&mut self) {
- self.start_index = self.current_index;
- self.start_position = self.current_position;
- }
-
- pub fn end_span(&mut self) -> Span {
- let range = Range::new(self.start_position, self.current_position);
- let text = &self.text[self.start_index..self.current_index];
- Span::new(range, text.to_owned())
- }
-
- pub fn seek(&mut self, position: Position) {
- while self.current_position < position {
- self.next();
- }
- }
-
- pub fn command(&mut self) -> Span {
- self.start_span();
- self.next();
- let mut escape = true;
- while self.satifies(|c| is_command_char(*c)) {
- self.next();
- escape = false;
- }
-
- if let Some(c) = self.peek() {
- if c != '\r' && c != '\n' && (escape || c == '*') {
- self.next();
- }
- }
-
- self.end_span()
- }
-
- fn update_position(&mut self, c: char) {
- if c == '\n' {
- self.current_position.line += 1;
- self.current_position.character = 0;
- } else {
- self.current_position.character += 1;
- }
- }
-
- pub fn extract(text: &'a str, range: Range) -> String {
- let mut stream = Self::new(text);
- stream.seek(range.start);
- stream.start_span();
- stream.seek(range.end);
- stream.end_span().text
- }
-}
-
-impl<'a> Iterator for CharStream<'a> {
- type Item = char;
-
- fn next(&mut self) -> Option<char> {
- if let Some((i, c)) = self.chars.next() {
- self.current_index = i + c.len_utf8();
- self.update_position(c);
- Some(c)
- } else {
- None
- }
- }
-}
-
-fn is_command_char(c: char) -> bool {
- c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '@'
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::protocol::RangeExt;
-
- #[test]
- fn peek() {
- let mut stream = CharStream::new("ab\nc");
- assert_eq!(Some('a'), stream.peek());
- assert_eq!(Some('a'), stream.next());
- assert_eq!(Some('b'), stream.peek());
- assert_eq!(Some('b'), stream.next());
- assert_eq!(Some('\n'), stream.peek());
- assert_eq!(Some('\n'), stream.next());
- assert_eq!(Some('c'), stream.peek());
- assert_eq!(Some('c'), stream.next());
- assert_eq!(None, stream.peek());
- assert_eq!(None, stream.next());
- }
-
- #[test]
- fn span() {
- let mut stream = CharStream::new("abc\ndef");
- stream.next();
- stream.start_span();
- stream.next();
- stream.next();
- let span = stream.end_span();
- assert_eq!(
- Span::new(Range::new_simple(0, 1, 0, 3), "bc".to_owned()),
- span
- );
- assert_eq!(Position::new(0, 1), span.start());
- assert_eq!(Position::new(0, 3), span.end());
- }
-
- #[test]
- fn span_unicode() {
- let mut stream = CharStream::new("😀😃😄😁");
- stream.next();
- stream.start_span();
- stream.next();
- stream.next();
- let span = stream.end_span();
- assert_eq!(
- Span::new(Range::new_simple(0, 1, 0, 3), "😃😄".to_owned()),
- span
- );
- }
-
- #[test]
- fn satifies() {
- let mut stream = CharStream::new("aBc");
- assert_eq!(true, stream.satifies(|c| c.is_lowercase()));
- stream.next();
- assert_eq!(false, stream.satifies(|c| c.is_lowercase()));
- }
-
- #[test]
- fn skip_rest_of_line() {
- let mut stream = CharStream::new("abc\ndef");
- stream.skip_rest_of_line();
- assert_eq!(Some('d'), stream.next());
- stream.skip_rest_of_line();
- assert_eq!(None, stream.next());
- stream.skip_rest_of_line();
- assert_eq!(None, stream.next());
- }
-
- #[test]
- fn seek() {
- let mut stream = CharStream::new("abc\ndefghi");
- let pos = Position::new(1, 2);
- stream.seek(pos);
- assert_eq!(Some('f'), stream.peek());
- }
-
- #[test]
- fn command_basic() {
- let mut stream = CharStream::new("\\foo@bar");
- let span = stream.command();
- assert_eq!(
- Span::new(Range::new_simple(0, 0, 0, 8), "\\foo@bar".to_owned()),
- span
- );
- }
-
- #[test]
- fn command_star() {
- let mut stream = CharStream::new("\\foo*");
- let span = stream.command();
- assert_eq!(
- Span::new(Range::new_simple(0, 0, 0, 5), "\\foo*".to_owned()),
- span
- );
- }
-
- #[test]
- fn command_escape() {
- let mut stream = CharStream::new("\\**");
- let span = stream.command();
- assert_eq!(
- Span::new(Range::new_simple(0, 0, 0, 2), "\\*".to_owned()),
- span
- );
- }
-}
diff --git a/support/texlab/src/test/client.rs b/support/texlab/src/test/client.rs
deleted file mode 100644
index b8806cc933..0000000000
--- a/support/texlab/src/test/client.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use crate::protocol::*;
-use jsonrpc::client::Result;
-use jsonrpc_derive::{jsonrpc_client, jsonrpc_method};
-
-#[jsonrpc_client(TestLatexLspClient)]
-pub trait TestLspClient {
- #[jsonrpc_method("initialize", kind = "request")]
- async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult>;
-
- #[jsonrpc_method("initialized", kind = "notification")]
- async fn initialized(&self, params: InitializedParams);
-
- #[jsonrpc_method("shutdown", kind = "request")]
- async fn shutdown(&self, params: ()) -> Result<()>;
-
- #[jsonrpc_method("exit", kind = "notification")]
- async fn exit(&self, params: ());
-
- #[jsonrpc_method("textDocument/didOpen", kind = "notification")]
- async fn did_open(&self, params: DidOpenTextDocumentParams);
-
- #[jsonrpc_method("textDocument/didChange", kind = "notification")]
- async fn did_change(&self, params: DidChangeTextDocumentParams);
-
- #[jsonrpc_method("workspace/didChangeConfiguration", kind = "notification")]
- async fn did_change_configuration(&self, params: DidChangeConfigurationParams);
-
- #[jsonrpc_method("textDocument/definition", kind = "request")]
- async fn definition(&self, params: TextDocumentPositionParams) -> Result<DefinitionResponse>;
-
- #[jsonrpc_method("textDocument/completion", kind = "request")]
- async fn completion(&self, params: CompletionParams) -> Result<CompletionList>;
-
- #[jsonrpc_method("completionItem/resolve", kind = "request")]
- async fn completion_resolve(&self, item: CompletionItem) -> Result<CompletionItem>;
-
- #[jsonrpc_method("textDocument/foldingRange", kind = "request")]
- async fn folding_range(&self, params: FoldingRangeParams) -> Result<Vec<FoldingRange>>;
-
- #[jsonrpc_method("textDocument/documentHighlight", kind = "request")]
- async fn document_highlight(
- &self,
- params: TextDocumentPositionParams,
- ) -> Result<Vec<DocumentHighlight>>;
-
- #[jsonrpc_method("textDocument/documentLink", kind = "request")]
- async fn document_link(&self, params: DocumentLinkParams) -> Result<Vec<DocumentLink>>;
-
- #[jsonrpc_method("textDocument/references", kind = "request")]
- async fn references(&self, params: ReferenceParams) -> Result<Vec<Location>>;
-
- #[jsonrpc_method("textDocument/prepareRename", kind = "request")]
- async fn prepare_rename(&self, params: TextDocumentPositionParams) -> Result<Option<Range>>;
-
- #[jsonrpc_method("textDocument/rename", kind = "request")]
- async fn rename(&self, params: RenameParams) -> Result<Option<WorkspaceEdit>>;
-
- #[jsonrpc_method("textDocument/hover", kind = "request")]
- async fn hover(&self, params: TextDocumentPositionParams) -> Result<Option<Hover>>;
-
- #[jsonrpc_method("workspace/symbol", kind = "request")]
- async fn workspace_symbol(
- &self,
- params: WorkspaceSymbolParams,
- ) -> Result<Vec<SymbolInformation>>;
-
- #[jsonrpc_method("textDocument/documentSymbol", kind = "request")]
- async fn document_symbol(&self, params: DocumentSymbolParams)
- -> Result<DocumentSymbolResponse>;
-
- #[jsonrpc_method("$/detectRoot", kind = "request")]
- async fn detect_root(&self, params: TextDocumentIdentifier) -> Result<()>;
-}
diff --git a/support/texlab/src/test/mod.rs b/support/texlab/src/test/mod.rs
deleted file mode 100644
index 5f26fb0dcc..0000000000
--- a/support/texlab/src/test/mod.rs
+++ /dev/null
@@ -1,632 +0,0 @@
-#![allow(deprecated)]
-
-mod client;
-mod server;
-
-pub use self::{
- client::{TestLatexLspClient, TestLspClient},
- server::TestLatexLspServer,
-};
-
-use crate::{
- protocol::*,
- server::LatexLspServer,
- tex::{Distribution, UnknownDistribution},
-};
-use futures::{
- channel::mpsc,
- future::{join, AbortHandle, Abortable},
- lock::Mutex,
- prelude::*,
-};
-use jsonrpc::MessageHandler;
-use once_cell::sync::Lazy;
-use std::{path::PathBuf, sync::Arc};
-use tempfile::{tempdir, TempDir};
-use tokio::fs;
-
-struct GlobalDistribution {
- distro: Mutex<Option<Arc<dyn Distribution>>>,
-}
-
-impl GlobalDistribution {
- fn new() -> Self {
- Self {
- distro: Mutex::new(None),
- }
- }
-
- async fn get(&self, use_distro: bool) -> Arc<dyn Distribution> {
- if use_distro {
- let mut distro_lock = self.distro.lock().await;
- match &*distro_lock {
- Some(distro) => distro.clone(),
- None => {
- let distro = Distribution::detect().await;
- *distro_lock = Some(distro.clone());
- distro
- }
- }
- } else {
- Arc::new(UnknownDistribution::default())
- }
- }
-}
-
-static DISTRO: Lazy<GlobalDistribution> = Lazy::new(GlobalDistribution::new);
-
-#[derive(Debug)]
-struct Endpoint<S, C> {
- receiver: mpsc::Receiver<String>,
- client: Arc<C>,
- server: Arc<S>,
- handler: MessageHandler<S, C>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct TestBedBuilder {
- files: Vec<(PathBuf, String)>,
- use_distro: bool,
- root_dir: Option<PathBuf>,
- latex_build: Option<LatexBuildOptions>,
- latex_lint: Option<LatexLintOptions>,
- latex_forward_search: Option<LatexForwardSearchOptions>,
- bibtex_formatting: Option<BibtexFormattingOptions>,
-}
-
-impl TestBedBuilder {
- pub fn new() -> Self {
- Self::default()
- }
-
- pub fn file<P: Into<PathBuf>>(&mut self, path: P, text: &str) -> &mut Self {
- self.files.push((path.into(), text.trim().into()));
- self
- }
-
- pub fn use_distro(&mut self) -> &mut Self {
- self.use_distro = true;
- self
- }
-
- pub fn root_dir<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
- self.root_dir = Some(path.into());
- self
- }
-
- pub fn latex_build(&mut self, options: LatexBuildOptions) -> &mut Self {
- self.latex_build = Some(options);
- self
- }
-
- pub fn latex_lint(&mut self, options: LatexLintOptions) -> &mut Self {
- self.latex_lint = Some(options);
- self
- }
-
- pub fn latex_forward_search(&mut self, options: LatexForwardSearchOptions) -> &mut Self {
- self.latex_forward_search = Some(options);
- self
- }
-
- pub fn bibtex_formatting(&mut self, options: BibtexFormattingOptions) -> &mut Self {
- self.bibtex_formatting = Some(options);
- self
- }
-
- pub async fn build(&self) -> TestBed {
- let dir = tempdir().expect("failed to create temporary directory");
- for (path, text) in &self.files {
- let full_path = dir.path().join(path);
- fs::create_dir_all(full_path.parent().unwrap())
- .await
- .unwrap();
- fs::write(&full_path, text).await.unwrap();
- }
-
- let (tx1, rx1) = mpsc::channel(0);
- let (tx2, rx2) = mpsc::channel(0);
-
- let endpoint1 = self.build_endpoint1(&dir, tx2, rx1).await;
- let endpoint2 = self.build_endpoint2(&dir, tx1, rx2).await;
- let server = Arc::clone(&endpoint2.server);
- let client = Arc::clone(&endpoint2.client);
- TestBed {
- dir,
- server,
- client,
- endpoint1: Some(endpoint1),
- endpoint2: Some(endpoint2),
- handle: None,
- }
- }
-
- async fn build_endpoint1(
- &self,
- dir: &TempDir,
- tx2: mpsc::Sender<String>,
- rx1: mpsc::Receiver<String>,
- ) -> Endpoint<LatexLspServer<LatexLspClient>, LatexLspClient> {
- let client = Arc::new(LatexLspClient::new(tx2.clone()));
- let server = Arc::new(LatexLspServer::new(
- DISTRO.get(self.use_distro).await,
- Arc::clone(&client),
- Arc::new(dir.path().to_path_buf()),
- ));
-
- Endpoint {
- receiver: rx1,
- client: Arc::clone(&client),
- server: Arc::clone(&server),
- handler: MessageHandler {
- client,
- server,
- output: tx2.clone(),
- },
- }
- }
-
- async fn build_endpoint2(
- &self,
- dir: &TempDir,
- tx1: mpsc::Sender<String>,
- rx2: mpsc::Receiver<String>,
- ) -> Endpoint<TestLatexLspServer, TestLatexLspClient> {
- let options = Options {
- latex: Some(LatexOptions {
- root_directory: self.root_dir.as_ref().map(|path| dir.path().join(path)),
- build: self.latex_build.clone(),
- forward_search: self.latex_forward_search.clone(),
- lint: self.latex_lint.clone(),
- }),
- bibtex: Some(BibtexOptions {
- formatting: self.bibtex_formatting.clone(),
- }),
- };
-
- let test_client = Arc::new(TestLatexLspClient::new(tx1.clone()));
- let test_server = Arc::new(TestLatexLspServer::new(options));
-
- Endpoint {
- receiver: rx2,
- client: Arc::clone(&test_client),
- server: Arc::clone(&test_server),
- handler: MessageHandler {
- client: test_client,
- server: test_server,
- output: tx1,
- },
- }
- }
-}
-
-pub struct TestBed {
- pub dir: TempDir,
- pub server: Arc<TestLatexLspServer>,
- pub client: Arc<TestLatexLspClient>,
- endpoint1: Option<Endpoint<LatexLspServer<LatexLspClient>, LatexLspClient>>,
- endpoint2: Option<Endpoint<TestLatexLspServer, TestLatexLspClient>>,
- handle: Option<AbortHandle>,
-}
-
-impl TestBed {
- pub fn spawn(&mut self) {
- let (handle, reg) = AbortHandle::new_pair();
-
- let endpoint1 = self.endpoint1.take().unwrap();
- let endpoint2 = self.endpoint2.take().unwrap();
- let mut rx1 = endpoint1.receiver;
- let mut rx2 = endpoint2.receiver;
- let mut handler1 = endpoint1.handler;
- let mut handler2 = endpoint2.handler;
-
- tokio::spawn(Abortable::new(
- async move {
- let task1 = async move {
- while let Some(json) = rx2.next().await {
- handler2.handle(&json).await;
- }
- };
-
- let task2 = async move {
- while let Some(json) = rx1.next().await {
- handler1.handle(&json).await;
- }
- };
-
- join(task1, task2).await;
- },
- reg,
- ));
- self.handle = Some(handle);
- }
-
- pub async fn initialize(&self, capabilities: ClientCapabilities) {
- self.client
- .initialize(InitializeParams {
- capabilities,
- initialization_options: None,
- process_id: None,
- root_path: None,
- root_uri: None,
- trace: None,
- workspace_folders: None,
- client_info: None,
- })
- .await
- .unwrap();
- self.client.initialized(InitializedParams {}).await;
- }
-
- pub fn path(&self, relative_path: &str) -> PathBuf {
- self.dir.path().join(relative_path)
- }
-
- pub fn uri(&self, relative_path: &str) -> Uri {
- Uri::from_file_path(self.path(relative_path)).unwrap()
- }
-
- pub fn identifier(&self, relative_path: &str) -> TextDocumentIdentifier {
- TextDocumentIdentifier::new(self.uri(relative_path).into())
- }
-
- pub async fn open(&self, relative_path: &str) {
- let full_path = self.path(relative_path);
- let params = DidOpenTextDocumentParams {
- text_document: TextDocumentItem {
- language_id: if relative_path.ends_with("bib") {
- "bibtex".into()
- } else {
- "latex".into()
- },
- uri: Uri::from_file_path(&full_path).unwrap().into(),
- version: 0,
- text: fs::read_to_string(&full_path).await.unwrap(),
- },
- };
- self.client.did_open(params).await;
- }
-
- pub async fn edit<S: Into<String>>(&self, relative_path: &str, text: S) {
- let uri = self.uri(relative_path).into();
- let params = DidChangeTextDocumentParams {
- text_document: VersionedTextDocumentIdentifier::new(uri, 0),
- content_changes: vec![TextDocumentContentChangeEvent {
- range: None,
- range_length: None,
- text: text.into(),
- }],
- };
- self.client.did_change(params).await;
- }
-
- pub async fn push_options(&self) {
- let options = self.server.options.lock().await.clone();
- let params = DidChangeConfigurationParams {
- settings: serde_json::to_value::<Options>(options).unwrap(),
- };
- self.client.did_change_configuration(params).await
- }
-
- pub async fn definition_link(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<LocationLink>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- let response = self.client.definition(params).await.ok()?;
- match response {
- DefinitionResponse::LocationLinks(links) => Some(links),
- DefinitionResponse::Locations(_) => unreachable!(),
- }
- }
-
- pub async fn definition_location(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<Location>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- let response = self.client.definition(params).await.ok()?;
- match response {
- DefinitionResponse::LocationLinks(_) => unreachable!(),
- DefinitionResponse::Locations(locations) => Some(locations),
- }
- }
-
- pub async fn completion(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<CompletionItem>> {
- let params = CompletionParams {
- text_document_position: TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- },
- context: None,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client
- .completion(params)
- .await
- .ok()
- .map(|list| list.items)
- }
-
- pub async fn folding_range(&self, relative_path: &str) -> Option<Vec<FoldingRange>> {
- let params = FoldingRangeParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client.folding_range(params).await.ok()
- }
-
- pub async fn document_highlight(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<DocumentHighlight>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- self.client.document_highlight(params).await.ok()
- }
-
- pub async fn document_link(&self, relative_path: &str) -> Option<Vec<DocumentLink>> {
- let params = DocumentLinkParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client.document_link(params).await.ok()
- }
-
- pub async fn references(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- include_declaration: bool,
- ) -> Option<Vec<Location>> {
- let params = ReferenceParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(relative_path),
- Position::new(line, character),
- ),
- context: ReferenceContext {
- include_declaration,
- },
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client.references(params).await.ok()
- }
-
- pub async fn prepare_rename(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Option<Range>> {
- let pos = Position::new(line, character);
- let params = TextDocumentPositionParams::new(self.identifier(relative_path), pos);
- self.client.prepare_rename(params).await.ok()
- }
-
- pub async fn rename<S: Into<String>>(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- new_name: S,
- ) -> Option<Option<WorkspaceEdit>> {
- let params = RenameParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(relative_path),
- Position::new(line, character),
- ),
- new_name: new_name.into(),
- work_done_progress_params: WorkDoneProgressParams::default(),
- };
- self.client.rename(params).await.ok()
- }
-
- pub async fn document_symbol_flat(
- &self,
- relative_path: &str,
- ) -> Option<Vec<SymbolInformation>> {
- let params = DocumentSymbolParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- match self.client.document_symbol(params).await.ok()? {
- DocumentSymbolResponse::Flat(symbols) => Some(symbols),
- DocumentSymbolResponse::Nested(_) => unreachable!(),
- }
- }
-
- pub async fn document_symbol_nested(&self, relative_path: &str) -> Option<Vec<DocumentSymbol>> {
- let params = DocumentSymbolParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- match self.client.document_symbol(params).await.ok()? {
- DocumentSymbolResponse::Flat(_) => unreachable!(),
- DocumentSymbolResponse::Nested(symbols) => Some(symbols),
- }
- }
-
- pub async fn hover(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Option<Hover>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- self.client.hover(params).await.ok()
- }
-
- pub async fn detect_root(&self, relative_path: &str) {
- self.client
- .detect_root(self.identifier(relative_path))
- .await
- .unwrap();
- }
-
- pub async fn shutdown(&self) {
- self.client.shutdown(()).await.unwrap();
- self.client.exit(()).await;
- }
-}
-
-impl Drop for TestBed {
- fn drop(&mut self) {
- if let Some(handle) = self.handle.as_ref() {
- handle.abort();
- }
- }
-}
-
-pub static PULL_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: None,
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: Some(true),
- did_change_configuration: None,
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
-
-pub static PUSH_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: None,
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: None,
- did_change_configuration: Some(GenericCapability {
- dynamic_registration: Some(true),
- }),
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
-
-pub static NESTED_SYMBOL_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: Some(TextDocumentClientCapabilities {
- code_action: None,
- code_lens: None,
- color_provider: None,
- completion: None,
- declaration: None,
- definition: None,
- document_highlight: None,
- document_link: None,
- document_symbol: Some(DocumentSymbolCapability {
- hierarchical_document_symbol_support: Some(true),
- dynamic_registration: None,
- symbol_kind: None,
- }),
- folding_range: None,
- formatting: None,
- hover: None,
- implementation: None,
- on_type_formatting: None,
- publish_diagnostics: None,
- range_formatting: None,
- references: None,
- rename: None,
- signature_help: None,
- synchronization: None,
- type_definition: None,
- }),
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: Some(true),
- did_change_configuration: None,
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
-
-pub static LOCATION_LINK_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: Some(TextDocumentClientCapabilities {
- code_action: None,
- code_lens: None,
- color_provider: None,
- completion: None,
- declaration: None,
- definition: Some(GotoCapability {
- dynamic_registration: None,
- link_support: Some(true),
- }),
- document_highlight: None,
- document_link: None,
- document_symbol: None,
- folding_range: None,
- formatting: None,
- hover: None,
- implementation: None,
- on_type_formatting: None,
- publish_diagnostics: None,
- range_formatting: None,
- references: None,
- rename: None,
- signature_help: None,
- synchronization: None,
- type_definition: None,
- }),
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: Some(true),
- did_change_configuration: None,
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
diff --git a/support/texlab/src/test/server.rs b/support/texlab/src/test/server.rs
deleted file mode 100644
index 77bed68c07..0000000000
--- a/support/texlab/src/test/server.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-use crate::protocol::*;
-use aovec::Aovec;
-use async_trait::async_trait;
-use chashmap::CHashMap;
-use futures::lock::Mutex;
-use jsonrpc::server::{Middleware, Result};
-use jsonrpc_derive::{jsonrpc_method, jsonrpc_server};
-
-pub struct TestLatexLspServer {
- pub options: Mutex<Options>,
- pub show_message_buf: Aovec<ShowMessageParams>,
- pub register_capability_buf: Aovec<RegistrationParams>,
- pub diagnostics_by_uri: CHashMap<Uri, Vec<Diagnostic>>,
- pub progress_buf: Aovec<ProgressParams>,
- pub work_done_progress_create_buf: Aovec<WorkDoneProgressCreateParams>,
- pub log_message_buf: Aovec<LogMessageParams>,
-}
-
-#[jsonrpc_server]
-impl TestLatexLspServer {
- pub fn new(options: Options) -> Self {
- let base = 16;
- Self {
- options: Mutex::new(options),
- show_message_buf: Aovec::new(base),
- register_capability_buf: Aovec::new(base),
- diagnostics_by_uri: CHashMap::new(),
- progress_buf: Aovec::new(base),
- work_done_progress_create_buf: Aovec::new(base),
- log_message_buf: Aovec::new(base),
- }
- }
-
- #[jsonrpc_method("workspace/configuration", kind = "request")]
- pub async fn configuration(&self, params: ConfigurationParams) -> Result<serde_json::Value> {
- let options = self.options.lock().await;
- if params.items[0].section.as_ref().unwrap() == "latex" {
- Ok(serde_json::to_value(vec![options.latex.clone().unwrap_or_default()]).unwrap())
- } else {
- Ok(serde_json::to_value(vec![options.bibtex.clone().unwrap_or_default()]).unwrap())
- }
- }
-
- #[jsonrpc_method("window/showMessage", kind = "notification")]
- pub async fn show_message(&self, params: ShowMessageParams) {
- self.show_message_buf.push(params);
- }
-
- #[jsonrpc_method("client/registerCapability", kind = "request")]
- pub async fn register_capability(&self, params: RegistrationParams) -> Result<()> {
- self.register_capability_buf.push(params);
- Ok(())
- }
-
- #[jsonrpc_method("textDocument/publishDiagnostics", kind = "notification")]
- pub async fn publish_diagnostics(&self, params: PublishDiagnosticsParams) {
- let _ = self
- .diagnostics_by_uri
- .insert(params.uri.into(), params.diagnostics);
- }
-
- #[jsonrpc_method("$/progress", kind = "notification")]
- pub async fn progress(&self, params: ProgressParams) {
- self.progress_buf.push(params);
- }
-
- #[jsonrpc_method("window/workDoneProgress/create", kind = "request")]
- pub async fn work_done_progress_create(
- &self,
- params: WorkDoneProgressCreateParams,
- ) -> Result<()> {
- self.work_done_progress_create_buf.push(params);
- Ok(())
- }
-
- #[jsonrpc_method("window/logMessage", kind = "notification")]
- pub async fn log_message(&self, params: LogMessageParams) {
- self.log_message_buf.push(params);
- }
-}
-
-#[async_trait]
-impl Middleware for TestLatexLspServer {
- async fn before_message(&self) {}
-
- async fn after_message(&self) {}
-}
diff --git a/support/texlab/src/tex/compile.rs b/support/texlab/src/tex/compile.rs
deleted file mode 100644
index a2b0d2f37d..0000000000
--- a/support/texlab/src/tex/compile.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use std::{io, process::Stdio, time::Duration};
-use tempfile::{tempdir, TempDir};
-use thiserror::Error;
-use tokio::{
- fs,
- process::Command,
- time::{timeout, Elapsed},
-};
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum Format {
- Latex,
- Pdflatex,
- Xelatex,
- Lualatex,
-}
-
-impl Format {
- pub fn executable(self) -> &'static str {
- match self {
- Self::Latex => "latex",
- Self::Pdflatex => "pdflatex",
- Self::Xelatex => "xelatex",
- Self::Lualatex => "lualatex",
- }
- }
-}
-
-#[derive(Debug)]
-pub struct Artifacts {
- pub dir: TempDir,
- pub log: String,
-}
-
-#[derive(Debug, Error)]
-pub enum CompileError {
- #[error("an I/O error occurred: `{0}`")]
- IO(#[from] io::Error),
- #[error("TeX engine is not installed")]
- NotInstalled,
- #[error("build timeout: `{0}`")]
- Timeout(#[from] Elapsed),
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct CompileParams<'a> {
- pub format: Format,
- pub file_name: &'a str,
- pub code: &'a str,
- pub timeout: Duration,
-}
-
-impl<'a> Default for CompileParams<'a> {
- fn default() -> Self {
- Self {
- format: Format::Lualatex,
- file_name: "code.tex",
- code: "",
- timeout: Duration::from_secs(15),
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub struct Compiler<'a> {
- pub executable: &'a str,
- pub args: &'a [&'a str],
- pub file_name: &'a str,
- pub timeout: Duration,
-}
-
-impl<'a> Compiler<'a> {
- pub async fn compile<'b>(&'a self, code: &'b str) -> Result<Artifacts, CompileError> {
- let directory = tempdir()?;
- let tex_file = directory.path().join(self.file_name);
- fs::write(&tex_file, code).await?;
-
- let child = Command::new(self.executable)
- .args(self.args)
- .current_dir(&directory)
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .status();
-
- timeout(self.timeout, child)
- .await?
- .map_err(|_| CompileError::NotInstalled)?;
-
- let log_file = tex_file.with_extension("log");
- let log_bytes = fs::read(log_file).await?;
- let log = String::from_utf8_lossy(&log_bytes).into_owned();
- Ok(Artifacts {
- dir: directory,
- log,
- })
- }
-}
diff --git a/support/texlab/src/tex/kpsewhich.rs b/support/texlab/src/tex/kpsewhich.rs
deleted file mode 100644
index cb2ab89de5..0000000000
--- a/support/texlab/src/tex/kpsewhich.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-use super::Language;
-use futures::Future;
-use std::{
- collections::HashMap,
- env,
- ffi::OsStr,
- io,
- path::{Path, PathBuf},
- string::FromUtf8Error,
-};
-use thiserror::Error;
-use tokio::{fs, process::Command};
-
-#[derive(Debug, Error)]
-pub enum KpsewhichError {
- #[error("an I/O error occurred: `{0}`")]
- IO(#[from] io::Error),
- #[error("an utf8 error occurred: `{0}`")]
- Decode(#[from] FromUtf8Error),
- #[error("invalid output from kpsewhich")]
- InvalidOutput,
- #[error("kpsewhich not installed")]
- NotInstalled,
- #[error("no kpsewhich database")]
- NoDatabase,
- #[error("corrupt kpsewhich database")]
- CorruptDatabase,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct Resolver {
- pub files_by_name: HashMap<String, PathBuf>,
-}
-
-impl Resolver {
- pub fn new(files_by_name: HashMap<String, PathBuf>) -> Self {
- Self { files_by_name }
- }
-}
-
-pub async fn parse_database<'a, R, F>(
- root_directories: &'a [PathBuf],
- reader: R,
-) -> Result<Resolver, KpsewhichError>
-where
- R: Fn(&'a Path) -> F,
- F: Future<Output = Result<Vec<PathBuf>, KpsewhichError>>,
-{
- let mut files_by_name = HashMap::new();
- for directory in root_directories {
- for path in reader(directory).await? {
- if is_tex_file(&path) {
- if let Some(path) = make_absolute(root_directories, &path).await {
- if let Some(name) = path
- .file_name()
- .and_then(OsStr::to_str)
- .map(ToString::to_string)
- {
- files_by_name.insert(name, path);
- }
- }
- }
- }
- }
- Ok(Resolver::new(files_by_name))
-}
-
-fn is_tex_file(path: &Path) -> bool {
- path.extension()
- .and_then(OsStr::to_str)
- .and_then(Language::by_extension)
- .is_some()
-}
-
-async fn make_absolute(root_directories: &[PathBuf], relative_path: &Path) -> Option<PathBuf> {
- for dir in root_directories.iter().rev() {
- if let Ok(path) = fs::canonicalize(dir.join(&relative_path)).await {
- return Some(path);
- }
- }
- None
-}
-
-pub async fn root_directories() -> Result<Vec<PathBuf>, KpsewhichError> {
- let texmf = run(&["-var-value", "TEXMF"]).await?;
- let expand_arg = format!("--expand-braces={}", texmf);
- let expanded = run(&[&expand_arg]).await?;
- let directories = env::split_paths(&expanded.replace("!", ""))
- .filter(|path| path.exists())
- .collect();
- Ok(directories)
-}
-
-async fn run<I, S>(args: I) -> Result<String, KpsewhichError>
-where
- I: IntoIterator<Item = S>,
- S: AsRef<OsStr>,
-{
- let output = Command::new("kpsewhich")
- .args(args)
- .output()
- .await
- .map_err(|_| KpsewhichError::NotInstalled)?;
-
- let result = String::from_utf8(output.stdout)?
- .lines()
- .next()
- .ok_or(KpsewhichError::InvalidOutput)?
- .into();
-
- Ok(result)
-}
diff --git a/support/texlab/src/tex/mod.rs b/support/texlab/src/tex/mod.rs
deleted file mode 100644
index 59318f9d22..0000000000
--- a/support/texlab/src/tex/mod.rs
+++ /dev/null
@@ -1,154 +0,0 @@
-mod compile;
-mod kpsewhich;
-mod miktex;
-mod tectonic;
-mod texlive;
-
-pub use self::{
- compile::{Artifacts, CompileError, CompileParams, Format},
- kpsewhich::{KpsewhichError, Resolver},
-};
-
-use self::{compile::Compiler, miktex::Miktex, tectonic::Tectonic, texlive::Texlive};
-use async_trait::async_trait;
-use std::{fmt, process::Stdio, sync::Arc};
-use tokio::process::Command;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum DistributionKind {
- Texlive,
- Miktex,
- Tectonic,
- Unknown,
-}
-
-impl fmt::Display for DistributionKind {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let name = match self {
- Self::Texlive => "TeXLive",
- Self::Miktex => "MikTeX",
- Self::Tectonic => "Tectonic",
- Self::Unknown => "Unknown",
- };
- write!(f, "{}", name)
- }
-}
-
-impl DistributionKind {
- pub async fn detect() -> Self {
- if Command::new("tectonic")
- .arg("--version")
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .status()
- .await
- .is_ok()
- {
- return Self::Tectonic;
- }
-
- match Command::new("latex").arg("--version").output().await {
- Ok(output) => {
- let stdout = String::from_utf8_lossy(&output.stdout);
- if stdout.contains("TeX Live") {
- Self::Texlive
- } else if stdout.contains("MiKTeX") {
- Self::Miktex
- } else {
- Self::Unknown
- }
- }
- Err(_) => Self::Unknown,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum Language {
- Latex,
- Bibtex,
-}
-
-impl Language {
- pub fn by_extension(extension: &str) -> Option<Self> {
- match extension.to_lowercase().as_str() {
- "tex" | "sty" | "cls" | "def" | "lco" | "aux" | "rnw" => Some(Language::Latex),
- "bib" | "bibtex" => Some(Language::Bibtex),
- _ => None,
- }
- }
-
- pub fn by_language_id(language_id: &str) -> Option<Self> {
- match language_id {
- "latex" | "tex" => Some(Language::Latex),
- "bibtex" | "bib" => Some(Language::Bibtex),
- _ => None,
- }
- }
-}
-
-#[async_trait]
-pub trait Distribution: Send + Sync {
- fn kind(&self) -> DistributionKind;
-
- async fn compile<'a>(&'a self, params: CompileParams<'a>) -> Result<Artifacts, CompileError>;
-
- async fn load(&self) -> Result<(), KpsewhichError>;
-
- async fn resolver(&self) -> Arc<Resolver>;
-}
-
-impl dyn Distribution {
- pub async fn detect() -> Arc<dyn Distribution> {
- let kind = DistributionKind::detect().await;
- let distro: Arc<dyn Distribution + Send + Sync> = match kind {
- DistributionKind::Texlive => Arc::new(Texlive::default()),
- DistributionKind::Miktex => Arc::new(Miktex::default()),
- DistributionKind::Tectonic => Arc::new(Tectonic::default()),
- DistributionKind::Unknown => Arc::new(UnknownDistribution::default()),
- };
- distro
- }
-}
-
-impl fmt::Debug for dyn Distribution {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.kind())
- }
-}
-
-async fn compile(params: CompileParams<'_>) -> Result<Artifacts, CompileError> {
- let executable = params.format.executable();
- let args = &["--interaction=batchmode", "-shell-escape", params.file_name];
- let compiler = Compiler {
- executable,
- args,
- file_name: params.file_name,
- timeout: params.timeout,
- };
- compiler.compile(params.code).await
-}
-
-#[derive(Debug, Default)]
-pub struct UnknownDistribution {
- resolver: Arc<Resolver>,
-}
-
-#[async_trait]
-impl Distribution for UnknownDistribution {
- fn kind(&self) -> DistributionKind {
- DistributionKind::Unknown
- }
-
- async fn compile<'a>(&'a self, _params: CompileParams<'a>) -> Result<Artifacts, CompileError> {
- Err(CompileError::NotInstalled)
- }
-
- async fn load(&self) -> Result<(), KpsewhichError> {
- Ok(())
- }
-
- async fn resolver(&self) -> Arc<Resolver> {
- Arc::clone(&self.resolver)
- }
-}
diff --git a/support/texlab/src/tex/tectonic.rs b/support/texlab/src/tex/tectonic.rs
deleted file mode 100644
index 1c19466830..0000000000
--- a/support/texlab/src/tex/tectonic.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use super::{
- compile::{Artifacts, CompileError, CompileParams, Compiler},
- kpsewhich::{KpsewhichError, Resolver},
- Distribution, DistributionKind,
-};
-use async_trait::async_trait;
-use std::sync::Arc;
-
-#[derive(Debug, Default)]
-pub struct Tectonic;
-
-#[async_trait]
-impl Distribution for Tectonic {
- fn kind(&self) -> DistributionKind {
- DistributionKind::Tectonic
- }
-
- async fn compile<'a>(&'a self, params: CompileParams<'a>) -> Result<Artifacts, CompileError> {
- let args = [params.file_name];
- let compiler = Compiler {
- executable: "tectonic",
- args: &args,
- file_name: params.file_name,
- timeout: params.timeout,
- };
- compiler.compile(params.code).await
- }
-
- async fn load(&self) -> Result<(), KpsewhichError> {
- Ok(())
- }
-
- async fn resolver(&self) -> Arc<Resolver> {
- Arc::new(Resolver::default())
- }
-}
diff --git a/support/texlab/src/tex/texlive.rs b/support/texlab/src/tex/texlive.rs
deleted file mode 100644
index 5afb763d9e..0000000000
--- a/support/texlab/src/tex/texlive.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-use super::{
- compile,
- kpsewhich::{self, KpsewhichError, Resolver},
- Artifacts, CompileError, CompileParams, Distribution, DistributionKind,
-};
-use async_trait::async_trait;
-use futures::lock::Mutex;
-use std::{
- io,
- path::{Path, PathBuf},
- str::Lines,
- sync::Arc,
-};
-use tokio::fs;
-
-#[derive(Debug, Default)]
-pub struct Texlive {
- resolver: Mutex<Arc<Resolver>>,
-}
-
-#[async_trait]
-impl Distribution for Texlive {
- fn kind(&self) -> DistributionKind {
- DistributionKind::Texlive
- }
-
- async fn compile<'a>(&'a self, params: CompileParams<'a>) -> Result<Artifacts, CompileError> {
- compile(params).await
- }
-
- async fn load(&self) -> Result<(), KpsewhichError> {
- let root_directories = kpsewhich::root_directories().await?;
- let resolver = kpsewhich::parse_database(&root_directories, read_database).await?;
- *self.resolver.lock().await = Arc::new(resolver);
- Ok(())
- }
-
- async fn resolver(&self) -> Arc<Resolver> {
- let resolver = self.resolver.lock().await;
- Arc::clone(&resolver)
- }
-}
-
-const DATABASE_PATH: &str = "ls-R";
-
-async fn read_database(directory: &Path) -> Result<Vec<PathBuf>, KpsewhichError> {
- let file = directory.join(DATABASE_PATH);
- if !file.is_file() {
- return Ok(Vec::new());
- }
-
- let text = fs::read_to_string(file)
- .await
- .map_err(|_| KpsewhichError::NoDatabase)?;
- parse_database(text.lines()).map_err(|_| KpsewhichError::CorruptDatabase)
-}
-
-fn parse_database(lines: Lines) -> io::Result<Vec<PathBuf>> {
- let mut paths = Vec::new();
- let mut directory = "";
-
- for line in lines.filter(|x| !x.trim().is_empty() && !x.starts_with('%')) {
- if line.ends_with(':') {
- directory = &line[..line.len() - 1];
- } else {
- let path = PathBuf::from(directory).join(line);
- paths.push(path);
- }
- }
- Ok(paths)
-}
diff --git a/support/texlab/src/protocol/uri.rs b/support/texlab/src/uri.rs
index e8dd1ba160..b1ae9073e7 100644
--- a/support/texlab/src/protocol/uri.rs
+++ b/support/texlab/src/uri.rs
@@ -1,11 +1,11 @@
-use lsp_types::{TextDocumentIdentifier, TextDocumentPositionParams};
-use serde::{Deserialize, Serialize};
use std::{
fmt,
hash::{Hash, Hasher},
ops::Deref,
path::Path,
};
+
+use serde::{Deserialize, Serialize};
use url::{ParseError, Url};
#[derive(Eq, Clone, Serialize, Deserialize)]
@@ -27,6 +27,10 @@ impl Uri {
Url::parse(input).map(|url| url.into())
}
+ pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Self, ()> {
+ Url::from_directory_path(path).map(|url| url.into())
+ }
+
pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Self, ()> {
Url::from_file_path(path).map(|url| url.into())
}
@@ -79,19 +83,3 @@ impl fmt::Display for Uri {
self.0.fmt(f)
}
}
-
-pub trait AsUri {
- fn as_uri(&self) -> Uri;
-}
-
-impl AsUri for TextDocumentIdentifier {
- fn as_uri(&self) -> Uri {
- self.uri.clone().into()
- }
-}
-
-impl AsUri for TextDocumentPositionParams {
- fn as_uri(&self) -> Uri {
- self.text_document.as_uri()
- }
-}
diff --git a/support/texlab/src/workspace.rs b/support/texlab/src/workspace.rs
index c3c2551325..12924e2cf4 100644
--- a/support/texlab/src/workspace.rs
+++ b/support/texlab/src/workspace.rs
@@ -1,964 +1,32 @@
-use crate::{
- components::COMPONENT_DATABASE,
- protocol::{Options, TextDocumentItem, Uri},
- syntax::{bibtex, latex, LatexIncludeKind},
- tex::{Distribution, Language, Resolver},
-};
-use futures::lock::Mutex;
-use log::{debug, error, warn};
-use petgraph::{graph::Graph, visit::Dfs};
-use std::{
- collections::HashMap,
- ffi::OsStr,
- hash::{Hash, Hasher},
- io,
- path::{Path, PathBuf},
- sync::Arc,
- time::SystemTime,
-};
-use thiserror::Error;
-use tokio::fs;
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct DocumentParams<'a> {
- pub uri: Uri,
- pub text: String,
- pub language: Language,
- pub resolver: &'a Resolver,
- pub options: &'a Options,
- pub current_dir: &'a Path,
-}
-
-#[derive(Debug, Clone)]
-pub enum DocumentContent {
- Latex(Box<latex::SymbolTable>),
- Bibtex(Box<bibtex::Tree>),
-}
-
-impl DocumentContent {
- pub fn as_latex(&self) -> Option<&latex::SymbolTable> {
- if let Self::Latex(table) = self {
- Some(&table)
- } else {
- None
- }
- }
-
- pub fn as_bibtex(&self) -> Option<&bibtex::Tree> {
- if let Self::Bibtex(tree) = self {
- Some(&tree)
- } else {
- None
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct Document {
- pub uri: Uri,
- pub text: String,
- pub content: DocumentContent,
- pub modified: SystemTime,
-}
-
-impl Document {
- pub fn is_file(&self) -> bool {
- self.uri.scheme() == "file"
- }
-
- pub fn open(params: DocumentParams) -> Self {
- let DocumentParams {
- uri,
- text,
- language,
- resolver,
- options,
- current_dir,
- } = params;
-
- let content = match language {
- Language::Latex => {
- let table = latex::open(latex::OpenParams {
- uri: &uri,
- text: &text,
- resolver,
- options,
- current_dir,
- });
- DocumentContent::Latex(Box::new(table))
- }
- Language::Bibtex => {
- let tree = bibtex::open(&text);
- DocumentContent::Bibtex(Box::new(tree))
- }
- };
-
- Self {
- uri,
- text,
- content,
- modified: SystemTime::now(),
- }
- }
-}
-
-impl PartialEq for Document {
- fn eq(&self, other: &Self) -> bool {
- self.uri == other.uri
- }
-}
-
-impl Eq for Document {}
-
-impl Hash for Document {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.uri.hash(state);
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct Snapshot(pub Vec<Arc<Document>>);
-
-impl Snapshot {
- pub fn new() -> Self {
- Self(Vec::new())
- }
-
- pub fn push(&mut self, doc: Document) {
- self.0.push(Arc::new(doc));
- }
-
- pub fn find(&self, uri: &Uri) -> Option<Arc<Document>> {
- self.0.iter().find(|doc| doc.uri == *uri).map(Arc::clone)
- }
-
- pub fn relations(
- &self,
- uri: &Uri,
- options: &Options,
- current_dir: &Path,
- ) -> Vec<Arc<Document>> {
- let mut graph = Graph::new_undirected();
- let mut indices_by_uri = HashMap::new();
- for document in &self.0 {
- indices_by_uri.insert(&document.uri, graph.add_node(document));
- }
-
- for parent in &self.0 {
- if let DocumentContent::Latex(table) = &parent.content {
- table
- .includes
- .iter()
- .flat_map(|include| include.all_targets.iter())
- .filter_map(|targets| targets.iter().find_map(|target| self.find(target)))
- .for_each(|child| {
- graph.add_edge(indices_by_uri[&parent.uri], indices_by_uri[&child.uri], ());
- });
-
- table
- .imports
- .iter()
- .flat_map(|import| import.targets.iter())
- .find_map(|target| self.find(target))
- .into_iter()
- .for_each(|child| {
- graph.add_edge(indices_by_uri[&parent.uri], indices_by_uri[&child.uri], ());
- });
-
- self.resolve_aux_targets(&parent.uri, options, current_dir, "aux")
- .into_iter()
- .flatten()
- .find_map(|target| self.find(&target))
- .into_iter()
- .for_each(|child| {
- graph.add_edge(indices_by_uri[&parent.uri], indices_by_uri[&child.uri], ());
- });
- }
- }
-
- let mut documents = Vec::new();
- if self.find(uri).is_some() {
- let mut dfs = Dfs::new(&graph, indices_by_uri[uri]);
- while let Some(index) = dfs.next(&graph) {
- documents.push(Arc::clone(&graph[index]));
- }
- }
- documents
- }
-
- pub fn parent(
- &self,
- uri: &Uri,
- options: &Options,
- current_dir: &Path,
- ) -> Option<Arc<Document>> {
- for doc in self.relations(uri, options, current_dir) {
- if let DocumentContent::Latex(table) = &doc.content {
- if table.is_standalone {
- return Some(doc);
- }
- }
- }
- None
- }
-
- pub fn parent_subfile(
- &self,
- uri: &Uri,
- options: &Options,
- current_dir: &Path,
- ) -> Option<Arc<Document>> {
- for doc in self.relations(uri, options, current_dir) {
- if let DocumentContent::Latex(table) = &doc.content {
- if table.is_standalone
- && !table.components.iter().any(|comp| comp == "subfiles.cls")
- {
- return Some(doc);
- }
- }
- }
- None
- }
-
- pub fn expand(&self, options: &Options, current_dir: &Path) -> Vec<Uri> {
- let mut unknown_targets = Vec::new();
- for parent in &self.0 {
- if let DocumentContent::Latex(table) = &parent.content {
- table
- .includes
- .iter()
- .filter(|include| Self::should_expand_include(&table, include))
- .flat_map(|include| include.all_targets.iter())
- .filter(|targets| targets.iter().all(|target| self.find(target).is_none()))
- .flatten()
- .for_each(|target| unknown_targets.push(target.clone()));
-
- table
- .imports
- .iter()
- .filter(|import| {
- import
- .targets
- .iter()
- .all(|target| self.find(target).is_none())
- })
- .flat_map(|import| import.targets.iter())
- .for_each(|target| unknown_targets.push(target.clone()));
-
- self.resolve_aux_targets(&parent.uri, options, current_dir, "aux")
- .into_iter()
- .filter(|targets| targets.iter().all(|target| self.find(target).is_none()))
- .flatten()
- .for_each(|target| unknown_targets.push(target));
- }
- }
- unknown_targets
- }
-
- fn should_expand_include(tree: &latex::Tree, include: &latex::Include) -> bool {
- match include.kind {
- LatexIncludeKind::Bibliography | LatexIncludeKind::Latex => true,
- LatexIncludeKind::Everything
- | LatexIncludeKind::Image
- | LatexIncludeKind::Pdf
- | LatexIncludeKind::Svg => false,
- LatexIncludeKind::Package | LatexIncludeKind::Class => !include
- .paths(tree)
- .into_iter()
- .all(|name| COMPONENT_DATABASE.contains(name.text())),
- }
- }
-
- pub fn resolve_aux_targets(
- &self,
- tex_uri: &Uri,
- options: &Options,
- current_dir: &Path,
- extension: &str,
- ) -> Option<Vec<Uri>> {
- let mut targets = Vec::new();
- targets.push(tex_uri.with_extension(extension)?);
- if tex_uri.scheme() == "file" {
- let tex_path = tex_uri.to_file_path().ok()?;
- let file_stem = tex_path.file_stem()?;
- let aux_name = format!("{}.{}", file_stem.to_str()?, extension);
-
- if let Some(root_dir) = options
- .latex
- .as_ref()
- .and_then(|opts| opts.root_directory.as_ref())
- {
- let path = current_dir.join(root_dir).join(&aux_name);
- targets.push(Uri::from_file_path(path).ok()?);
- }
-
- if let Some(build_dir) = options
- .latex
- .as_ref()
- .and_then(|opts| opts.build.as_ref())
- .and_then(|opts| opts.output_directory.as_ref())
- {
- let path = current_dir.join(build_dir).join(&aux_name);
- targets.push(Uri::from_file_path(path).ok()?);
- }
- }
- Some(targets)
- }
-}
-
-#[derive(Debug, Error)]
-pub enum WorkspaceLoadError {
- #[error("invalid language id")]
- UnknownLanguage,
- #[error("invalid file path")]
- InvalidPath,
- #[error("an I/O error occurred: `{0}`")]
- IO(#[from] io::Error),
-}
-
-pub struct Workspace {
- distro: Arc<dyn Distribution>,
- current_dir: Arc<PathBuf>,
- snapshot: Mutex<Arc<Snapshot>>,
-}
-
-impl Workspace {
- pub fn new(distro: Arc<dyn Distribution>, current_dir: Arc<PathBuf>) -> Self {
- Self {
- distro,
- current_dir,
- snapshot: Mutex::default(),
- }
- }
-
- pub async fn get(&self) -> Arc<Snapshot> {
- let snapshot = self.snapshot.lock().await;
- Arc::clone(&snapshot)
- }
-
- pub async fn add(&self, document: TextDocumentItem, options: &Options) {
- let language = match Language::by_language_id(&document.language_id) {
- Some(language) => language,
- None => {
- error!(
- "Invalid language id: {} ({})",
- &document.language_id, &document.uri,
- );
- return;
- }
- };
-
- debug!("Adding document: {}", document.uri);
- let mut snapshot = self.snapshot.lock().await;
- *snapshot = self
- .add_or_update(
- &snapshot,
- document.uri.into(),
- document.text,
- language,
- options,
- )
- .await;
- }
-
- pub async fn load(&self, path: &Path, options: &Options) -> Result<(), WorkspaceLoadError> {
- let language = match path
- .extension()
- .and_then(OsStr::to_str)
- .and_then(Language::by_extension)
- {
- Some(language) => language,
- None => {
- warn!("Could not determine language: {}", path.to_string_lossy());
- return Err(WorkspaceLoadError::UnknownLanguage);
- }
- };
-
- let uri = match Uri::from_file_path(path) {
- Ok(uri) => uri,
- Err(_) => {
- error!("Invalid path: {}", path.to_string_lossy());
- return Err(WorkspaceLoadError::InvalidPath);
- }
- };
-
- let text = match fs::read_to_string(path).await {
- Ok(text) => text,
- Err(why) => {
- warn!("Could not open file: {}", uri);
- return Err(WorkspaceLoadError::IO(why));
- }
- };
+mod api;
+mod children_expand;
+mod document;
+mod parent_expand;
+mod storage;
+mod watch;
- debug!("Loading document: {}", uri);
- let mut snapshot = self.snapshot.lock().await;
- *snapshot = self
- .add_or_update(&snapshot, uri, text, language, options)
- .await;
- Ok(())
- }
+use std::sync::Arc;
- pub async fn update(&self, uri: Uri, text: String, options: &Options) {
- let mut snapshot = self.snapshot.lock().await;
+use anyhow::Result;
- let old_document = match snapshot.0.iter().find(|x| x.uri == uri) {
- Some(document) => document,
- None => {
- warn!("Document not found: {}", uri);
- return;
- }
- };
+use crate::ServerContext;
- let language = match old_document.content {
- DocumentContent::Latex(_) => Language::Latex,
- DocumentContent::Bibtex(_) => Language::Bibtex,
- };
-
- *snapshot = self
- .add_or_update(&snapshot, uri, text, language, options)
- .await;
- }
-
- pub async fn reparse(&self, options: &Options) {
- let snapshot = self.get().await;
- for doc in &snapshot.0 {
- let language = match doc.content {
- DocumentContent::Latex(_) => Language::Latex,
- DocumentContent::Bibtex(_) => Language::Bibtex,
- };
-
- let mut snapshot = self.snapshot.lock().await;
- debug!("Reparsing document: {}", doc.uri);
- *snapshot = self
- .add_or_update(
- &snapshot,
- doc.uri.clone(),
- doc.text.clone(),
- language,
- options,
- )
- .await;
- }
- }
-
- pub async fn detect_root(&self, uri: &Uri, options: &Options) -> io::Result<()> {
- if uri.scheme() != "file" {
- return Ok(());
- }
-
- if let Ok(mut path) = uri.to_file_path() {
- while path.pop() {
- let snapshot = self.get().await;
- if snapshot
- .parent_subfile(&uri, &options, &self.current_dir)
- .is_some()
- {
- break;
- }
-
- let mut entries = fs::read_dir(&path).await?;
- while let Some(entry) = entries.next_entry().await? {
- if entry.file_type().await?.is_file() {
- let path = entry.path();
- if path
- .extension()
- .and_then(OsStr::to_str)
- .and_then(Language::by_extension)
- .is_some()
- {
- if let Ok(parent_uri) = Uri::from_file_path(&path) {
- if snapshot.find(&parent_uri).is_none() {
- let _ = self.load(&path, options).await;
- }
- }
- }
- }
- }
- }
- }
- Ok(())
- }
-
- pub async fn detect_children(&self, options: &Options) {
- loop {
- let mut changed = false;
-
- let snapshot = self.get().await;
- for path in snapshot
- .expand(&options, &self.current_dir)
- .into_iter()
- .filter(|uri| uri.scheme() == "file" && uri.fragment().is_none())
- .filter_map(|uri| uri.to_file_path().ok())
- {
- if path.exists() {
- changed |= self.load(&path, &options).await.is_ok();
- }
- }
-
- if !changed {
- break;
- }
- }
- }
-
- pub async fn reparse_all_if_newer(&self, options: &Options) {
- let snapshot = self.get().await;
- for doc in &snapshot.0 {
- if let Err(WorkspaceLoadError::IO(why)) = self.reparse_if_newer(doc, options).await {
- warn!("Reparsing document {} failed: {}", doc.uri, why);
- }
- }
- }
-
- async fn reparse_if_newer(
- &self,
- doc: &Document,
- options: &Options,
- ) -> Result<(), WorkspaceLoadError> {
- if !doc.is_file() {
- return Ok(());
- }
-
- if let Ok(path) = doc.uri.to_file_path() {
- let data = fs::metadata(&path).await?;
- if data.modified()? > doc.modified {
- self.load(&path, options).await?;
- }
- }
- Ok(())
- }
-
- async fn add_or_update(
- &self,
- snapshot: &Snapshot,
- uri: Uri,
- text: String,
- language: Language,
- options: &Options,
- ) -> Arc<Snapshot> {
- let resolver = self.distro.resolver().await;
- let document = Document::open(DocumentParams {
- uri,
- text,
- language,
- resolver: &resolver,
- options,
- current_dir: &self.current_dir,
- });
-
- let mut documents: Vec<Arc<Document>> = snapshot
- .0
- .iter()
- .filter(|x| x.uri != document.uri)
- .cloned()
- .collect();
+pub use self::{api::*, document::*};
+use self::{
+ children_expand::ChildrenExpander, parent_expand::ParentExpander, storage::Storage,
+ watch::DocumentWatcher,
+};
- documents.push(Arc::new(document));
- Arc::new(Snapshot(documents))
- }
+pub fn create_workspace_fast(context: Arc<ServerContext>) -> Result<impl Workspace> {
+ let workspace = Storage::new(context);
+ let workspace = ChildrenExpander::new(Arc::new(workspace));
+ Ok(workspace)
}
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::protocol::{LatexBuildOptions, LatexOptions};
- use itertools::Itertools;
- use std::env;
-
- fn create_simple_document(uri: &Uri, language: Language, text: &str) -> Arc<Document> {
- Arc::new(Document::open(DocumentParams {
- uri: uri.clone(),
- text: text.into(),
- language,
- resolver: &Resolver::default(),
- options: &Options::default(),
- current_dir: &env::current_dir().unwrap(),
- }))
- }
-
- #[test]
- fn relations_append_missing_extension() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar/baz.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#"\include{bar/baz}"#),
- create_simple_document(&uri2, Language::Latex, r#""#),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2]);
- }
-
- #[test]
- fn relations_parent_directory() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar/baz.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#""#),
- create_simple_document(&uri2, Language::Latex, r#"\input{../foo.tex}"#),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2]);
- }
-
- #[test]
- fn relations_invalid_include() {
- let uri = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![create_simple_document(
- &uri,
- Language::Latex,
- r#"\include{<foo>?|bar|:}"#,
- )];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri]);
- }
-
- #[test]
- fn relations_bibliography() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar.bib").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#"\addbibresource{bar.bib}"#),
- create_simple_document(&uri2, Language::Bibtex, r#""#),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri2, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri2, uri1]);
- }
-
- #[test]
- fn relations_unknown_include() {
- let uri = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![create_simple_document(
- &uri,
- Language::Latex,
- r#"\input{bar.tex}"#,
- )];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri]);
- }
-
- #[test]
- fn relations_include_cycle() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#"\include{bar}"#),
- create_simple_document(&uri2, Language::Latex, r#"\input{foo.tex}"#),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2]);
- }
-
- #[test]
- fn relations_same_parent() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar.tex").unwrap();
- let uri3 = Uri::parse("http://www.example.com/baz.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#"\input{bar.tex}\input{baz.tex}"#),
- create_simple_document(&uri2, Language::Latex, r#""#),
- create_simple_document(&uri3, Language::Latex, r#""#),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri3, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri3, uri1, uri2]);
- }
-
- #[test]
- fn relations_aux_default_options() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/foo.aux").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#""#),
- create_simple_document(&uri2, Language::Latex, r#""#),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2]);
- }
-
- #[test]
- fn relations_aux_output_directory() {
- let cwd = env::current_dir().unwrap();
- let options = Options {
- latex: Some(LatexOptions {
- build: Some(LatexBuildOptions {
- output_directory: Some(PathBuf::from("build")),
- ..LatexBuildOptions::default()
- }),
- ..LatexOptions::default()
- }),
- ..Options::default()
- };
-
- let uri1 = Uri::from_file_path(cwd.join("foo.tex")).unwrap();
- let uri2 = Uri::from_file_path(cwd.join("build/foo.aux")).unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- Arc::new(Document::open(DocumentParams {
- uri: uri1.clone(),
- text: String::new(),
- language: Language::Latex,
- resolver: &Resolver::default(),
- options: &options,
- current_dir: &cwd,
- })),
- Arc::new(Document::open(DocumentParams {
- uri: uri2.clone(),
- text: String::new(),
- language: Language::Latex,
- resolver: &Resolver::default(),
- options: &options,
- current_dir: &cwd,
- })),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &options, &cwd)
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2]);
- }
-
- #[test]
- fn relations_aux_root_directory() {
- let cwd = env::current_dir().unwrap();
- let options = Options {
- latex: Some(LatexOptions {
- root_directory: Some(PathBuf::from(".")),
- ..LatexOptions::default()
- }),
- ..Options::default()
- };
-
- let uri1 = Uri::from_file_path(cwd.join("src/foo.tex")).unwrap();
- let uri2 = Uri::from_file_path(cwd.join("foo.aux")).unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- Arc::new(Document::open(DocumentParams {
- uri: uri1.clone(),
- text: String::new(),
- language: Language::Latex,
- resolver: &Resolver::default(),
- options: &options,
- current_dir: &cwd,
- })),
- Arc::new(Document::open(DocumentParams {
- uri: uri2.clone(),
- text: String::new(),
- language: Language::Latex,
- resolver: &Resolver::default(),
- options: &options,
- current_dir: &cwd,
- })),
- ];
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &options, &cwd)
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2]);
- }
-
- #[test]
- fn relations_import() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar/baz.tex").unwrap();
- let uri3 = Uri::parse("http://www.example.com/bar/qux/foo-bar.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#"\import{bar/}{baz.tex}"#),
- create_simple_document(&uri2, Language::Latex, r#"\subimport{qux/}{foo-bar}"#),
- create_simple_document(&uri3, Language::Latex, r#""#),
- ];
-
- let actual_uris: Vec<_> = snapshot
- .relations(&uri1, &Options::default(), &env::current_dir().unwrap())
- .into_iter()
- .map(|doc| doc.uri.clone())
- .collect();
-
- assert_eq!(actual_uris, vec![uri1, uri2, uri3]);
- }
-
- #[test]
- fn parent() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#""#),
- create_simple_document(
- &uri2,
- Language::Latex,
- r#"\begin{document}\include{foo}\end{document}"#,
- ),
- ];
- let doc = snapshot
- .parent(&uri1, &Options::default(), &env::current_dir().unwrap())
- .unwrap();
- assert_eq!(doc.uri, uri2);
- }
-
- #[test]
- fn parent_nothing_found() {
- let uri1 = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/bar.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(&uri1, Language::Latex, r#""#),
- create_simple_document(&uri2, Language::Latex, r#"\begin{document}\end{document}"#),
- ];
- let doc = snapshot.parent(&uri1, &Options::default(), &env::current_dir().unwrap());
- assert_eq!(doc, None);
- }
-
- #[test]
- fn expand_aux_file() {
- let uri = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![create_simple_document(&uri, Language::Latex, r#""#)];
- let expansion = snapshot.expand(&Options::default(), &env::current_dir().unwrap());
- assert_eq!(
- expansion
- .iter()
- .map(|uri| uri.as_str())
- .filter(|uri| uri.ends_with(".aux"))
- .collect_vec(),
- vec!["http://www.example.com/foo.aux"]
- );
- }
-
- #[test]
- fn expand_local_package() {
- let uri = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![create_simple_document(
- &uri,
- Language::Latex,
- r#"\usepackage{foo-bar-baz}"#,
- )];
- let expansion = snapshot.expand(&Options::default(), &env::current_dir().unwrap());
-
- assert_eq!(
- expansion
- .iter()
- .map(|uri| uri.as_str())
- .filter(|uri| uri.ends_with(".sty"))
- .collect_vec(),
- vec!["http://www.example.com/foo-bar-baz.sty"]
- );
- }
-
- #[test]
- fn expand_system_package() {
- let uri = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![create_simple_document(
- &uri,
- Language::Latex,
- r#"\usepackage{amsmath}"#,
- )];
- let expansion = snapshot.expand(&Options::default(), &env::current_dir().unwrap());
-
- assert_eq!(
- expansion
- .iter()
- .map(|uri| uri.as_str())
- .filter(|uri| uri.ends_with(".sty"))
- .collect_vec(),
- Vec::<&str>::new()
- );
- }
-
- #[test]
- fn expand_subdirectory() {
- let uri = Uri::parse("http://www.example.com/foo.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![create_simple_document(
- &uri,
- Language::Latex,
- r#"\include{bar/baz}"#,
- )];
- let expansion = snapshot.expand(&Options::default(), &env::current_dir().unwrap());
- assert_eq!(
- expansion
- .iter()
- .map(|uri| uri.as_str())
- .filter(|uri| uri.ends_with(".tex"))
- .collect_vec(),
- vec!["http://www.example.com/bar/baz.tex"]
- );
- }
-
- #[test]
- fn expand_import() {
- let uri1 = Uri::parse("http://www.example.com/qux/foo.tex").unwrap();
- let uri2 = Uri::parse("http://www.example.com/qux/baz/bar.tex").unwrap();
- let mut snapshot = Snapshot::new();
- snapshot.0 = vec![
- create_simple_document(
- &uri1,
- Language::Latex,
- r#"\import{.}{foo}\import{baz/}{bar}\import{baz/foo-bar/}{qux}"#,
- ),
- create_simple_document(&uri2, Language::Latex, r#""#),
- ];
- let expansion = snapshot.expand(&Options::default(), &env::current_dir().unwrap());
- assert_eq!(
- expansion
- .iter()
- .map(|uri| uri.as_str())
- .filter(|uri| uri.ends_with(".tex"))
- .collect_vec(),
- vec!["http://www.example.com/qux/baz/foo-bar/qux.tex"]
- )
- }
+pub fn create_workspace_full(context: Arc<ServerContext>) -> Result<impl Workspace> {
+ let workspace = Storage::new(context);
+ let workspace = DocumentWatcher::new(Arc::new(workspace))?;
+ let workspace = ParentExpander::new(workspace);
+ let workspace = ChildrenExpander::new(Arc::new(workspace));
+ Ok(workspace)
}
diff --git a/support/texlab/src/workspace/api.rs b/support/texlab/src/workspace/api.rs
new file mode 100644
index 0000000000..38fa0ce530
--- /dev/null
+++ b/support/texlab/src/workspace/api.rs
@@ -0,0 +1,86 @@
+use std::{fs, path::PathBuf, sync::Arc};
+
+use anyhow::Result;
+
+use crate::{DocumentLanguage, Uri};
+
+use super::Document;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
+pub enum WorkspaceSource {
+ Client,
+ Server,
+}
+
+#[derive(Debug, Clone)]
+pub struct WorkspaceSubset {
+ pub documents: Vec<Arc<Document>>,
+}
+
+pub type OpenHandler = Arc<dyn Fn(Arc<dyn Workspace>, Arc<Document>) + Send + Sync + 'static>;
+
+pub trait Workspace: Send + Sync {
+ fn open(
+ &self,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ source: WorkspaceSource,
+ ) -> Arc<Document>;
+
+ fn register_open_handler(&self, handler: OpenHandler);
+
+ fn reload(&self, path: PathBuf) -> Result<Option<Arc<Document>>> {
+ let uri = Arc::new(Uri::from_file_path(path.clone()).unwrap());
+
+ if self.is_open(&uri) {
+ return Ok(self.get(&uri));
+ }
+
+ let data = fs::read(&path)?;
+ let text = String::from_utf8_lossy(&data).into_owned();
+ if let Some(language) = DocumentLanguage::by_path(&path) {
+ Ok(Some(self.open(
+ uri,
+ text,
+ language,
+ WorkspaceSource::Server,
+ )))
+ } else {
+ Ok(None)
+ }
+ }
+
+ fn load(&self, path: PathBuf) -> Result<Option<Arc<Document>>> {
+ let uri = Arc::new(Uri::from_file_path(path.clone()).unwrap());
+
+ if let Some(document) = self.get(&uri) {
+ return Ok(Some(document));
+ }
+
+ let data = fs::read(&path)?;
+ let text = String::from_utf8_lossy(&data).into_owned();
+ if let Some(language) = DocumentLanguage::by_path(&path) {
+ Ok(Some(self.open(
+ uri,
+ text,
+ language,
+ WorkspaceSource::Server,
+ )))
+ } else {
+ Ok(None)
+ }
+ }
+
+ fn documents(&self) -> Vec<Arc<Document>>;
+
+ fn has(&self, uri: &Uri) -> bool;
+
+ fn get(&self, uri: &Uri) -> Option<Arc<Document>>;
+
+ fn close(&self, uri: &Uri);
+
+ fn is_open(&self, uri: &Uri) -> bool;
+
+ fn subset(&self, uri: Arc<Uri>) -> Option<WorkspaceSubset>;
+}
diff --git a/support/texlab/src/workspace/children_expand.rs b/support/texlab/src/workspace/children_expand.rs
new file mode 100644
index 0000000000..006e7b17e2
--- /dev/null
+++ b/support/texlab/src/workspace/children_expand.rs
@@ -0,0 +1,92 @@
+use std::sync::Arc;
+
+use rayon::iter::{IntoParallelIterator, ParallelIterator};
+
+use crate::{
+ component_db::COMPONENT_DATABASE, Document, DocumentLanguage, OpenHandler, Uri, Workspace,
+ WorkspaceSource, WorkspaceSubset,
+};
+
+pub struct ChildrenExpander<W> {
+ workspace: Arc<W>,
+}
+
+impl<W> ChildrenExpander<W>
+where
+ W: Workspace + Send + Sync + 'static,
+{
+ pub fn new(workspace: Arc<W>) -> Self {
+ workspace.register_open_handler(Arc::new(move |workspace, document| {
+ Self::expand(workspace.as_ref(), document.as_ref());
+ }));
+ Self { workspace }
+ }
+
+ fn expand(workspace: &dyn Workspace, document: &Document) {
+ if let Some(data) = document.data.as_latex() {
+ let extras = &data.extras;
+ let mut all_targets = vec![&extras.implicit_links.aux, &extras.implicit_links.log];
+ for link in &extras.explicit_links {
+ if link
+ .as_component_name()
+ .and_then(|name| COMPONENT_DATABASE.find(&name))
+ .is_none()
+ {
+ all_targets.push(&link.targets);
+ }
+ }
+
+ all_targets.into_par_iter().for_each(|targets| {
+ for path in targets
+ .iter()
+ .filter(|uri| uri.scheme() == "file" && uri.fragment().is_none())
+ .filter_map(|uri| uri.to_file_path().ok())
+ {
+ if workspace.load(path).is_ok() {
+ break;
+ }
+ }
+ });
+ }
+ }
+}
+
+impl<W: Workspace> Workspace for ChildrenExpander<W> {
+ fn open(
+ &self,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ source: WorkspaceSource,
+ ) -> Arc<Document> {
+ self.workspace.open(uri, text, language, source)
+ }
+
+ fn register_open_handler(&self, handler: OpenHandler) {
+ self.workspace.register_open_handler(handler)
+ }
+
+ fn documents(&self) -> Vec<Arc<Document>> {
+ self.workspace.documents()
+ }
+
+ fn has(&self, uri: &Uri) -> bool {
+ self.workspace.has(uri)
+ }
+
+ fn get(&self, uri: &Uri) -> Option<Arc<Document>> {
+ self.workspace.get(uri)
+ }
+
+ fn close(&self, uri: &Uri) {
+ self.workspace.close(uri)
+ }
+
+ fn is_open(&self, uri: &Uri) -> bool {
+ self.workspace.is_open(uri)
+ }
+
+ fn subset(&self, uri: Arc<Uri>) -> Option<WorkspaceSubset> {
+ self.workspace.subset(uri)
+ }
+}
diff --git a/support/texlab/src/workspace/document.rs b/support/texlab/src/workspace/document.rs
new file mode 100644
index 0000000000..a98be226c1
--- /dev/null
+++ b/support/texlab/src/workspace/document.rs
@@ -0,0 +1,127 @@
+use std::{fmt, sync::Arc};
+
+use derive_more::From;
+
+use crate::{
+ line_index::LineIndex,
+ syntax::{
+ bibtex, build_log,
+ latex::{self, LatexAnalyzerContext},
+ },
+ DocumentLanguage, ServerContext, Uri,
+};
+
+#[derive(Debug, Clone)]
+pub struct LatexDocumentData {
+ pub root: latex::SyntaxNode,
+ pub extras: latex::Extras,
+}
+
+#[derive(Debug, Clone)]
+pub struct BibtexDocumentData {
+ pub root: bibtex::SyntaxNode,
+}
+
+#[derive(Debug, Clone, From)]
+pub enum DocumentData {
+ Latex(LatexDocumentData),
+ Bibtex(BibtexDocumentData),
+ BuildLog(build_log::Parse),
+}
+
+impl DocumentData {
+ pub fn language(&self) -> DocumentLanguage {
+ match self {
+ Self::Latex(_) => DocumentLanguage::Latex,
+ Self::Bibtex(_) => DocumentLanguage::Bibtex,
+ Self::BuildLog(_) => DocumentLanguage::BuildLog,
+ }
+ }
+
+ pub fn as_latex(&self) -> Option<&LatexDocumentData> {
+ if let Self::Latex(data) = self {
+ Some(data)
+ } else {
+ None
+ }
+ }
+
+ pub fn as_bibtex(&self) -> Option<&BibtexDocumentData> {
+ if let Self::Bibtex(data) = self {
+ Some(data)
+ } else {
+ None
+ }
+ }
+
+ pub fn as_build_log(&self) -> Option<&build_log::Parse> {
+ if let Self::BuildLog(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
+}
+
+#[derive(Clone)]
+pub struct Document {
+ pub uri: Arc<Uri>,
+ pub text: String,
+ pub line_index: LineIndex,
+ pub data: DocumentData,
+}
+
+impl fmt::Debug for Document {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.uri)
+ }
+}
+
+impl Document {
+ pub fn parse(
+ context: Arc<ServerContext>,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ ) -> Self {
+ let line_index = LineIndex::new(&text);
+ let data = match language {
+ DocumentLanguage::Latex => {
+ let root = latex::parse(&text).root;
+
+ let base_uri = match &context.options.read().unwrap().root_directory {
+ Some(root_dir) => Uri::from_directory_path(root_dir)
+ .map(Arc::new)
+ .unwrap_or_else(|()| Arc::clone(&uri)),
+ None => Arc::clone(&uri),
+ };
+ let mut context = LatexAnalyzerContext {
+ inner: context,
+ extras: latex::Extras::default(),
+ document_uri: Arc::clone(&uri),
+ base_uri,
+ };
+ latex::analyze(&mut context, &root);
+ let extras = context.extras;
+
+ LatexDocumentData { root, extras }.into()
+ }
+ DocumentLanguage::Bibtex => {
+ let root = bibtex::parse(&text).root;
+ BibtexDocumentData { root }.into()
+ }
+ DocumentLanguage::BuildLog => DocumentData::BuildLog(build_log::parse(&text)),
+ };
+
+ Self {
+ uri,
+ text,
+ line_index,
+ data,
+ }
+ }
+
+ pub fn language(&self) -> DocumentLanguage {
+ self.data.language()
+ }
+}
diff --git a/support/texlab/src/workspace/parent_expand.rs b/support/texlab/src/workspace/parent_expand.rs
new file mode 100644
index 0000000000..33b0ca3c5e
--- /dev/null
+++ b/support/texlab/src/workspace/parent_expand.rs
@@ -0,0 +1,123 @@
+use std::{fs, sync::Arc};
+
+use rayon::iter::{IntoParallelIterator, ParallelIterator};
+use rustc_hash::FxHashSet;
+
+use crate::{
+ Document, DocumentLanguage, OpenHandler, Uri, Workspace, WorkspaceSource, WorkspaceSubset,
+};
+
+pub struct ParentExpander<W> {
+ workspace: W,
+}
+
+impl<W: Workspace> ParentExpander<W> {
+ pub fn new(workspace: W) -> Self {
+ Self { workspace }
+ }
+}
+
+impl<W> Workspace for ParentExpander<W>
+where
+ W: Workspace + Send + Sync + 'static,
+{
+ fn open(
+ &self,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ source: WorkspaceSource,
+ ) -> Arc<Document> {
+ let document = self
+ .workspace
+ .open(Arc::clone(&uri), text, language, source);
+
+ let all_current_paths = self
+ .workspace
+ .documents()
+ .into_iter()
+ .filter_map(|doc| doc.uri.to_file_path().ok())
+ .collect::<FxHashSet<_>>();
+
+ if uri.scheme() == "file" {
+ if let Ok(mut path) = uri.to_file_path() {
+ while path.pop() && !self.has_parent(Arc::clone(&uri)).unwrap_or(false) {
+ let mut files = Vec::new();
+ fs::read_dir(&path)
+ .into_iter()
+ .flatten()
+ .filter_map(|entry| entry.ok())
+ .filter(|entry| entry.file_type().ok().filter(|ty| ty.is_file()).is_some())
+ .map(|entry| entry.path())
+ .filter(|path| {
+ matches!(
+ DocumentLanguage::by_path(&path),
+ Some(DocumentLanguage::Latex)
+ )
+ })
+ .filter(|path| !all_current_paths.contains(path))
+ .for_each(|path| {
+ files.push(path);
+ });
+ files.into_par_iter().for_each(|path| {
+ let _ = self.workspace.load(path);
+ });
+ }
+ }
+ }
+
+ document
+ }
+
+ fn register_open_handler(&self, handler: OpenHandler) {
+ self.workspace.register_open_handler(handler)
+ }
+
+ fn documents(&self) -> Vec<Arc<Document>> {
+ self.workspace.documents()
+ }
+
+ fn has(&self, uri: &Uri) -> bool {
+ self.workspace.has(uri)
+ }
+
+ fn get(&self, uri: &Uri) -> Option<Arc<Document>> {
+ self.workspace.get(uri)
+ }
+
+ fn close(&self, uri: &Uri) {
+ self.workspace.close(uri)
+ }
+
+ fn is_open(&self, uri: &Uri) -> bool {
+ self.workspace.is_open(uri)
+ }
+
+ fn subset(&self, uri: Arc<Uri>) -> Option<WorkspaceSubset> {
+ self.workspace.subset(uri)
+ }
+}
+
+impl<W> ParentExpander<W>
+where
+ W: Workspace + Send + Sync + 'static,
+{
+ fn has_parent(&self, uri: Arc<Uri>) -> Option<bool> {
+ let subset = self.subset(Arc::clone(&uri))?;
+ Some(subset.documents.iter().any(|document| {
+ document
+ .data
+ .as_latex()
+ .map(|data| {
+ data.extras.has_document_environment
+ && !data
+ .extras
+ .explicit_links
+ .iter()
+ .filter_map(|link| link.as_component_name())
+ .any(|name| name == "subfiles.cls")
+ })
+ .unwrap_or(false)
+ }))
+ }
+}
diff --git a/support/texlab/src/workspace/storage.rs b/support/texlab/src/workspace/storage.rs
new file mode 100644
index 0000000000..964535a718
--- /dev/null
+++ b/support/texlab/src/workspace/storage.rs
@@ -0,0 +1,136 @@
+use std::sync::{Arc, Mutex};
+
+use petgraph::{graphmap::UnGraphMap, visit::Dfs};
+use rustc_hash::{FxHashMap, FxHashSet};
+
+use crate::{
+ Document, DocumentLanguage, OpenHandler, ServerContext, Uri, Workspace, WorkspaceSource,
+ WorkspaceSubset,
+};
+
+#[derive(Clone)]
+pub struct Storage {
+ context: Arc<ServerContext>,
+ documents_by_uri: Arc<Mutex<FxHashMap<Arc<Uri>, Arc<Document>>>>,
+ opened_documents: Arc<Mutex<FxHashSet<Arc<Uri>>>>,
+ open_handlers: Arc<Mutex<Vec<OpenHandler>>>,
+}
+
+impl Storage {
+ pub fn new(context: Arc<ServerContext>) -> Self {
+ Self {
+ context,
+ documents_by_uri: Arc::default(),
+ opened_documents: Arc::default(),
+ open_handlers: Arc::default(),
+ }
+ }
+}
+
+impl Workspace for Storage {
+ fn open(
+ &self,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ source: WorkspaceSource,
+ ) -> Arc<Document> {
+ log::debug!("(Re)Loading document: {}", uri);
+ let document = Arc::new(Document::parse(
+ Arc::clone(&self.context),
+ Arc::clone(&uri),
+ text,
+ language,
+ ));
+ {
+ self.documents_by_uri
+ .lock()
+ .unwrap()
+ .insert(Arc::clone(&uri), Arc::clone(&document));
+ }
+
+ if source == WorkspaceSource::Client {
+ self.opened_documents.lock().unwrap().insert(uri);
+ }
+
+ let handlers = { self.open_handlers.lock().unwrap().clone() };
+ for handler in handlers {
+ handler(Arc::new(self.clone()), Arc::clone(&document));
+ }
+
+ document
+ }
+
+ fn register_open_handler(&self, handler: OpenHandler) {
+ self.open_handlers.lock().unwrap().push(handler);
+ }
+
+ fn documents(&self) -> Vec<Arc<Document>> {
+ self.documents_by_uri
+ .lock()
+ .unwrap()
+ .values()
+ .cloned()
+ .collect()
+ }
+
+ fn has(&self, uri: &Uri) -> bool {
+ self.documents_by_uri.lock().unwrap().contains_key(uri)
+ }
+
+ fn get(&self, uri: &Uri) -> Option<Arc<Document>> {
+ self.documents_by_uri.lock().unwrap().get(uri).cloned()
+ }
+
+ fn close(&self, uri: &Uri) {
+ self.opened_documents.lock().unwrap().remove(uri);
+ }
+
+ fn is_open(&self, uri: &Uri) -> bool {
+ self.opened_documents.lock().unwrap().contains(uri)
+ }
+
+ fn subset(&self, uri: Arc<Uri>) -> Option<WorkspaceSubset> {
+ let all_current_uris: Vec<Arc<Uri>> = self
+ .documents_by_uri
+ .lock()
+ .unwrap()
+ .keys()
+ .cloned()
+ .collect();
+
+ let mut edges = Vec::new();
+ for (i, uri) in all_current_uris.iter().enumerate() {
+ let document = self.get(uri);
+ if let Some(data) = document
+ .as_ref()
+ .and_then(|document| document.data.as_latex())
+ {
+ let extras = &data.extras;
+ let mut all_targets = vec![&extras.implicit_links.aux, &extras.implicit_links.log];
+ for link in &extras.explicit_links {
+ all_targets.push(&link.targets);
+ }
+
+ for targets in all_targets {
+ for target in targets {
+ if let Some(j) = all_current_uris.iter().position(|uri| uri == target) {
+ edges.push((i, j, ()));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ let graph = UnGraphMap::from_edges(edges);
+ let start = all_current_uris.iter().position(|u| *u == uri)?;
+ let mut dfs = Dfs::new(&graph, start);
+ let mut documents = Vec::new();
+ while let Some(i) = dfs.next(&graph) {
+ documents.push(self.get(&all_current_uris[i])?);
+ }
+
+ Some(WorkspaceSubset { documents })
+ }
+}
diff --git a/support/texlab/src/workspace/watch.rs b/support/texlab/src/workspace/watch.rs
new file mode 100644
index 0000000000..655872f603
--- /dev/null
+++ b/support/texlab/src/workspace/watch.rs
@@ -0,0 +1,107 @@
+use std::{
+ path::PathBuf,
+ sync::{Arc, Mutex},
+};
+
+use anyhow::Result;
+use log::warn;
+use notify::{RecommendedWatcher, RecursiveMode, Watcher};
+use rustc_hash::FxHashSet;
+
+use crate::{
+ Document, DocumentLanguage, OpenHandler, Uri, Workspace, WorkspaceSource, WorkspaceSubset,
+};
+
+pub struct DocumentWatcher<W> {
+ workspace: Arc<W>,
+ watcher: Mutex<RecommendedWatcher>,
+ watched_paths: Mutex<FxHashSet<PathBuf>>,
+}
+
+impl<W> DocumentWatcher<W>
+where
+ W: Workspace + Send + Sync + 'static,
+{
+ pub fn new(workspace: Arc<W>) -> Result<Self> {
+ let watcher = Self::create_watcher(Arc::clone(&workspace))?;
+ Ok(Self {
+ workspace,
+ watcher: Mutex::new(watcher),
+ watched_paths: Mutex::default(),
+ })
+ }
+
+ fn create_watcher(workspace: Arc<W>) -> Result<RecommendedWatcher> {
+ let watcher = Watcher::new_immediate(move |event: notify::Result<notify::Event>| {
+ if let Ok(event) = event {
+ if event.kind.is_modify() {
+ for path in event.paths {
+ let _ = workspace.reload(path);
+ }
+ }
+ }
+ })?;
+ Ok(watcher)
+ }
+}
+
+impl<W: Workspace> Workspace for DocumentWatcher<W> {
+ fn open(
+ &self,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ source: WorkspaceSource,
+ ) -> Arc<Document> {
+ let document = self.workspace.open(uri, text, language, source);
+ if document.uri.scheme() == "file" {
+ if let Ok(mut path) = document.uri.to_file_path() {
+ path.pop();
+ let mut watched_paths = self.watched_paths.lock().unwrap();
+ if !watched_paths.contains(&path) {
+ if let Err(why) = self
+ .watcher
+ .lock()
+ .unwrap()
+ .watch(&path, RecursiveMode::NonRecursive)
+ {
+ warn!(
+ "Failed to watch folder of document \"{}\": {}",
+ document.uri, why
+ );
+ }
+ watched_paths.insert(path);
+ }
+ }
+ }
+ document
+ }
+
+ fn register_open_handler(&self, handler: OpenHandler) {
+ self.workspace.register_open_handler(handler);
+ }
+
+ fn documents(&self) -> Vec<Arc<Document>> {
+ self.workspace.documents()
+ }
+
+ fn has(&self, uri: &Uri) -> bool {
+ self.workspace.has(uri)
+ }
+
+ fn get(&self, uri: &Uri) -> Option<Arc<Document>> {
+ self.workspace.get(uri)
+ }
+
+ fn close(&self, uri: &Uri) {
+ self.workspace.close(uri)
+ }
+
+ fn is_open(&self, uri: &Uri) -> bool {
+ self.workspace.is_open(uri)
+ }
+
+ fn subset(&self, uri: Arc<Uri>) -> Option<WorkspaceSubset> {
+ self.workspace.subset(uri)
+ }
+}
diff --git a/support/texlab/tests/integration/common.rs b/support/texlab/tests/integration/common.rs
new file mode 100644
index 0000000000..5430bfd2be
--- /dev/null
+++ b/support/texlab/tests/integration/common.rs
@@ -0,0 +1,318 @@
+use std::{
+ fs,
+ sync::{
+ atomic::{AtomicI32, Ordering},
+ Mutex,
+ },
+ thread::{self, JoinHandle},
+};
+
+use anyhow::Result;
+use lsp_server::{Connection, RequestId};
+use lsp_types::{notification::Notification, request::Request, *};
+use rustc_hash::FxHashMap;
+use tempfile::{tempdir, TempDir};
+use texlab::Server;
+use unindent::unindent;
+
+pub struct ServerTester {
+ pub directory: TempDir,
+ client: Connection,
+ handle: Option<JoinHandle<()>>,
+ request_id: AtomicI32,
+ pub diagnostics_by_uri: Mutex<FxHashMap<Url, Vec<Diagnostic>>>,
+}
+
+impl ServerTester {
+ pub fn launch_new_instance() -> Result<Self> {
+ let directory = tempdir()?;
+ let (conn, client) = Connection::memory();
+ let server = Server::with_connection(conn, directory.path().to_path_buf(), false)?;
+ let handle = thread::spawn(move || server.run().unwrap());
+ Ok(Self {
+ directory,
+ client,
+ handle: Some(handle),
+ request_id: AtomicI32::new(0),
+ diagnostics_by_uri: Mutex::default(),
+ })
+ }
+
+ fn wait_for_response(&self, request_id: RequestId) -> Result<lsp_server::Response> {
+ loop {
+ match self.client.receiver.recv()? {
+ lsp_server::Message::Request(request) => {
+ match request.method.as_str() {
+ request::RegisterCapability::METHOD => {
+ self.client
+ .sender
+ .send(lsp_server::Response::new_ok(request.id, ()).into())?;
+ }
+ method => {
+ panic!("unknown request: {}", method);
+ }
+ };
+ }
+ lsp_server::Message::Notification(notification) => {
+ match notification.method.as_str() {
+ notification::PublishDiagnostics::METHOD => {
+ let params = serde_json::from_value::<PublishDiagnosticsParams>(
+ notification.params,
+ )?;
+ let mut diagnostics_by_uri = self.diagnostics_by_uri.lock().unwrap();
+ diagnostics_by_uri.insert(params.uri, params.diagnostics);
+ }
+ method => {
+ panic!("unknown notification: {}", method);
+ }
+ };
+ }
+ lsp_server::Message::Response(response) => {
+ assert_eq!(response.id, request_id);
+ return Ok(response);
+ }
+ }
+ }
+ }
+
+ #[allow(deprecated)]
+ pub fn initialize(
+ &self,
+ client_capabilities: ClientCapabilities,
+ client_info: Option<ClientInfo>,
+ ) -> anyhow::Result<()> {
+ let request_id = RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst));
+ self.client.sender.send(
+ lsp_server::Request::new(
+ request_id.clone(),
+ request::Initialize::METHOD.to_string(),
+ InitializeParams {
+ process_id: None,
+ root_path: None,
+ root_uri: None,
+ initialization_options: None,
+ capabilities: client_capabilities,
+ trace: None,
+ workspace_folders: None,
+ client_info,
+ locale: None,
+ },
+ )
+ .into(),
+ )?;
+ self.wait_for_response(request_id)?;
+
+ self.client.sender.send(
+ lsp_server::Notification::new(notification::Initialized::METHOD.to_string(), ()).into(),
+ )?;
+
+ Ok(())
+ }
+
+ pub fn open(&self, name: &str, text: &str, language_id: &str, store: bool) -> Result<Url> {
+ let text = unindent(text).trim().to_string();
+ let path = self.directory.path().join(name);
+ if store {
+ fs::create_dir_all(path.parent().unwrap())?;
+ fs::write(&path, &text)?;
+ }
+
+ let uri = Url::from_file_path(path).unwrap();
+ self.client.sender.send(
+ lsp_server::Notification::new(
+ notification::DidOpenTextDocument::METHOD.to_string(),
+ DidOpenTextDocumentParams {
+ text_document: TextDocumentItem::new(
+ uri.clone(),
+ language_id.to_string(),
+ 0,
+ text,
+ ),
+ },
+ )
+ .into(),
+ )?;
+ Ok(uri)
+ }
+
+ pub fn open_memory(&self, uri: Url, text: &str, language_id: &str) -> Result<()> {
+ let text = unindent(text).trim().to_string();
+ let text_document = TextDocumentItem::new(uri, language_id.to_string(), 0, text);
+ self.client.sender.send(
+ lsp_server::Notification::new(
+ notification::DidOpenTextDocument::METHOD.to_string(),
+ DidOpenTextDocumentParams { text_document },
+ )
+ .into(),
+ )?;
+ Ok(())
+ }
+
+ // pub fn edit(&self, uri: Url, text: &str) -> Result<()> {
+ // let text = unindent(text).trim().to_string();
+ // self.client.sender.send(
+ // lsp_server::Notification::new(
+ // notification::DidChangeTextDocument::METHOD.to_string(),
+ // DidChangeTextDocumentParams {
+ // text_document: VersionedTextDocumentIdentifier::new(uri, 0),
+ // content_changes: vec![TextDocumentContentChangeEvent {
+ // text,
+ // range: None,
+ // range_length: None,
+ // }],
+ // },
+ // )
+ // .into(),
+ // )?;
+ // Ok(())
+ // }
+
+ pub fn complete(&self, uri: Url, line: u32, character: u32) -> Result<CompletionList> {
+ let request_id = RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst));
+
+ self.client.sender.send(
+ lsp_server::Request::new(
+ request_id.clone(),
+ request::Completion::METHOD.to_string(),
+ CompletionParams {
+ text_document_position: TextDocumentPositionParams::new(
+ TextDocumentIdentifier::new(uri),
+ Position::new(line, character),
+ ),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ context: None,
+ },
+ )
+ .into(),
+ )?;
+
+ let response = self.wait_for_response(request_id)?;
+ let list = serde_json::from_value(response.result.expect("completion request failed"))?;
+ Ok(list)
+ }
+
+ pub fn resolve_completion_item(&self, item: CompletionItem) -> Result<CompletionItem> {
+ let request_id = RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst));
+
+ self.client.sender.send(
+ lsp_server::Request::new(
+ request_id.clone(),
+ request::ResolveCompletionItem::METHOD.to_string(),
+ item,
+ )
+ .into(),
+ )?;
+
+ let response = self.wait_for_response(request_id)?;
+ let result = serde_json::from_value(
+ response
+ .result
+ .expect("resolve completion item request failed"),
+ )?;
+ Ok(result)
+ }
+
+ pub fn hover(&self, uri: Url, line: u32, character: u32) -> Result<Option<Hover>> {
+ let request_id = RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst));
+
+ self.client.sender.send(
+ lsp_server::Request::new(
+ request_id.clone(),
+ request::HoverRequest::METHOD.to_string(),
+ HoverParams {
+ text_document_position_params: TextDocumentPositionParams::new(
+ TextDocumentIdentifier::new(uri),
+ Position::new(line, character),
+ ),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ },
+ )
+ .into(),
+ )?;
+
+ let response = self.wait_for_response(request_id)?;
+ let hover = serde_json::from_value(response.result.expect("hover request failed"))?;
+ Ok(hover)
+ }
+
+ pub fn find_document_symbols(&self, uri: Url) -> Result<DocumentSymbolResponse> {
+ let request_id = RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst));
+
+ self.client.sender.send(
+ lsp_server::Request::new(
+ request_id.clone(),
+ request::DocumentSymbolRequest::METHOD.to_string(),
+ DocumentSymbolParams {
+ text_document: TextDocumentIdentifier::new(uri),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
+ },
+ )
+ .into(),
+ )?;
+
+ let response = self.wait_for_response(request_id)?;
+ let symbols =
+ serde_json::from_value(response.result.expect("document symbol request failed"))?;
+ Ok(symbols)
+ }
+
+ pub fn find_workspace_symbols(&self, query: &str) -> Result<Vec<SymbolInformation>> {
+ let request_id = RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst));
+
+ self.client.sender.send(
+ lsp_server::Request::new(
+ request_id.clone(),
+ request::WorkspaceSymbol::METHOD.to_string(),
+ WorkspaceSymbolParams {
+ partial_result_params: PartialResultParams::default(),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ query: query.to_string(),
+ },
+ )
+ .into(),
+ )?;
+
+ let response = self.wait_for_response(request_id)?;
+ let symbols =
+ serde_json::from_value(response.result.expect("workspace symbol request failed"))?;
+ Ok(symbols)
+ }
+
+ // pub fn change_configuration(&self, options: Options) -> Result<()> {
+ // self.client.sender.send(
+ // lsp_server::Notification::new(
+ // notification::DidChangeConfiguration::METHOD.to_string(),
+ // DidChangeConfigurationParams {
+ // settings: serde_json::to_value(options)?,
+ // },
+ // )
+ // .into(),
+ // )?;
+ // Ok(())
+ // }
+}
+
+impl Drop for ServerTester {
+ fn drop(&mut self) {
+ self.client
+ .sender
+ .send(
+ lsp_server::Request::new(
+ RequestId::from(self.request_id.fetch_add(1, Ordering::SeqCst)),
+ request::Shutdown::METHOD.to_string(),
+ (),
+ )
+ .into(),
+ )
+ .unwrap();
+
+ self.client
+ .sender
+ .send(lsp_server::Notification::new(notification::Exit::METHOD.to_string(), ()).into())
+ .unwrap();
+
+ self.handle.take().unwrap().join().unwrap();
+ }
+}
diff --git a/support/texlab/tests/integration/completion.rs b/support/texlab/tests/integration/completion.rs
index 4b3b4ecd83..33af77f003 100644
--- a/support/texlab/tests/integration/completion.rs
+++ b/support/texlab/tests/integration/completion.rs
@@ -1,1227 +1,762 @@
-#[cfg(feature = "citation")]
-use texlab::protocol::{MarkupContent, MarkupKind};
-
-use indoc::indoc;
-use itertools::Itertools;
-use texlab::{
- protocol::{CompletionItem, CompletionTextEdit, Documentation, Range, RangeExt, TextEdit},
- test::{TestBed, TestBedBuilder, TestLspClient, PULL_CAPABILITIES},
-};
-
-async fn run_item(
- test_bed: &TestBed,
- relative_path: &str,
- line: u64,
- character: u64,
- label: &str,
-) -> CompletionItem {
- let item = test_bed
- .completion(relative_path, line, character)
- .await
- .unwrap()
- .into_iter()
- .find(|item| item.label == label)
- .unwrap();
-
- test_bed.client.completion_resolve(item).await.unwrap()
-}
-
-async fn run_list(
- test_bed: &TestBed,
- relative_path: &str,
- line: u64,
- character: u64,
-) -> Vec<String> {
- test_bed
- .completion(relative_path, line, character)
- .await
- .unwrap()
- .into_iter()
- .map(|item| item.label)
- .sorted()
- .collect()
-}
-
-fn verify_text_edit(
- item: &CompletionItem,
- start_line: u64,
- start_character: u64,
- end_line: u64,
- end_character: u64,
- text: &str,
-) {
- assert_eq!(
- *item.text_edit.as_ref().unwrap(),
- CompletionTextEdit::Edit(TextEdit::new(
- Range::new_simple(start_line, start_character, end_line, end_character),
- text.into()
- ))
- );
-}
-
-fn verify_detail(item: &CompletionItem, detail: &str) {
- assert_eq!(item.detail.as_ref().unwrap(), detail);
-}
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = test_bed.completion("main.tex", 0, 0).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_items.is_empty());
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_items = test_bed.completion("main.bib", 0, 0).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_items.is_empty());
-}
-
-#[tokio::test]
-async fn bibtex_comment() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "foo").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_items = test_bed.completion("main.bib", 0, 2).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_items.is_empty());
-}
-
-#[tokio::test]
-async fn bibtex_command_incomplete_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+use anyhow::Result;
+use lsp_types::{CompletionList, Url};
+
+use crate::common::ServerTester;
+
+fn complete_and_resolve(
+ server: &ServerTester,
+ uri: Url,
+ line: u32,
+ character: u32,
+) -> Result<CompletionList> {
+ let mut list = server.complete(uri, line, character)?;
+ let mut new_items = Vec::new();
+ for item in list.items.into_iter().take(7) {
+ let mut new_item = server.resolve_completion_item(item)?;
+ new_item.data = None;
+ new_items.push(new_item);
+ }
+ list.items = new_items;
+ Ok(list)
+}
+
+mod bibtex {
+ use insta::assert_json_snapshot;
+ use lsp_types::ClientCapabilities;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_document() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open("main.bib", "", "bibtex", false)?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 0)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_junk() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open("main.bib", "foo", "bibtex", false)?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 0)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_command_incomplete_entry() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @article{foo,
- author = {\LaT
- }
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 1, 18, "LaTeX").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "built-in");
- verify_text_edit(&actual_item, 1, 15, 1, 18, "LaTeX");
-}
-
-#[tokio::test]
-async fn bibtex_command_complete_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @article{foo,
+ author = {\LaT
+ }
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 18)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_command_complete_entry() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @article{foo,
- author = {\LaT}
- }
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 1, 18, "LaTeX").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "built-in");
- verify_text_edit(&actual_item, 1, 15, 1, 18, "LaTeX");
-}
-
-#[tokio::test]
-async fn bibtex_type_empty() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @article{foo,
+ author = {\LaT}
+ }
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 18)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_entry_type_empty_name() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 0, 1, "article").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 0, 1, 0, 1, "article");
-}
-
-#[tokio::test]
-async fn bibtex_type_incomplete() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 1)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_entry_type_empty_name_before() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @art
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 0, 1, "article").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 0, 1, 0, 4, "article");
-}
-
-#[tokio::test]
-async fn bibtex_type_complete() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 0)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_entry_type_incomplete() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @article
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 0, 1, "article").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 0, 1, 0, 8, "article");
-}
-
-#[tokio::test]
-async fn bibtex_field_incomplete_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @art
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 1)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_entry_type_complete() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @article{foo,
- titl
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 1, 6, "title").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 1, 4, 1, 8, "title");
-}
-
-#[tokio::test]
-async fn bibtex_field_complete_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @article
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 1)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_field_incomplete_entry() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @article{foo,
- title = {}
- }
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.bib", 1, 6, "title").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 1, 4, 1, 9, "title");
-}
-
-#[tokio::test]
-async fn latex_begin_command() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", r#"\"#).build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 0, 1, "begin").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "built-in");
-}
-
-#[cfg(feature = "citation")]
-#[tokio::test]
-async fn latex_citation_valid() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \bibliography{main}
- \begin{document}
- \cite{
- \end{document}
- "#
- ),
- )
- .file(
+ r#"
+ @article{foo,
+ titl
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 6)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_field_complete_entry() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.bib",
- indoc!(
- r#"
- @article{foo:2019,
- author = {Foo Bar},
- title = {Baz Qux},
- year = {2019},
- }
-
- @article{bar:2005,}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 3, 6, "foo:2019").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 3, 6, 3, 6, "foo:2019");
- assert_eq!(
- actual_item.documentation.unwrap(),
- Documentation::MarkupContent(MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Bar, F. (2019). *Baz Qux*.".into()
- })
- );
-}
-
-#[cfg(feature = "citation")]
-#[tokio::test]
-async fn latex_citation_invalid() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @article{foo,
+ title = {}
+ }
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 6)?);
+ Ok(())
+ }
+}
+
+mod latex {
+ use insta::assert_json_snapshot;
+ use lsp_types::ClientCapabilities;
+
+ use super::*;
+
+ #[test]
+ fn test_empty_document() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open("main.tex", "", "latex", false)?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 0)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_begin_command() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open("main.tex", r#"\b"#, "latex", false)?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 1)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_citation() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let tex_uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \bibliography{main}
- \begin{document}
- \cite{
- \end{document}
- "#
- ),
- )
- .file(
+ r#"
+ \documentclass{article}
+ \bibliography{main}
+ \begin{document}
+ \cite{
+ \end{document}
+ "#,
+ "latex",
+ false,
+ )?;
+ server.open(
"main.bib",
- indoc!(
- r#"
- @article{foo:2019,
- author = {Foo Bar},
- title = {Baz Qux},
- year = {2019},
- }
-
- @article{bar:2005,}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
- test_bed.open("main.bib").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 3, 6, "bar:2005").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 3, 6, 3, 6, "bar:2005");
- assert_eq!(actual_item.documentation, None);
-}
-
-#[tokio::test]
-async fn latex_color_name() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \color{re}
- \definecolor{foo}{
- \definecolorset{R}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 0, 9, "red").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 0, 7, 0, 9, "red");
-}
-
-#[tokio::test]
-async fn latex_color_model_define_color() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \color{re}
- \definecolor{foo}{
- \definecolorset{R}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 1, 18, "rgb").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 1, 18, 1, 18, "rgb");
-}
-
-#[tokio::test]
-async fn latex_model_define_color_set() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ @article{foo:2019,
+ author = {Foo Bar},
+ title = {Baz Qux},
+ year = {2019},
+ }
+
+ @article{bar:2005,}
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, tex_uri, 3, 6)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_citation_after() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let tex_uri = server.open(
"main.tex",
- indoc!(
- r#"
- \color{re}
- \definecolor{foo}{
- \definecolorset{R}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 2, 17, "RGB").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 2, 16, 2, 17, "RGB");
-}
-
-#[tokio::test]
-async fn latex_component_kernel_command() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 0, 1, "documentclass").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "built-in");
- verify_text_edit(&actual_item, 0, 1, 0, 14, "documentclass");
-}
-
-#[tokio::test]
-async fn latex_component_kernel_command_glyph() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{article}
+ \bibliography{main}
+ \begin{document}
+ \cite{}
+ \end{document}
+ "#,
+ "latex",
+ false,
+ )?;
+ server.open(
+ "main.bib",
+ r#"
+ @article{foo:2019,
+ author = {Foo Bar},
+ title = {Baz Qux},
+ year = {2019},
+ }
+
+ @article{bar:2005,}
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, tex_uri, 3, 7)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_citation_open_brace() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let tex_uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 7, 7, "varepsilon").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "ε, built-in");
- verify_text_edit(&actual_item, 7, 1, 7, 7, "varepsilon");
-}
-
-#[tokio::test]
-async fn latex_component_kernel_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{article}
+ \bibliography{main}
+ \begin{document}
+ \cite{Foo
+ \end{document}
+ "#,
+ "latex",
+ false,
+ )?;
+ server.open(
+ "main.bib",
+ r#"
+ @article{FooBar,
+ author = {Foo Bar},
+ title = {Baz Qux},
+ year = {2019},
+ }
+ "#,
+ "bibtex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, tex_uri, 3, 9)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_color_name() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 6, 10, "document").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "built-in");
- verify_text_edit(&actual_item, 6, 7, 6, 10, "document");
-}
-
-#[tokio::test]
-async fn latex_component_class_command() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \color{re}
+ \definecolor{foo}{
+ \definecolorset{R}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 9)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_color_model_define_color() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 2, 5, "chapter").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "book.cls");
- verify_text_edit(&actual_item, 2, 1, 2, 5, "chapter");
-}
-
-#[tokio::test]
-async fn latex_component_class_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \color{re}
+ \definecolor{foo}{
+ \definecolorset{R}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 18)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_color_model_define_color_set() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 4, 13, "theindex").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "book.cls");
- verify_text_edit(&actual_item, 4, 7, 4, 13, "theindex");
-}
-
-#[tokio::test]
-async fn latex_component_package_command() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \color{re}
+ \definecolor{foo}{
+ \definecolorset{R}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 2, 17)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_kernel_command() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 3, 7, "varDelta").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "amsmath.sty");
- verify_text_edit(&actual_item, 3, 1, 3, 7, "varDelta");
-}
-
-#[tokio::test]
-async fn latex_component_package_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 1)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_kernel_command_glyph() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- \chap
- \varDel
- \begin{theind}
- \end{alig}
- \begin{doc}
- \vareps
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 5, 5, "align").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "amsmath.sty");
- verify_text_edit(&actual_item, 5, 5, 5, 9, "align");
-}
-
-#[tokio::test]
-async fn latex_import_class() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 7, 7)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_kernel_command_environment() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 0, 19, "book").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 0, 15, 0, 19, "book");
-}
-
-#[tokio::test]
-async fn latex_import_package() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 6, 10)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_class_command() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{book}
- \usepackage{amsmath}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 1, 15, "amsmath").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.documentation.is_some());
- verify_text_edit(&actual_item, 1, 12, 1, 19, "amsmath");
-}
-
-#[tokio::test]
-async fn latex_include_relative_root_no_extension() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 2, 5)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_class_environment() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \include{}
- \input{}
- \input{qux/}
- \addbibresource{}
- "#
- ),
- )
- .file("foo.bib", "")
- .file("bar.tex", "")
- .file("qux/baz.tex", "")
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = run_list(&test_bed, "main.tex", 1, 9).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items, vec!["bar", "main", "qux"]);
-}
-
-#[tokio::test]
-async fn latex_include_relative_root_with_extension() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 4, 13)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_package_command() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \include{}
- \input{}
- \input{qux/}
- \addbibresource{}
- "#
- ),
- )
- .file("foo.bib", "")
- .file("bar.tex", "")
- .file("qux/baz.tex", "")
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = run_list(&test_bed, "main.tex", 2, 7).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items, vec!["bar.tex", "main.tex", "qux"]);
-}
-
-#[tokio::test]
-async fn latex_include_relative_subdir() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 3, 7)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_package_environment() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \include{}
- \input{}
- \input{qux/}
- \addbibresource{}
- "#
- ),
- )
- .file("foo.bib", "")
- .file("bar.tex", "")
- .file("qux/baz.tex", "")
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = run_list(&test_bed, "main.tex", 3, 11).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items, vec!["baz.tex"]);
-}
-
-#[tokio::test]
-async fn latex_include_relative_parent_dir() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ \chap
+ \varDel
+ \begin{theind}
+ \end{alig}
+ \begin{doc}
+ \vareps
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 5, 5)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_class_import() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \include{}
- \input{}
- \input{qux/}
- \addbibresource{}
- "#
- ),
- )
- .file("foo.bib", "")
- .file("bar.tex", "")
- .file("qux/baz.tex", r#"\input{../}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("qux/baz.tex").await;
-
- let actual_items = run_list(&test_bed, "qux/baz.tex", 0, 10).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items, vec!["bar.tex", "main.tex", "qux"]);
-}
-
-#[tokio::test]
-async fn latex_include_relative_bibliography() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 0, 19)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_package_import() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \include{}
- \input{}
- \input{qux/}
- \addbibresource{}
- "#
- ),
- )
- .file("foo.bib", "")
- .file("bar.tex", "")
- .file("qux/baz.tex", "")
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = run_list(&test_bed, "main.tex", 4, 16).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items, vec!["foo.bib", "qux"]);
-}
-
-#[tokio::test]
-async fn latex_include_root_dir() {
- let mut test_bed = TestBedBuilder::new()
- .file("src/main.tex", r#"\input{}"#)
- .root_dir(".")
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("src/main.tex").await;
-
- let actual_items = run_list(&test_bed, "src/main.tex", 0, 7).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items, vec!["src"]);
-}
-
-#[tokio::test]
-async fn latex_label() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{book}
+ \usepackage{amsmath}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 15)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_label() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+
+ server.open(
"foo.tex",
- indoc!(
- r#"
- \documentclass{article}
- %
- \usepackage{amsmath}
- \usepackage{caption}
- \usepackage{amsthm}
- \newtheorem{lemma}{Lemma}
- %
- \begin{document}
- %
- \section{Foo}%
- \label{sec:foo}
- %
- \begin{equation}%
- \label{eq:foo}
- 1 + 1 = 2
- \end{equation}
- %
- \begin{equation}%
- \label{eq:bar}
- 1 + 1 = 2
- \end{equation}
- %
- \begin{figure}%
- \LaTeX{}
- \caption{Baz}%
- \label{fig:baz}
- \end{figure}
- %
- \begin{lemma}%
- \label{thm:foo}
- 1 + 1 = 2
- \end{lemma}
- %
- \include{bar}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "foo.aux",
- indoc!(
- r#"
- \relax
- \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Baz\relax }}{1}\protected@file@percent }
- \providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}}
- \newlabel{fig:baz}{{1}{1}}
- \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
- \newlabel{sec:foo}{{1}{1}}
- \newlabel{eq:foo}{{1}{1}}
- \newlabel{eq:bar}{{2}{1}}
- \newlabel{thm:foo}{{1}{1}}
- \@input{bar.aux}
- "#
- ),
- )
- .file(
- "bar.tex",
- indoc!(
- r#"
- \section{Bar}%
- \label{sec:bar}
- %
- Lorem ipsum dolor sit amet.
- \ref{}
- \eqref{}
- "#
- ),
- )
- .file(
- "bar.aux",
- indoc!(
- r#"
- \relax
- \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{2}\protected@file@percent }
- \newlabel{sec:bar}{{2}{2}}
- \@setckpt{bar}{
- \setcounter{page}{3}
- \setcounter{equation}{2}
- \setcounter{enumi}{0}
- \setcounter{enumii}{0}
- \setcounter{enumiii}{0}
- \setcounter{enumiv}{0}
- \setcounter{footnote}{0}
- \setcounter{mpfootnote}{0}
- \setcounter{part}{0}
- \setcounter{section}{2}
- \setcounter{subsection}{0}
- \setcounter{subsubsection}{0}
- \setcounter{paragraph}{0}
- \setcounter{subparagraph}{0}
- \setcounter{figure}{1}
- \setcounter{table}{0}
- \setcounter{parentequation}{0}
- \setcounter{caption@flags}{0}
- \setcounter{ContinuedFloat}{0}
- \setcounter{lemma}{1}
- }
- "#),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("foo.tex").await;
- test_bed.open("foo.aux").await;
- test_bed.open("bar.tex").await;
- test_bed.open("bar.aux").await;
-
- let actual_items = test_bed.completion("bar.tex", 4, 5).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_items.len(), 6);
- verify_text_edit(&actual_items[0], 4, 5, 4, 5, "sec:bar");
- verify_text_edit(&actual_items[1], 4, 5, 4, 5, "sec:foo");
- verify_text_edit(&actual_items[2], 4, 5, 4, 5, "eq:foo");
- verify_text_edit(&actual_items[3], 4, 5, 4, 5, "eq:bar");
- verify_text_edit(&actual_items[4], 4, 5, 4, 5, "fig:baz");
- verify_text_edit(&actual_items[5], 4, 5, 4, 5, "thm:foo");
- verify_detail(&actual_items[0], "Section 2 (Bar)");
- verify_detail(&actual_items[1], "Section 1 (Foo)");
- verify_detail(&actual_items[2], "Equation (1)");
- verify_detail(&actual_items[3], "Equation (2)");
- verify_detail(&actual_items[4], "Figure 1");
- verify_detail(&actual_items[5], "Lemma 1");
- assert_eq!(
- *actual_items[4].documentation.as_ref().unwrap(),
- Documentation::String("Baz".into())
- );
-}
-
-#[tokio::test]
-async fn latex_preselect_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{document}
- \end{
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 1, 5, "document").await;
-
- test_bed.shutdown().await;
-
- assert!(actual_item.preselect.unwrap());
-}
-
-#[tokio::test]
-async fn latex_theorem() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{article}
+
+ \usepackage{amsmath}
+ \usepackage{caption}
+ \usepackage{amsthm}
+ \newtheorem{lemma}{Lemma}
+
+ \begin{document}
+
+ \section{Foo}%
+ \label{sec:foo}
+
+ \begin{equation}%
+ \label{eq:foo}
+ 1 + 1 = 2
+ \end{equation}
+
+ \begin{equation}%
+ \label{eq:bar}
+ 1 + 1 = 2
+ \end{equation}
+
+ \begin{figure}%
+ \LaTeX{}
+ \caption{Baz}%
+ \label{fig:baz}
+ \end{figure}
+
+ \begin{lemma}%
+ \label{thm:foo}
+ 1 + 1 = 2
+ \end{lemma}
+
+ \include{bar}
+
+ \end{document}
+ "#,
+ "latex",
+ true,
+ )?;
+ server.open(
+ "foo.aux",
+ r#"
+ \relax
+ \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Baz\relax }}{1}\protected@file@percent }
+ \providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}}
+ \newlabel{fig:baz}{{1}{1}}
+ \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
+ \newlabel{sec:foo}{{1}{1}}
+ \newlabel{eq:foo}{{1}{1}}
+ \newlabel{eq:bar}{{2}{1}}
+ \newlabel{thm:foo}{{1}{1}}
+ \@input{bar.aux}
+ "#,
+ "latex",
+ true,
+ )?;
+ let uri = server.open(
+ "bar.tex",
+ r#"
+ \section{Bar}%
+ \label{sec:bar}
+
+ Lorem ipsum dolor sit amet.
+ \ref{}
+ \eqref{}
+ "#,
+ "latex",
+ true,
+ )?;
+ server.open(
+ "bar.aux",
+ r#"
+ \relax
+ \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{2}\protected@file@percent }
+ \newlabel{sec:bar}{{2}{2}}
+ \@setckpt{bar}{
+ \setcounter{page}{3}
+ \setcounter{equation}{2}
+ \setcounter{enumi}{0}
+ \setcounter{enumii}{0}
+ \setcounter{enumiii}{0}
+ \setcounter{enumiv}{0}
+ \setcounter{footnote}{0}
+ \setcounter{mpfootnote}{0}
+ \setcounter{part}{0}
+ \setcounter{section}{2}
+ \setcounter{subsection}{0}
+ \setcounter{subsubsection}{0}
+ \setcounter{paragraph}{0}
+ \setcounter{subparagraph}{0}
+ \setcounter{figure}{1}
+ \setcounter{table}{0}
+ \setcounter{parentequation}{0}
+ \setcounter{caption@flags}{0}
+ \setcounter{ContinuedFloat}{0}
+ \setcounter{lemma}{1}
+ "#,
+ "latex",
+ true,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 4, 5)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_preselect_environment() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \usepackage{amsthm}
- \newtheorem{foo}{Foo}
- \begin{f}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 3, 7, "foo").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 3, 7, 3, 8, "foo");
- verify_detail(&actual_item, "user-defined");
-}
-
-#[tokio::test]
-async fn latex_pgf_library() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \begin{document}
+ \end{
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 5)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_theorem_environment() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \usepackage{tikz}
- \usepgflibrary{}
- \usetikzlibrary{}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 1, 15, "arrows").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 1, 15, 1, 15, "arrows");
-}
-
-#[tokio::test]
-async fn latex_tikz_library() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \documentclass{article}
+ \usepackage{amsthm}
+ \newtheorem{foo}{Foo}
+ \begin{f}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 3, 7)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_pgf_library() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \usepackage{tikz}
- \usepgflibrary{}
- \usetikzlibrary{}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 2, 16, "arrows").await;
-
- test_bed.shutdown().await;
-
- verify_text_edit(&actual_item, 2, 16, 2, 16, "arrows");
-}
-
-#[tokio::test]
-async fn latex_user_command() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \usepackage{tikz}
+ \usepgflibrary{}
+ \usetikzlibrary{}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 15)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_user_command() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \foo
- \fo
- \begin{foo}
- \end{foo}
- \begin{fo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 1, 3, "foo").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "user-defined");
- verify_text_edit(&actual_item, 1, 1, 1, 3, "foo");
-}
-
-#[tokio::test]
-async fn latex_user_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file(
+ r#"
+ \foobar
+ \fooba
+ \begin{foo}
+ \end{foo}
+ \begin{fo}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 1, 3)?);
+ Ok(())
+ }
+
+ #[test]
+ fn test_user_environment() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
"main.tex",
- indoc!(
- r#"
- \foo
- \fo
- \begin{foo}
- \end{foo}
- \begin{fo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_item = run_item(&test_bed, "main.tex", 4, 7, "foo").await;
-
- test_bed.shutdown().await;
-
- verify_detail(&actual_item, "user-defined");
- verify_text_edit(&actual_item, 4, 7, 4, 9, "foo");
+ r#"
+ \foobar
+ \fooba
+ \begin{foo}
+ \end{foo}
+ \begin{fo}
+ "#,
+ "latex",
+ false,
+ )?;
+ assert_json_snapshot!(complete_and_resolve(&server, uri, 4, 7)?);
+ Ok(())
+ }
}
diff --git a/support/texlab/tests/integration/definition.rs b/support/texlab/tests/integration/definition.rs
deleted file mode 100644
index 685b121377..0000000000
--- a/support/texlab/tests/integration/definition.rs
+++ /dev/null
@@ -1,482 +0,0 @@
-use indoc::indoc;
-use texlab::{
- protocol::{LocationLink, Range, RangeExt},
- test::{TestBedBuilder, LOCATION_LINK_CAPABILITIES, PULL_CAPABILITIES},
-};
-
-fn verify_origin_selection_range(
- link: &LocationLink,
- start_line: u64,
- start_character: u64,
- end_line: u64,
- end_character: u64,
-) {
- assert_eq!(
- link.origin_selection_range,
- Some(Range::new_simple(
- start_line,
- start_character,
- end_line,
- end_character
- ))
- );
-}
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_locations = test_bed
- .definition_location("main.tex", 0, 0)
- .await
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_locations.is_empty());
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_locations = test_bed
- .definition_location("main.bib", 0, 0)
- .await
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_locations.is_empty());
-}
-
-#[tokio::test]
-async fn bibtex_string() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = "Foo"}
- %
- @string{bar = "Bar"}
- %
- @article{baz,
- author = bar
- }
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.bib").await;
-
- let mut actual_links = test_bed.definition_link("main.bib", 5, 14).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 5, 13, 5, 16);
- assert_eq!(link.target_uri, test_bed.uri("main.bib").into());
- assert_eq!(link.target_range, Range::new_simple(2, 0, 2, 20));
- assert_eq!(link.target_selection_range, Range::new_simple(2, 8, 2, 11));
-}
-
-#[tokio::test]
-async fn latex_citation_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \bibliography{bar}
- \cite{bar}
- "#
- ),
- )
- .file(
- "bar.bib",
- indoc!(
- r#"
- @article{foo,}
- %
- @article{bar,}
- "#
- ),
- )
- .file(
- "baz.bib",
- indoc!(
- r#"
- @article{foo,}
- %
- @article{bar,}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("foo.tex").await;
- test_bed.open("bar.bib").await;
- test_bed.open("baz.bib").await;
-
- let mut actual_links = test_bed.definition_link("foo.tex", 1, 7).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 1, 6, 1, 9);
- assert_eq!(link.target_uri, test_bed.uri("bar.bib").into());
- assert_eq!(link.target_range, Range::new_simple(2, 0, 2, 14));
- assert_eq!(link.target_selection_range, Range::new_simple(2, 9, 2, 12));
-}
-
-#[tokio::test]
-async fn latex_citation_location() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \bibliography{bar}
- \cite{bar}
- "#
- ),
- )
- .file(
- "bar.bib",
- indoc!(
- r#"
- @article{foo,}
- %
- @article{bar,}
- "#
- ),
- )
- .file(
- "baz.bib",
- indoc!(
- r#"
- @article{foo,}
- %
- @article{bar,}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("foo.tex").await;
- test_bed.open("bar.bib").await;
- test_bed.open("baz.bib").await;
-
- let mut actual_locations = test_bed.definition_location("foo.tex", 1, 7).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_locations.len(), 1);
- let location = actual_locations.pop().unwrap();
- assert_eq!(location.uri, test_bed.uri("bar.bib").into());
- assert_eq!(location.range, Range::new_simple(2, 9, 2, 12));
-}
-
-#[tokio::test]
-async fn latex_command_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \newcommand{\foo}{Foo}
- %
- \foo
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 2, 2).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 2, 0, 2, 4);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 0, 22));
- assert_eq!(link.target_selection_range, Range::new_simple(0, 0, 0, 22));
-}
-
-#[tokio::test]
-async fn latex_math_operator_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \DeclareMathOperator{\foo}{foo}
- %
- \foo
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 2, 2).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 2, 0, 2, 4);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 0, 31));
- assert_eq!(link.target_selection_range, Range::new_simple(0, 0, 0, 31));
-}
-
-#[tokio::test]
-async fn latex_label_unknown_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \label{foo}
- \ref{foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 1, 7).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 1, 5, 1, 8);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 0, 11));
- assert_eq!(link.target_selection_range, Range::new_simple(0, 0, 0, 11));
-}
-
-#[tokio::test]
-async fn latex_label_equation_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{equation}%
- \label{eq:foo}
- Foo
- \end{equation}
- %
- \ref{eq:foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 5, 8).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 5, 5, 5, 11);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 3, 14));
- assert_eq!(link.target_selection_range, Range::new_simple(1, 0, 1, 14));
-}
-
-#[tokio::test]
-async fn latex_label_float_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{figure}
- Foo
- \caption{Bar}
- \label{fig}
- \end{figure}
- %
- \ref{fig}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 6, 6).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 6, 5, 6, 8);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 4, 12));
- assert_eq!(link.target_selection_range, Range::new_simple(3, 0, 3, 11));
-}
-
-#[tokio::test]
-async fn latex_label_item_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{enumerate}
- \item Foo
- \item\label{bar} Bar
- \item Baz
- \end{enumerate}
- %
- \ref{bar}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 6, 6).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 6, 5, 6, 8);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 4, 15));
- assert_eq!(link.target_selection_range, Range::new_simple(2, 9, 2, 20));
-}
-
-#[tokio::test]
-async fn latex_label_section_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \section{Foo}
- \label{sec:foo}
- %
- \section{Bar}
- \label{sec:bar}
- %
- \ref{sec:foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 6, 6).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 6, 5, 6, 12);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(0, 0, 3, 0));
- assert_eq!(link.target_selection_range, Range::new_simple(1, 0, 1, 15));
-}
-
-#[tokio::test]
-async fn latex_label_theorem_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \usepackage{amsthm}
- \newtheorem{lemma}{Lemma}
- %
- \begin{lemma}%
- \label{thm:foo}
- Foo
- \end{lemma}
- %
- \ref{thm:foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let mut actual_links = test_bed.definition_link("main.tex", 8, 7).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links.len(), 1);
- let link = actual_links.pop().unwrap();
- verify_origin_selection_range(&link, 8, 5, 8, 12);
- assert_eq!(link.target_uri, test_bed.uri("main.tex").into());
- assert_eq!(link.target_range, Range::new_simple(3, 0, 6, 11));
- assert_eq!(link.target_selection_range, Range::new_simple(4, 0, 4, 15));
-}
diff --git a/support/texlab/tests/integration/document_symbol.rs b/support/texlab/tests/integration/document_symbol.rs
index afc3d54831..dbdbe64972 100644
--- a/support/texlab/tests/integration/document_symbol.rs
+++ b/support/texlab/tests/integration/document_symbol.rs
@@ -1,424 +1,438 @@
-use indoc::indoc;
-use texlab::{
- protocol::{DocumentSymbol, Range, RangeExt},
- test::{TestBedBuilder, NESTED_SYMBOL_CAPABILITIES},
+use anyhow::Result;
+use insta::assert_json_snapshot;
+use lsp_types::{
+ ClientCapabilities, DocumentSymbolClientCapabilities, TextDocumentClientCapabilities, Url,
};
-fn verify_symbol(
- symbol: &DocumentSymbol,
- name: &str,
- detail: Option<&str>,
- selection_range: Range,
- range: Range,
-) {
- assert_eq!(symbol.name, name);
- assert_eq!(symbol.detail.as_ref().map(AsRef::as_ref), detail);
- assert_eq!(symbol.selection_range, selection_range);
- assert_eq!(symbol.range, range);
+use crate::common::ServerTester;
+
+fn nested_symbol_capabilities() -> ClientCapabilities {
+ ClientCapabilities {
+ text_document: Some(TextDocumentClientCapabilities {
+ document_symbol: Some(DocumentSymbolClientCapabilities {
+ hierarchical_document_symbol_support: Some(true),
+ ..DocumentSymbolClientCapabilities::default()
+ }),
+ ..TextDocumentClientCapabilities::default()
+ }),
+ ..ClientCapabilities::default()
+ }
}
-#[tokio::test]
-async fn enumerate() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- %
- \begin{document}
- %
- \begin{enumerate}
- \item\label{it:foo} Foo
- \item\label{it:bar} Bar
- \item[Baz] Baz
- \item[Qux]\label{it:qux} Qux
- \end{enumerate}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "main.aux",
- indoc!(
- r#"
- \relax
- \newlabel{it:foo}{{1}{1}}
- \newlabel{it:qux}{{2}{1}}
- "#
- ),
- )
- .build()
- .await;
-
- test_bed.spawn();
- test_bed
- .initialize(NESTED_SYMBOL_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
- test_bed.open("main.aux").await;
-
- let mut actual_symbols = test_bed.document_symbol_nested("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_symbols.len(), 1);
- verify_symbol(
- &actual_symbols[0],
- "Enumerate",
- None,
- Range::new_simple(4, 0, 9, 15),
- Range::new_simple(4, 0, 9, 15),
- );
-
- let children = actual_symbols[0].children.take().unwrap();
- assert_eq!(children.len(), 4);
- verify_symbol(
- &children[0],
- "1",
- Some("it:foo"),
- Range::new_simple(5, 9, 5, 23),
- Range::new_simple(5, 4, 6, 4),
- );
- verify_symbol(
- &children[1],
- "Item",
- Some("it:bar"),
- Range::new_simple(6, 9, 6, 23),
- Range::new_simple(6, 4, 7, 4),
- );
- verify_symbol(
- &children[2],
- "Baz",
- None,
- Range::new_simple(7, 4, 7, 14),
- Range::new_simple(7, 4, 8, 4),
- );
- verify_symbol(
- &children[3],
- "Qux",
- Some("it:qux"),
- Range::new_simple(8, 14, 8, 28),
- Range::new_simple(8, 4, 9, 0),
- );
+#[test]
+fn test_enumerate_nested() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(nested_symbol_capabilities(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \begin{enumerate}
+ \item\label{it:foo} Foo
+ \item\label{it:bar} Bar
+ \item[Baz] Baz
+ \item[Qux]\label{it:qux} Qux
+ \end{enumerate}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \newlabel{it:foo}{{1}{1}}
+ \newlabel{it:qux}{{2}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
}
-#[tokio::test]
-async fn equation() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- %
- \begin{document}
- %
- \begin{equation}\label{eq:foo}
- Foo
- \end{equation}
- %
- \begin{equation}\label{eq:bar}
- Bar
- \end{equation}
- %
- \begin{equation}
- Baz
- \end{equation}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "main.aux",
- indoc!(
- r#"
- \relax
- \newlabel{eq:foo}{{1}{1}}
- "#
- ),
- )
- .build()
- .await;
-
- test_bed.spawn();
- test_bed
- .initialize(NESTED_SYMBOL_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
- test_bed.open("main.aux").await;
-
- let actual_symbols = test_bed.document_symbol_nested("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_symbols.len(), 3);
- verify_symbol(
- &actual_symbols[0],
- "Equation (1)",
- Some("eq:foo"),
- Range::new_simple(4, 16, 4, 30),
- Range::new_simple(4, 0, 6, 14),
- );
- verify_symbol(
- &actual_symbols[1],
- "Equation",
- Some("eq:bar"),
- Range::new_simple(8, 16, 8, 30),
- Range::new_simple(8, 0, 10, 14),
- );
- verify_symbol(
- &actual_symbols[2],
- "Equation",
- None,
- Range::new_simple(12, 0, 14, 14),
- Range::new_simple(12, 0, 14, 14),
- );
+#[test]
+fn test_enumerate_flat() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \begin{enumerate}
+ \item\label{it:foo} Foo
+ \item\label{it:bar} Bar
+ \item[Baz] Baz
+ \item[Qux]\label{it:qux} Qux
+ \end{enumerate}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \newlabel{it:foo}{{1}{1}}
+ \newlabel{it:qux}{{2}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
}
-#[tokio::test]
-async fn float() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- %
- \begin{document}
- %
- \begin{figure}
- Foo
- \caption{Foo}\label{fig:foo}
- \end{figure}
- %
- \begin{figure}
- Bar
- \caption{Bar}\label{fig:bar}
- \end{figure}
- %
- \begin{figure}
- Baz
- \caption{Baz}
- \end{figure}
- %
- \begin{figure}
- Qux
- \end{figure}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "main.aux",
- indoc!(
- r#"
- \relax
- \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Foo}}{1}\protected@file@percent }
- \newlabel{fig:foo}{{1}{1}}
- \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Bar}}{1}\protected@file@percent }
- \@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Baz}}{1}\protected@file@percent }
- "#
- ),
- )
- .build()
- .await;
-
- test_bed.spawn();
- test_bed
- .initialize(NESTED_SYMBOL_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
- test_bed.open("main.aux").await;
-
- let actual_symbols = test_bed.document_symbol_nested("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_symbols.len(), 3);
- verify_symbol(
- &actual_symbols[0],
- "Figure 1: Foo",
- Some("fig:foo"),
- Range::new_simple(6, 17, 6, 32),
- Range::new_simple(4, 0, 7, 12),
- );
- verify_symbol(
- &actual_symbols[1],
- "Figure: Bar",
- Some("fig:bar"),
- Range::new_simple(11, 17, 11, 32),
- Range::new_simple(9, 0, 12, 12),
- );
- verify_symbol(
- &actual_symbols[2],
- "Figure: Baz",
- None,
- Range::new_simple(14, 0, 17, 12),
- Range::new_simple(14, 0, 17, 12),
- );
+#[test]
+fn test_equation_nested() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(nested_symbol_capabilities(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \begin{equation}\label{eq:foo}
+ Foo
+ \end{equation}
+
+ \begin{equation}\label{eq:bar}
+ Bar
+ \end{equation}
+
+ \begin{equation}
+ Baz
+ \end{equation}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \newlabel{eq:foo}{{1}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
}
-#[tokio::test]
-async fn section() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- %
- \begin{document}
- %
- \section{Foo}
- %
- \section{Bar}\label{sec:bar}
- %
- \subsection{Baz}\label{sec:baz}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "main.aux",
- indoc!(
- r#"
- \relax
- \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
- \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{1}\protected@file@percent }
- \newlabel{sec:bar}{{2}{1}}
- "#
- ),
- )
- .build()
- .await;
-
- test_bed.spawn();
- test_bed
- .initialize(NESTED_SYMBOL_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
- test_bed.open("main.aux").await;
-
- let mut actual_symbols = test_bed.document_symbol_nested("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_symbols.len(), 2);
- verify_symbol(
- &actual_symbols[0],
- "Foo",
- None,
- Range::new_simple(4, 0, 4, 13),
- Range::new_simple(4, 0, 6, 0),
- );
- verify_symbol(
- &actual_symbols[1],
- "2 Bar",
- Some("sec:bar"),
- Range::new_simple(6, 0, 6, 13),
- Range::new_simple(6, 0, 10, 0),
- );
-
- let children = actual_symbols[1].children.take().unwrap();
- assert_eq!(children.len(), 1);
- verify_symbol(
- &children[0],
- "Baz",
- Some("sec:baz"),
- Range::new_simple(8, 0, 8, 16),
- Range::new_simple(8, 0, 10, 0),
- );
+#[test]
+fn test_equation_flat() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \begin{equation}\label{eq:foo}
+ Foo
+ \end{equation}
+
+ \begin{equation}\label{eq:bar}
+ Bar
+ \end{equation}
+
+ \begin{equation}
+ Baz
+ \end{equation}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \newlabel{eq:foo}{{1}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
}
-#[tokio::test]
-async fn theorem() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \usepackage{amsthm}
- \newtheorem{lemma}{Lemma}
- %
- \begin{document}
- %
- \begin{lemma}[Foo]\label{thm:foo}
- Foo
- \end{lemma}
- %
- \begin{lemma}\label{thm:bar}
- Bar
- \end{lemma}
- %
- \begin{lemma}\label{thm:baz}
- Baz
- \end{lemma}
- %
- \begin{lemma}[Qux]
- Qux
- \end{lemma}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "main.aux",
- indoc!(
- r#"
- \relax
- \newlabel{thm:foo}{{1}{1}}
- \newlabel{thm:bar}{{2}{1}}
- "#
- ),
- )
- .build()
- .await;
-
- test_bed.spawn();
- test_bed
- .initialize(NESTED_SYMBOL_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
- test_bed.open("main.aux").await;
-
- let actual_symbols = test_bed.document_symbol_nested("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_symbols.len(), 4);
- verify_symbol(
- &actual_symbols[0],
- "Lemma 1 (Foo)",
- Some("thm:foo"),
- Range::new_simple(6, 18, 6, 33),
- Range::new_simple(6, 0, 8, 11),
- );
- verify_symbol(
- &actual_symbols[1],
- "Lemma 2",
- Some("thm:bar"),
- Range::new_simple(10, 13, 10, 28),
- Range::new_simple(10, 0, 12, 11),
- );
- verify_symbol(
- &actual_symbols[2],
- "Lemma",
- Some("thm:baz"),
- Range::new_simple(14, 13, 14, 28),
- Range::new_simple(14, 0, 16, 11),
- );
- verify_symbol(
- &actual_symbols[3],
- "Lemma (Qux)",
- None,
- Range::new_simple(18, 0, 20, 11),
- Range::new_simple(18, 0, 20, 11),
- );
+#[test]
+fn test_float_nested() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(nested_symbol_capabilities(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \begin{figure}
+ Foo
+ \caption{Foo}\label{fig:foo}
+ \end{figure}
+
+ \begin{figure}
+ Bar
+ \caption{Bar}\label{fig:bar}
+ \end{figure}
+
+ \begin{figure}
+ Baz
+ \caption{Baz}
+ \end{figure}
+
+ \begin{figure}
+ Qux
+ \end{figure}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Foo}}{1}\protected@file@percent }
+ \newlabel{fig:foo}{{1}{1}}
+ \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Bar}}{1}\protected@file@percent }
+ \@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Baz}}{1}\protected@file@percent }
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
+}
+
+#[test]
+fn test_float_flat() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \begin{figure}
+ Foo
+ \caption{Foo}\label{fig:foo}
+ \end{figure}
+
+ \begin{figure}
+ Bar
+ \caption{Bar}\label{fig:bar}
+ \end{figure}
+
+ \begin{figure}
+ Baz
+ \caption{Baz}
+ \end{figure}
+
+ \begin{figure}
+ Qux
+ \end{figure}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Foo}}{1}\protected@file@percent }
+ \newlabel{fig:foo}{{1}{1}}
+ \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Bar}}{1}\protected@file@percent }
+ \@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Baz}}{1}\protected@file@percent }
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
+}
+
+#[test]
+fn test_section_nested() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(nested_symbol_capabilities(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \section{Foo}
+
+ \section{Bar}\label{sec:bar}
+
+ \subsection{Baz}\label{sec:baz}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
+ \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{1}\protected@file@percent }
+ \newlabel{sec:bar}{{2}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
+}
+
+#[test]
+fn test_section_flat() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+
+ \begin{document}
+
+ \section{Foo}
+
+ \section{Bar}\label{sec:bar}
+
+ \subsection{Baz}\label{sec:baz}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
+ \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{1}\protected@file@percent }
+ \newlabel{sec:bar}{{2}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
+}
+
+#[test]
+fn test_theorem_nested() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(nested_symbol_capabilities(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+ \usepackage{amsthm}
+ \newtheorem{lemma}{Lemma}
+
+ \begin{document}
+
+ \begin{lemma}[Foo]\label{thm:foo}
+ Foo
+ \end{lemma}
+
+ \begin{lemma}\label{thm:bar}
+ Bar
+ \end{lemma}
+
+ \begin{lemma}\label{thm:baz}
+ Baz
+ \end{lemma}
+
+ \begin{lemma}[Qux]
+ Qux
+ \end{lemma}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \newlabel{thm:foo}{{1}{1}}
+ \newlabel{thm:bar}{{2}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
+}
+
+#[test]
+fn test_theorem_flat() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+ \usepackage{amsthm}
+ \newtheorem{lemma}{Lemma}
+
+ \begin{document}
+
+ \begin{lemma}[Foo]\label{thm:foo}
+ Foo
+ \end{lemma}
+
+ \begin{lemma}\label{thm:bar}
+ Bar
+ \end{lemma}
+
+ \begin{lemma}\label{thm:baz}
+ Baz
+ \end{lemma}
+
+ \begin{lemma}[Qux]
+ Qux
+ \end{lemma}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \newlabel{thm:foo}{{1}{1}}
+ \newlabel{thm:bar}{{2}{1}}
+ "#,
+ "latex",
+ )?;
+ assert_json_snapshot!(server.find_document_symbols(uri)?);
+ Ok(())
}
diff --git a/support/texlab/tests/integration/folding.rs b/support/texlab/tests/integration/folding.rs
deleted file mode 100644
index 3540e2c680..0000000000
--- a/support/texlab/tests/integration/folding.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-use indoc::indoc;
-use texlab::{
- protocol::{FoldingRange, FoldingRangeKind},
- test::{TestBedBuilder, PULL_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_foldings = test_bed.folding_range("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_foldings.is_empty());
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_foldings = test_bed.folding_range("main.bib").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_foldings.is_empty());
-}
-
-#[tokio::test]
-async fn latex_sections_with_env() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{document}
- \section{Foo}
- Foo
- \section{Bar}
- Bar
- \end{document}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_foldings = test_bed.folding_range("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_foldings = vec![
- FoldingRange {
- start_line: 0,
- start_character: Some(16),
- end_line: 5,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- },
- FoldingRange {
- start_line: 1,
- start_character: Some(13),
- end_line: 2,
- end_character: Some(0),
- kind: Some(FoldingRangeKind::Region),
- },
- ];
- assert_eq!(actual_foldings, expected_foldings);
-}
-
-#[tokio::test]
-async fn bibtex_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo,
- author = {Foo Bar},
- title = {Baz Qux},
- }
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_foldings = test_bed.folding_range("main.bib").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_foldings = vec![FoldingRange {
- start_line: 0,
- start_character: Some(0),
- end_line: 3,
- end_character: Some(1),
- kind: Some(FoldingRangeKind::Region),
- }];
- assert_eq!(actual_foldings, expected_foldings);
-}
-
-#[tokio::test]
-async fn unknown_file() {
- let mut test_bed = TestBedBuilder::new().build().await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
-
- let actual_foldings = test_bed.folding_range("main.tex").await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_foldings, None);
-}
diff --git a/support/texlab/tests/integration/highlight.rs b/support/texlab/tests/integration/highlight.rs
deleted file mode 100644
index ba77a7b8e3..0000000000
--- a/support/texlab/tests/integration/highlight.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-use indoc::indoc;
-use texlab::{
- protocol::{DocumentHighlight, DocumentHighlightKind, Range, RangeExt},
- test::{TestBedBuilder, PULL_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_highlights = test_bed.document_highlight("main.tex", 0, 0).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_highlights.is_empty());
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_highlights = test_bed.document_highlight("main.bib", 0, 0).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_highlights.is_empty());
-}
-
-#[tokio::test]
-async fn label() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \label{foo}
- \ref{foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_highlights = test_bed.document_highlight("main.tex", 0, 7).await.unwrap();
-
- let expected_highlights = vec![
- DocumentHighlight {
- range: Range::new_simple(0, 7, 0, 10),
- kind: Some(DocumentHighlightKind::Write),
- },
- DocumentHighlight {
- range: Range::new_simple(1, 5, 1, 8),
- kind: Some(DocumentHighlightKind::Read),
- },
- ];
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_highlights, expected_highlights);
-}
-
-#[tokio::test]
-async fn unknown_file() {
- let mut test_bed = TestBedBuilder::new().build().await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
-
- let actual_highlights = test_bed.document_highlight("main.tex", 0, 0).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_highlights, None);
-}
diff --git a/support/texlab/tests/integration/hover.rs b/support/texlab/tests/integration/hover.rs
index 319ebcc5e9..70b14cccd0 100644
--- a/support/texlab/tests/integration/hover.rs
+++ b/support/texlab/tests/integration/hover.rs
@@ -1,86 +1,89 @@
-use indoc::indoc;
-use texlab::{
- protocol::{HoverContents, MarkupContent, MarkupKind},
- test::{TestBedBuilder, PULL_CAPABILITIES},
-};
+use anyhow::Result;
+use insta::assert_json_snapshot;
+use lsp_types::ClientCapabilities;
-#[tokio::test]
-async fn label_theorem_child_file() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \newtheorem{lemma}{Lemma}
- \include{child}
- \ref{thm:foo}
- "#
- ),
- )
- .file(
- "child.tex",
- indoc!(
- r#"
- \begin{lemma}\label{thm:foo}
- 1 + 1 = 2
- \end{lemma}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
+use crate::common::ServerTester;
- let actual_hover = test_bed.hover("main.tex", 3, 8).await.unwrap().unwrap();
- assert_eq!(
- actual_hover.contents,
- HoverContents::Markup(MarkupContent {
- kind: MarkupKind::PlainText,
- value: "Lemma".into()
- })
- );
+#[test]
+fn test_empty_bibtex_document() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open("main.bib", "", "bibtex", false)?;
+ assert_json_snapshot!(server.hover(uri, 0, 0)?);
+ Ok(())
}
-#[tokio::test]
-async fn label_theorem_child_file_number() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \newtheorem{lemma}{Lemma}
- \include{child}
- \ref{thm:foo}
- "#
- ),
- )
- .file(
- "child.tex",
- indoc!(
- r#"
- \begin{lemma}[Foo]\label{thm:foo}
- 1 + 1 = 2
- \end{lemma}
- "#
- ),
- )
- .file("child.aux", r#"\newlabel{thm:foo}{{1}{1}{Foo}{lemma.1}{}}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
+#[test]
+fn test_empty_labtex_document() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open("main.tex", "", "latex", false)?;
+ assert_json_snapshot!(server.hover(uri, 0, 0)?);
+ Ok(())
+}
+
+#[test]
+fn test_label_theorem_child_file() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
+ "main.tex",
+ r#"
+ \documentclass{article}
+ \newtheorem{lemma}{Lemma}
+ \include{child}
+ \ref{thm:foo}
+ "#,
+ "latex",
+ false,
+ )?;
+ server.open(
+ "child.tex",
+ r#"
+ \begin{lemma}\label{thm:foo}
+ 1 + 1 = 2
+ \end{lemma}
+ "#,
+ "latex",
+ false,
+ )?;
+
+ assert_json_snapshot!(server.hover(uri, 3, 8)?);
+ Ok(())
+}
+
+#[test]
+fn test_label_theorem_child_file_mumber() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = server.open(
+ "main.tex",
+ r#"
+ \documentclass{article}
+ \newtheorem{lemma}{Lemma}
+ \include{child}
+ \ref{thm:foo}
+ "#,
+ "latex",
+ false,
+ )?;
+ server.open(
+ "child.tex",
+ r#"
+ \begin{lemma}[Foo]\label{thm:foo}
+ 1 + 1 = 2
+ \end{lemma}
+ "#,
+ "latex",
+ false,
+ )?;
+ server.open(
+ "child.aux",
+ r#"\newlabel{thm:foo}{{1}{1}{Foo}{lemma.1}{}}"#,
+ "latex",
+ false,
+ )?;
- let actual_hover = test_bed.hover("main.tex", 3, 8).await.unwrap().unwrap();
- assert_eq!(
- actual_hover.contents,
- HoverContents::Markup(MarkupContent {
- kind: MarkupKind::PlainText,
- value: "Lemma 1 (Foo)".into()
- })
- );
+ assert_json_snapshot!(server.hover(uri, 3, 8)?);
+ Ok(())
}
diff --git a/support/texlab/tests/integration/issues.rs b/support/texlab/tests/integration/issues.rs
index 59a1bfeacb..5d6caeb79d 100644
--- a/support/texlab/tests/integration/issues.rs
+++ b/support/texlab/tests/integration/issues.rs
@@ -1,350 +1,41 @@
-use indoc::indoc;
-use texlab::{
- protocol::{HoverContents, Location, LocationLink, MarkupContent, MarkupKind, Range, RangeExt},
- test::{TestBedBuilder, LOCATION_LINK_CAPABILITIES, PULL_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn issue_14() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.tex", r#"\(\be\)"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = test_bed.completion("main.tex", 0, 5).await.unwrap();
-
- test_bed.shutdown().await;
- assert!(actual_items.iter().any(|item| item.label == "beta"));
-}
-
-#[tokio::test]
-async fn issue_15_link() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \begin{document}
- \newcommand{\test}{test}
- hello \test{}
- \end{document}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed
- .initialize(LOCATION_LINK_CAPABILITIES.clone())
- .await;
- test_bed.open("main.tex").await;
-
- let actual_links = test_bed.definition_link("main.tex", 3, 9).await.unwrap();
-
- test_bed.shutdown().await;
- let expected_links = vec![LocationLink {
- origin_selection_range: Some(Range::new_simple(3, 6, 3, 13)),
- target_range: Range::new_simple(2, 0, 2, 24),
- target_selection_range: Range::new_simple(2, 0, 2, 24),
- target_uri: test_bed.uri("main.tex").into(),
- }];
- assert_eq!(actual_links, expected_links);
-}
-
-#[tokio::test]
-async fn issue_15_location() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \begin{document}
- \newcommand{\test}{test}
- hello \test{}
- \end{document}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_locations = test_bed
- .definition_location("main.tex", 3, 9)
- .await
- .unwrap();
-
- test_bed.shutdown().await;
- let expected_locations = vec![Location {
- range: Range::new_simple(2, 0, 2, 24),
- uri: test_bed.uri("main.tex").into(),
- }];
- assert_eq!(actual_locations, expected_locations);
-}
-
-#[tokio::test]
-async fn issue_17() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.bib", r#"@ARTICLE{foo,}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_hover = test_bed.hover("main.bib", 0, 3).await.unwrap().unwrap();
-
- test_bed.shutdown().await;
- assert_eq!(actual_hover.range.unwrap(), Range::new_simple(0, 0, 0, 8));
-}
-
-#[tokio::test]
-async fn issue_21() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \label{foo}
- \cref{}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = test_bed.completion("main.tex", 1, 6).await.unwrap();
-
- test_bed.shutdown().await;
- assert!(actual_items.iter().any(|item| item.label == "foo"));
-}
-
-#[tokio::test]
-async fn issue_22_include() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \bibliography{bibfile}
- \cite{}
- "#
- ),
- )
- .file("bibfile.bib", r#"@article{foo,}"#)
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = test_bed.completion("main.tex", 1, 6).await.unwrap();
-
- test_bed.shutdown().await;
- assert!(actual_items.iter().any(|item| item.label == "foo"));
-}
-
-#[tokio::test]
-async fn issue_22_definition() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \bibliography{bibfile}
- \cite{A,B}
- "#
- ),
- )
- .file(
- "bibfile.bib",
- indoc!(
- r#"
- @article{A,}
- @article{B,}
- "#
- ),
- )
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_locations = test_bed
- .definition_location("main.tex", 1, 8)
- .await
- .unwrap();
-
- test_bed.shutdown().await;
- let expected_locations = vec![Location {
- range: Range::new_simple(1, 9, 1, 10),
- uri: test_bed.uri("bibfile.bib").into(),
- }];
- assert_eq!(actual_locations, expected_locations);
-}
-
-#[tokio::test]
-async fn issue_23_completion() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \begin{document}
- \include{test1}
- \include{test2}
- \end{document}
- "#
- ),
- )
- .file("test1.tex", r#"\section{Section 1}\label{sec:1}"#)
- .file(
- "test2.tex",
- indoc!(
- r#"
- \section{Section 2}\label{sec:2}
- %
- This section continues from Section \ref{sec}"#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("test2.tex").await;
- test_bed.detect_root("test2.tex").await;
-
- let actual_items = test_bed.completion("test2.tex", 2, 42).await.unwrap();
-
- test_bed.shutdown().await;
- assert_eq!(actual_items.len(), 2);
-}
-
-#[tokio::test]
-async fn issue_23_rename() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \begin{document}
- \include{test1}
- \include{test2}
- \end{document}
- "#
- ),
- )
- .file("test1.tex", r#"\section{Section 1}\label{sec:1}"#)
- .file(
- "test2.tex",
- indoc!(
- r#"
- \section{Section 2}\label{sec:2}
- %
- This section continues from Section \ref{sec:1}"#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("test1.tex").await;
- test_bed.detect_root("test1.tex").await;
-
- let workspace_edit = test_bed
- .rename("test1.tex", 0, 27, "foo")
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
- let changes = workspace_edit.changes.unwrap();
- assert!(changes.contains_key(&test_bed.uri("test1.tex")));
- assert!(changes.contains_key(&test_bed.uri("test2.tex")));
-}
-
-#[tokio::test]
-async fn issue_23_hover() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \documentclass{article}
- \begin{document}
- \include{test1}
- \include{test2}
- \end{document}
- "#
- ),
- )
- .file("test1.tex", r#"\section{Section 1}\label{sec:1}"#)
- .file(
- "test2.tex",
- indoc!(
- r#"
- \section{Section 2}\label{sec:2}
- %
- This section continues from Section \ref{sec:1}"#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("test2.tex").await;
- test_bed.detect_root("test2.tex").await;
-
- let actual_hover = test_bed.hover("test2.tex", 2, 42).await.unwrap().unwrap();
-
- test_bed.shutdown().await;
- assert_eq!(
- actual_hover.contents,
- HoverContents::Markup(MarkupContent {
- kind: MarkupKind::PlainText,
- value: "Section (Section 1)".into()
- })
- );
-}
-
-#[tokio::test]
-async fn issue_26() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \section{Foo}\label{sec:foo}
- \begin{equation}\label{eq:bar}
- \end{equation}
- \eqref{}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_items = test_bed.completion("main.tex", 3, 7).await.unwrap();
-
- test_bed.shutdown().await;
- assert!(actual_items.iter().any(|item| item.label == "eq:bar"));
- assert!(actual_items.iter().all(|item| item.label != "sec:foo"));
+use std::{fs, thread, time::Duration};
+
+use anyhow::Result;
+use lsp_types::ClientCapabilities;
+
+use crate::common::ServerTester;
+
+#[test]
+#[cfg(feature = "completion")]
+fn test_408_parent_expansion() -> Result<()> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let root = server.directory.path();
+
+ let level1 = root.join("level1");
+ let level2 = level1.join("level2");
+ let level3 = level2.join("level3");
+ fs::create_dir_all(&level3)?;
+ fs::write(level3.join("d.tex"), "d")?;
+ fs::write(
+ level2.join("c.tex"),
+ r#"\documentclass{subfiles}\begin{document}\include{level3/d}\end{document}"#,
+ )?;
+ fs::write(
+ level1.join("b.tex"),
+ r#"\documentclass{article}\begin{document}\include{level2/c}\end{document}"#,
+ )?;
+ fs::write(root.join("a.tex"), "}")?;
+
+ thread::sleep(Duration::from_millis(300));
+
+ let uri = server.open("level1/level2/level3/d.tex", "d", "latex", false)?;
+ server.complete(uri, 0, 0)?;
+
+ let diagnostics_by_uri = server.diagnostics_by_uri.lock().unwrap();
+ assert!(diagnostics_by_uri
+ .iter()
+ .all(|(uri, _)| !uri.as_str().ends_with("a.tex")));
+
+ Ok(())
}
diff --git a/support/texlab/tests/integration/link.rs b/support/texlab/tests/integration/link.rs
deleted file mode 100644
index 8db718bd26..0000000000
--- a/support/texlab/tests/integration/link.rs
+++ /dev/null
@@ -1,173 +0,0 @@
-use indoc::indoc;
-use texlab::{
- protocol::{DocumentLink, Range, RangeExt},
- test::{TestBedBuilder, PULL_CAPABILITIES, PUSH_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_links = test_bed.document_link("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_links.is_empty());
-}
-
-#[tokio::test]
-async fn default_settings() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \include{foo/bar}
- \input{qux.tex}
- "#
- ),
- )
- .file("foo/bar.tex", "")
- .file("qux.tex", "")
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_links = test_bed.document_link("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_links = vec![
- DocumentLink {
- range: Range::new_simple(0, 9, 0, 16),
- target: test_bed.uri("foo/bar.tex").into(),
- tooltip: None,
- },
- DocumentLink {
- range: Range::new_simple(1, 7, 1, 14),
- target: test_bed.uri("qux.tex").into(),
- tooltip: None,
- },
- ];
- assert_eq!(actual_links, expected_links);
-}
-
-#[tokio::test]
-async fn root_directory() {
- let mut test_bed = TestBedBuilder::new()
- .file("src/main.tex", r#"\include{src/foo}"#)
- .file("src/foo.tex", "")
- .root_dir(".")
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("src/main.tex").await;
-
- let actual_links = test_bed.document_link("src/main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_links = vec![DocumentLink {
- range: Range::new_simple(0, 9, 0, 16),
- target: test_bed.uri("src/foo.tex").into(),
- tooltip: None,
- }];
- assert_eq!(actual_links, expected_links);
-}
-
-#[tokio::test]
-async fn parent_directory() {
- let mut test_bed = TestBedBuilder::new()
- .file("src/main.tex", r#"\addbibresource{../foo.bib}"#)
- .file("foo.bib", "")
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("src/main.tex").await;
-
- let actual_links = test_bed.document_link("src/main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_links = vec![DocumentLink {
- range: Range::new_simple(0, 16, 0, 26),
- target: test_bed.uri("foo.bib").into(),
- tooltip: None,
- }];
- assert_eq!(actual_links, expected_links);
-}
-
-#[tokio::test]
-async fn unknown_file() {
- let mut test_bed = TestBedBuilder::new().build().await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
-
- let actual_links = test_bed.document_link("main.tex").await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_links, None);
-}
-
-#[tokio::test]
-async fn edit_file() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.tex", "")
- .file("foo.tex", "")
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
- test_bed.edit("main.tex", r#"\include{foo}"#).await;
-
- let actual_links = test_bed.document_link("main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_links = vec![DocumentLink {
- range: Range::new_simple(0, 9, 0, 12),
- target: test_bed.uri("foo.tex").into(),
- tooltip: None,
- }];
- assert_eq!(actual_links, expected_links);
-}
-
-#[tokio::test]
-async fn did_change_configuration() {
- let mut test_bed = TestBedBuilder::new()
- .file("src/main.tex", r#"\include{src/foo}"#)
- .file("src/foo.tex", "")
- .root_dir(".")
- .build()
- .await;
-
- test_bed.spawn();
- test_bed.initialize(PUSH_CAPABILITIES.clone()).await;
- test_bed.open("src/main.tex").await;
- test_bed.push_options().await;
-
- let actual_links = test_bed.document_link("src/main.tex").await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_links = vec![DocumentLink {
- range: Range::new_simple(0, 9, 0, 16),
- target: test_bed.uri("src/foo.tex").into(),
- tooltip: None,
- }];
- assert_eq!(actual_links, expected_links);
-}
diff --git a/support/texlab/tests/integration/main.rs b/support/texlab/tests/integration/main.rs
index 99c0b23a5c..ebccca7396 100644
--- a/support/texlab/tests/integration/main.rs
+++ b/support/texlab/tests/integration/main.rs
@@ -1,12 +1,7 @@
+mod common;
+#[cfg(feature = "completion")]
mod completion;
-mod definition;
mod document_symbol;
-mod folding;
-mod highlight;
mod hover;
mod issues;
-mod link;
-mod prepare_rename;
-mod reference;
-mod rename;
mod workspace_symbol;
diff --git a/support/texlab/tests/integration/prepare_rename.rs b/support/texlab/tests/integration/prepare_rename.rs
deleted file mode 100644
index 0efaa712b2..0000000000
--- a/support/texlab/tests/integration/prepare_rename.rs
+++ /dev/null
@@ -1,151 +0,0 @@
-use texlab::{
- protocol::{Range, RangeExt},
- test::{TestBedBuilder, PULL_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_range = test_bed.prepare_rename("main.tex", 0, 0).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, None);
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_range = test_bed.prepare_rename("main.bib", 0, 0).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, None);
-}
-
-#[tokio::test]
-async fn bibtex_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.bib", r#"@article{foo,}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_range = test_bed
- .prepare_rename("main.bib", 0, 10)
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, Range::new_simple(0, 9, 0, 12));
-}
-
-#[tokio::test]
-async fn latex_citation() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.tex", r#"\cite{foo,bar}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_range = test_bed
- .prepare_rename("main.tex", 0, 11)
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, Range::new_simple(0, 10, 0, 13));
-}
-
-#[tokio::test]
-async fn latex_command() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.tex", r#"\foo"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_range = test_bed
- .prepare_rename("main.tex", 0, 1)
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, Range::new_simple(0, 0, 0, 4));
-}
-
-#[tokio::test]
-async fn latex_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.tex", r#"\begin{foo}\end{bar}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_range = test_bed
- .prepare_rename("main.tex", 0, 7)
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, Range::new_simple(0, 7, 0, 10));
-}
-
-#[tokio::test]
-async fn latex_label() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.tex", r#"\ref{foo,bar}"#)
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_range = test_bed
- .prepare_rename("main.tex", 0, 9)
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, Range::new_simple(0, 9, 0, 12));
-}
-
-#[tokio::test]
-async fn unknown_file() {
- let mut test_bed = TestBedBuilder::new().build().await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
-
- let actual_range = test_bed.prepare_rename("main.tex", 0, 0).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_range, None);
-}
diff --git a/support/texlab/tests/integration/reference.rs b/support/texlab/tests/integration/reference.rs
deleted file mode 100644
index 224f85fbfc..0000000000
--- a/support/texlab/tests/integration/reference.rs
+++ /dev/null
@@ -1,150 +0,0 @@
-use indoc::indoc;
-use texlab::{
- protocol::{Location, Range, RangeExt},
- test::{TestBedBuilder, PULL_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_refs = test_bed.references("main.tex", 0, 0, false).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_refs.is_empty());
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_refs = test_bed.references("main.bib", 0, 0, false).await.unwrap();
-
- test_bed.shutdown().await;
-
- assert!(actual_refs.is_empty());
-}
-
-#[tokio::test]
-async fn bibtex_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file("main.bib", r#"@article{foo,}"#)
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
- test_bed.open("main.tex").await;
-
- let actual_refs = test_bed.references("main.tex", 1, 8, true).await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_refs = vec![
- Location {
- uri: test_bed.uri("main.tex").into(),
- range: Range::new_simple(1, 6, 1, 9),
- },
- Location {
- uri: test_bed.uri("main.bib").into(),
- range: Range::new_simple(0, 9, 0, 12),
- },
- ];
-
- assert_eq!(actual_refs, expected_refs);
-}
-
-#[tokio::test]
-async fn bibtex_string() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @string{foo = "foo"}
- @article{bar, author = foo # foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_refs = test_bed.references("main.bib", 1, 31, false).await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_refs = vec![
- Location {
- uri: test_bed.uri("main.bib").into(),
- range: Range::new_simple(1, 23, 1, 26),
- },
- Location {
- uri: test_bed.uri("main.bib").into(),
- range: Range::new_simple(1, 29, 1, 32),
- },
- ];
-
- assert_eq!(actual_refs, expected_refs);
-}
-
-#[tokio::test]
-async fn latex_label() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \label{foo}
- \ref{foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_refs = test_bed.references("main.tex", 0, 7, false).await.unwrap();
-
- test_bed.shutdown().await;
-
- let expected_refs = vec![Location {
- uri: test_bed.uri("main.tex").into(),
- range: Range::new_simple(1, 5, 1, 8),
- }];
-
- assert_eq!(actual_refs, expected_refs);
-}
-
-#[tokio::test]
-async fn unknown_file() {
- let mut test_bed = TestBedBuilder::new().build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
-
- let actual_refs = test_bed.references("main.tex", 0, 0, false).await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_refs, None);
-}
diff --git a/support/texlab/tests/integration/rename.rs b/support/texlab/tests/integration/rename.rs
deleted file mode 100644
index d8522f1ec6..0000000000
--- a/support/texlab/tests/integration/rename.rs
+++ /dev/null
@@ -1,236 +0,0 @@
-use indoc::indoc;
-use std::collections::HashMap;
-use texlab::{
- protocol::{Range, RangeExt, TextEdit, WorkspaceEdit},
- test::{TestBedBuilder, PULL_CAPABILITIES},
-};
-
-#[tokio::test]
-async fn empty_latex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.tex", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_edit = test_bed.rename("main.tex", 0, 0, "").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_edit, None);
-}
-
-#[tokio::test]
-async fn empty_bibtex_document() {
- let mut test_bed = TestBedBuilder::new().file("main.bib", "").build().await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
-
- let actual_edit = test_bed.rename("main.bib", 0, 0, "").await.unwrap();
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_edit, None);
-}
-
-#[tokio::test]
-async fn bibtex_entry() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.bib",
- indoc!(
- r#"
- @article{foo,}
- @article{bar,}
- "#
- ),
- )
- .file(
- "main.tex",
- indoc!(
- r#"
- \addbibresource{main.bib}
- \cite{foo,bar}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.bib").await;
- test_bed.open("main.tex").await;
-
- let actual_edit = test_bed
- .rename("main.bib", 1, 10, "baz")
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- test_bed.uri("main.bib").into(),
- vec![TextEdit::new(Range::new_simple(1, 9, 1, 12), "baz".into())],
- );
- expected_changes.insert(
- test_bed.uri("main.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 10, 1, 13), "baz".into())],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
-}
-
-#[tokio::test]
-async fn latex_command() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \input{bar.tex}
- \foo
- "#
- ),
- )
- .file(
- "bar.tex",
- indoc!(
- r#"
- \foo
- \bar
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("foo.tex").await;
- test_bed.open("bar.tex").await;
-
- let actual_edit = test_bed
- .rename("foo.tex", 1, 2, "baz")
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- test_bed.uri("foo.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 0, 1, 4), "\\baz".into())],
- );
- expected_changes.insert(
- test_bed.uri("bar.tex").into(),
- vec![TextEdit::new(Range::new_simple(0, 0, 0, 4), "\\baz".into())],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
-}
-
-#[tokio::test]
-async fn latex_environment() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "main.tex",
- indoc!(
- r#"
- \begin{foo}
- \begin{bar}
- Baz
- \end{bar}
- \end{foo}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("main.tex").await;
-
- let actual_edit = test_bed
- .rename("main.tex", 3, 11, "baz")
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- test_bed.uri("main.tex").into(),
- vec![
- TextEdit::new(Range::new_simple(1, 11, 1, 14), "baz".into()),
- TextEdit::new(Range::new_simple(3, 9, 3, 12), "baz".into()),
- ],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
-}
-
-#[tokio::test]
-async fn latex_label() {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \input{bar.tex}
- \ref{foo,bar}
- "#
- ),
- )
- .file(
- "bar.tex",
- indoc!(
- r#"
- \label{foo}
- \label{bar}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("foo.tex").await;
- test_bed.open("bar.tex").await;
-
- let actual_edit = test_bed
- .rename("foo.tex", 1, 10, "baz")
- .await
- .unwrap()
- .unwrap();
-
- test_bed.shutdown().await;
-
- let mut expected_changes = HashMap::new();
- expected_changes.insert(
- test_bed.uri("foo.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 9, 1, 12), "baz".into())],
- );
- expected_changes.insert(
- test_bed.uri("bar.tex").into(),
- vec![TextEdit::new(Range::new_simple(1, 7, 1, 10), "baz".into())],
- );
-
- assert_eq!(actual_edit, WorkspaceEdit::new(expected_changes));
-}
-
-#[tokio::test]
-async fn unknown_file() {
- let mut test_bed = TestBedBuilder::new().build().await;
-
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
-
- let actual_edit = test_bed.rename("main.tex", 0, 0, "").await;
-
- test_bed.shutdown().await;
-
- assert_eq!(actual_edit, None);
-}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_complete_entry.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_complete_entry.snap
new file mode 100644
index 0000000000..acd3389f49
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_complete_entry.snap
@@ -0,0 +1,150 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 18)?"
+
+---
+{
+ "isIncomplete": true,
+ "items": [
+ {
+ "label": "LaTeX",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "LaTeX"
+ }
+ },
+ {
+ "label": "LaTeXe",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "LaTeXe"
+ }
+ },
+ {
+ "label": "latexreleaseversion",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "latexreleaseversion"
+ }
+ },
+ {
+ "label": "LastDeclaredEncoding",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "LastDeclaredEncoding"
+ }
+ },
+ {
+ "label": "last",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "last"
+ }
+ },
+ {
+ "label": "lastbox",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "lastbox"
+ }
+ },
+ {
+ "label": "lastkern",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "lastkern"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_incomplete_entry.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_incomplete_entry.snap
new file mode 100644
index 0000000000..acd3389f49
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__command_incomplete_entry.snap
@@ -0,0 +1,150 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 18)?"
+
+---
+{
+ "isIncomplete": true,
+ "items": [
+ {
+ "label": "LaTeX",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "LaTeX"
+ }
+ },
+ {
+ "label": "LaTeXe",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "LaTeXe"
+ }
+ },
+ {
+ "label": "latexreleaseversion",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "latexreleaseversion"
+ }
+ },
+ {
+ "label": "LastDeclaredEncoding",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "LastDeclaredEncoding"
+ }
+ },
+ {
+ "label": "last",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "last"
+ }
+ },
+ {
+ "label": "lastbox",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "lastbox"
+ }
+ },
+ {
+ "label": "lastkern",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "lastkern"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__empty_document.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__empty_document.snap
new file mode 100644
index 0000000000..7f8638455c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__empty_document.snap
@@ -0,0 +1,9 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 0)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": []
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_complete.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_complete.snap
new file mode 100644
index 0000000000..fdc29dacb4
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_complete.snap
@@ -0,0 +1,33 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 1)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "article",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An article in a journal, magazine, newspaper, or other periodical which forms a \n self-contained unit with its own title. The title of the periodical is given in the \n journaltitle field. If the issue has its own title in addition to the main title of \n the periodical, it goes in the issuetitle field. Note that editor and related \n fields refer to the journal while translator and related fields refer to the article.\n\nRequired fields: `author`, `title`, `journaltitle`, `year/date`"
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 8
+ }
+ },
+ "newText": "article"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name.snap
new file mode 100644
index 0000000000..ad571951ed
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name.snap
@@ -0,0 +1,159 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 1)?"
+
+---
+{
+ "isIncomplete": true,
+ "items": [
+ {
+ "label": "preamble",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "preamble"
+ }
+ },
+ {
+ "label": "string",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "string"
+ }
+ },
+ {
+ "label": "comment",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "comment"
+ }
+ },
+ {
+ "label": "article",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An article in a journal, magazine, newspaper, or other periodical which forms a \n self-contained unit with its own title. The title of the periodical is given in the \n journaltitle field. If the issue has its own title in addition to the main title of \n the periodical, it goes in the issuetitle field. Note that editor and related \n fields refer to the journal while translator and related fields refer to the article.\n\nRequired fields: `author`, `title`, `journaltitle`, `year/date`"
+ },
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "article"
+ }
+ },
+ {
+ "label": "book",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "A single-volume book with one or more authors where the authors share credit for\n the work as a whole. This entry type also covers the function of the `@inbook` type\n of traditional BibTeX.\n\nRequired fields: `author`, `title`, `year/date`"
+ },
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "book"
+ }
+ },
+ {
+ "label": "mvbook",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "A multi-volume `@book`. For backwards compatibility, multi-volume books are also\n supported by the entry type `@book`. However, it is advisable to make use of the\n dedicated entry type `@mvbook`.\n\nRequired fields: `author`, `title`, `year/date`"
+ },
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "mvbook"
+ }
+ },
+ {
+ "label": "inbook",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "A part of a book which forms a self-contained unit with its own title. Note that the\n profile of this entry type is different from standard BibTeX.\n\nRequired fields: `author`, `title`, `booktitle`, `year/date`"
+ },
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 1
+ }
+ },
+ "newText": "inbook"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name_before.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name_before.snap
new file mode 100644
index 0000000000..7f8638455c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_empty_name_before.snap
@@ -0,0 +1,9 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 0)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": []
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_incomplete.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_incomplete.snap
new file mode 100644
index 0000000000..2f3236bfc4
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__entry_type_incomplete.snap
@@ -0,0 +1,79 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 1)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "article",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An article in a journal, magazine, newspaper, or other periodical which forms a \n self-contained unit with its own title. The title of the periodical is given in the \n journaltitle field. If the issue has its own title in addition to the main title of \n the periodical, it goes in the issuetitle field. Note that editor and related \n fields refer to the journal while translator and related fields refer to the article.\n\nRequired fields: `author`, `title`, `journaltitle`, `year/date`"
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 4
+ }
+ },
+ "newText": "article"
+ }
+ },
+ {
+ "label": "artwork",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "Works of the visual arts such as paintings, sculpture, and installations."
+ },
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 4
+ }
+ },
+ "newText": "artwork"
+ }
+ },
+ {
+ "label": "mastersthesis",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "Similar to `@thesis` except that the `type` field is optional and defaults to the\n localised term ‘Master’s thesis’. You may still use the `type` field to override that."
+ },
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 4
+ }
+ },
+ "newText": "mastersthesis"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_complete_entry.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_complete_entry.snap
new file mode 100644
index 0000000000..8c6f330647
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_complete_entry.snap
@@ -0,0 +1,171 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 6)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "title",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "The title of the work."
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "title"
+ }
+ },
+ {
+ "label": "titleaddon",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An annex to the `title`, to be printed in a different font."
+ },
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "titleaddon"
+ }
+ },
+ {
+ "label": "booksubtitle",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "The subtitle related to the `booktitle`. If the subtitle field refers to a work which is part of a larger publication, a possible subtitle of the main work is given in this field. See also `subtitle`."
+ },
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "booksubtitle"
+ }
+ },
+ {
+ "label": "booktitle",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "If the `title` field indicates the title of a work which is part of a larger publication, the title of the main work is given in this field. See also `title`."
+ },
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "booktitle"
+ }
+ },
+ {
+ "label": "booktitleaddon",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An annex to the `booktitle`, to be printed in a different font."
+ },
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "booktitleaddon"
+ }
+ },
+ {
+ "label": "eventtitle",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "The title of a conference, a symposium, or some other event in `@proceedings` and `@inproceedings` entries. Note that this field holds the plain title of the event. Things like \"Proceedings of the Fifth XYZ Conference\" go into the `titleaddon` or `booktitleaddon` field, respectively. See also `eventdate` and `venue`."
+ },
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "eventtitle"
+ }
+ },
+ {
+ "label": "eventtitleaddon",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An annex to the `eventtitle` field. Can be used for known event acronyms, for example."
+ },
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 9
+ }
+ },
+ "newText": "eventtitleaddon"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_incomplete_entry.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_incomplete_entry.snap
new file mode 100644
index 0000000000..72e803cd36
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__field_incomplete_entry.snap
@@ -0,0 +1,171 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 6)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "title",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "The title of the work."
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "title"
+ }
+ },
+ {
+ "label": "titleaddon",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An annex to the `title`, to be printed in a different font."
+ },
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "titleaddon"
+ }
+ },
+ {
+ "label": "booksubtitle",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "The subtitle related to the `booktitle`. If the subtitle field refers to a work which is part of a larger publication, a possible subtitle of the main work is given in this field. See also `subtitle`."
+ },
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "booksubtitle"
+ }
+ },
+ {
+ "label": "booktitle",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "If the `title` field indicates the title of a work which is part of a larger publication, the title of the main work is given in this field. See also `title`."
+ },
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "booktitle"
+ }
+ },
+ {
+ "label": "booktitleaddon",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An annex to the `booktitle`, to be printed in a different font."
+ },
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "booktitleaddon"
+ }
+ },
+ {
+ "label": "eventtitle",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "The title of a conference, a symposium, or some other event in `@proceedings` and `@inproceedings` entries. Note that this field holds the plain title of the event. Things like \"Proceedings of the Fifth XYZ Conference\" go into the `titleaddon` or `booktitleaddon` field, respectively. See also `eventdate` and `venue`."
+ },
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "eventtitle"
+ }
+ },
+ {
+ "label": "eventtitleaddon",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "An annex to the `eventtitle` field. Can be used for known event acronyms, for example."
+ },
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 4
+ },
+ "end": {
+ "line": 1,
+ "character": 8
+ }
+ },
+ "newText": "eventtitleaddon"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__bibtex__junk.snap b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__junk.snap
new file mode 100644
index 0000000000..7f8638455c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__bibtex__junk.snap
@@ -0,0 +1,9 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 0)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": []
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__begin_command.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__begin_command.snap
new file mode 100644
index 0000000000..ab5ea7765b
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__begin_command.snap
@@ -0,0 +1,162 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 1)?"
+
+---
+{
+ "isIncomplete": true,
+ "items": [
+ {
+ "label": "begin",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "begin"
+ }
+ },
+ {
+ "label": "b",
+ "kind": 1,
+ "detail": "built-in",
+ "documentation": {
+ "kind": "markdown",
+ "value": "![b](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA6CAIAAAB5+022AAAHLklEQVR4nO2ZX0hTbRzHz9nZ5jb2V8O5mqaOWrrUCJZgLqmkhBDroghSCYr+UDdGXRQFRnQTBUU3o4tjRGgJQZg4Jkgs5pIkM4uZtmzqnJa5s7X/5+w8570477v3cJzbMe19veh7+dvzfM/nnOd3fs/vPIMpioLWknj/NwBbf4Ayac0B8TmOi8Vi4+PjdrvdZrN9/Phxbm4uFAoBAMRicU5Ojl6vr66u3r17d3l5uUwmWwkQnPEti0ajdrv90aNHNpttbm4OhmGVSqVSqSQSCUmSGIbNz89Ho1Eej5ednW00GhsbG+vq6rKzs3+RiFpaAACXy3Xq1CmVSoUgiE6nO336dGdn58jIiNfrXVhYmJ+fd7lcXV1dzc3NSQKxWLx///6+vj6CINKYL6UlgQAAb9++3blzJ4/HU6vVV65c+fTp01LXiEajz58/NxgMyfvUaDT37t0Lh8OrBjQxMVFdXQ3DsMFg6OnpwXE8vREAwG636/X6JJNMJrtx40YkElkFIBzHL1y4gCBIVlZWS0vL0NBQNBrN6EWSZHt7u1wuTzLJ5fIHDx4kEomVAo2Ojm7cuJE2FQgEGo3m/Pnzs7OzGe1CodDhw4eZOarT6YaGhlYK9PjxY4FAwPTl8/ktLS3xeDyjY3d3t1QqTU6EYfjMmTNcJtJKXRg/f/5MEAQzkkgkurq6PB5PxtfWaDRu3ryZ+RZbLBaXy5VxIq3UQNFodHHQ7/f7/f6Mjjk5Odu3b2dGvF7vwMDAioB0Oh2fzy7iCoVCoVBkdEQQpLy8nMf715kgiHfv3gEAfh1o7969JSUlrMvU1dVptVoupgUFBawUnJqaYuXAkkqZWSRJ9vb2VlZWisViBEEUCsXRo0fdbjfHxHz58iUzryEIqq2tDYVCXOam3lx5PF5tbe3WrVuHh4cxDNNqtdu2bWMWmPQSCoXMJYMgCIZhGIa5zF1yt4dhWKPRaDQajhCsuayIQCBgIS4biIsAALFYLBgMBgIBv9//8+fPUCgUi8XoXe8/AiII4sePHy6X68OHDyMjIy6Xa25uDsOwcDiM4zhJkuAfMWdxXK9lAJEk6fV6+/v7rVbr4ODg9PQ03aBBECQUClUqVXFxcX5+vlarzcvL8/l8ZrM5Fost61a5AhEE4XQ629vbu7u7v3z5Eo/H6bhIJNLpdCaTqaamxmAwrF+/XiqVCoVCGIZfv36NoujqA1EUNTk5aTabOzo6PB5PchWkUqnJZGpsbKypqVGr1YtL6Iq0VD3AcfzFixdGoxFBkORgBEF27Njx5MkTv9+fppY4HA5WjTh48CDH/TU1UDweN5vNarWaaSoSiU6ePDkxMQEASG+6ykCJRAJFUVaXLhKJLl26hGEYF9NVBnI4HMnujBaPx2tubvb5fFwcVwjEzsdgMHjnzp2pqSlmUK/XX758WaVSpU/HZenv5wFBrILJBrLb7X19fRTjYw1BkKamJmbPtSr6+vXr/fv3KYq6e/cuM84u58+ePWN1YXl5efX19RwLPy0cxzN2P9++fUNRFEVRVpx9mf7+flZEr9cXFhZyp4EgCMMwrt3PIrGBZmZmWJHi4mKxWLws07GxMRzHVwcoEomwIjKZjPvWSDs4HA7qVw/m2ECs1hOCIAzDOLbDtEZHR9+8ecMK0t+KzAhBECRJZgbatGkTK+J0Orl8bNDCcfzhw4c+n2/Lli3M5xoMBlmLSOfZ4n2QDXTkyBHWoNHR0cWZnlIURVmt1o6OjsLCwrNnzzIzz+v1+nw+5sixsTGCIIqKilK4MDU5OVlVVcUaU1NTMz09nb7CAgAGBgYMBoNIJLp9+7bb7WYehkgkks7OzuTgQCCwb98+BEFaW1tZPmwgAIDNZmOVQQRBjh07loYJx3GLxVJWViYQCE6cOIFhWCKRaG1tZT5sk8nkdDoJggiHw2azWSqVlpWVjY+PZwCiKIokyVevXlVXVzPt+Hz+nj17LBZLIBBg7vaRSGR4ePjixYu5ublSqfTcuXPfv3+nf3K73VVVVclM4vF4JSUlTU1N9fX1SqVy3bp1T58+Xdw4pG4/AAAej+fmzZsGg0EoFCaxlEplbW3ttWvXUBRta2u7fv16Q0PDhg0bsrKyKioqUBRlfnzRi1hZWcnsqCAIgmG4qKiora0t5ZlTujNGkiQ9Ho/NZuvt7X3//v3s7Gw4HCYIAgBA7yQIgiiVytLS0kOHDjU0NBQUFLAqFkVRExMTKIparVb6NCc3N3fXrl3Hjx+vqKhggf6NmwYoKRzHFxYWZmZmvF6v1+sNBAKxWEwsFufn5+v1ep1OJ5fL0xRPkiR9Ph/dvahUqpycnDRdLyeg/1Jr7uD8D1AmrTmg1NkeiUR+uaFJL6FQKJFIlgcEALh161ZPT8/vADpw4MDVq1dTVqAlgehqNjg4+DuASktL0xea1EuWnZ2dn5//O4Ay/kv0pzBm0h+gTFpzQH8Bp4gu0MowthIAAAAASUVORK5CYII=|width=48,height=48)"
+ },
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "b"
+ }
+ },
+ {
+ "label": "backslash",
+ "kind": 1,
+ "detail": "\\, built-in",
+ "documentation": {
+ "kind": "markdown",
+ "value": "![backslash](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAA6CAIAAAAsmq7oAAADD0lEQVR4nO2Y3Uv6UBzGv5stsyhCiUTRytJIDTMkRUEqhmnbVTf+o9sygqjAi4RIVqlJKWWl1FB6oyLt/C68K9tb5+YHncudw4fnczjbcxiBEALcg8RO/IN+ha6srKTT6ZeXF5xQSZJ2d3fPzs5wQjc2Nlqt1vb29m+O2lcoy7IWiyWTyTw+PmKDer3eUCgkiuLp6Sk26NDQEMMwT09PW1tb+ncAfRuFQsHhcEQiEUmSvs+qGT3O6dTUVDgcLhQKoijqC9oDOjAwwLLs29vb5ubm5+enHmrP/Ofn5y6XKxgMNhoNPPoA4HA4YrFYuVw+PDzUEbQ3tL+/n2GYTqcjCEK73dZM/Unh8vJydnbW5/PVajU8+gBgs9ni8XilUsnlclqD/gjt6+tjWZYgCI7jPj4+tFFlLG5ububn52dmZiqVCh59ABgfH19dXa3VatlsVlNQOajBYFhfX6coiuf59/d3DVR5kbu7u1AoNDExUSqV8OgDgMVioWn69vZ2f39ffVAFKEmSyWRycHCQ5/nX11e1VEWXZrMZjUZtNpsoinj0AWB0dHRtbe3+/n5nZwep+2wrQwmCSCQSIyMjgiCorG5Vlwmv1xsIBI6OjkqlEjbo8PBwMplUX92qoARB0DTdre6Hhwc8UADweDyLi4vHx8dqqlsttFvdz8/PmUxGubjUv3wnJyd2uz0cDitWt4arpMvlWlpaKhaL+XxefqUGqMlk6la3IAidTkduqXp9hFC5XJ6cnFxYWKjX63j0AcDpdEajUcXq1gY1Go3d6uY4Tq66NekjhKrVqtvtnpubu7q6wqMPAHa7PR6PV6vVg4ODn9ZohlIUxTCMQnVr1UcIXV9f+3y+6enpi4sLPPoAYLVal5eXZapbD9RgMDAMQ1EUx3G9q1uHPkKo0WgEg0Gn01ksFvHoA8DY2BhN0/V6fW9v7/usTihJkqlUymQy8Tzfo7j06SOEJEmKRCJWqzWXy+HRBwCz2ZxIJCRJ4nkeW1KEUDabNZvNfr8fW1IA8Pv9sVjMaDR+eU6gvx8z/wX0H6vA4+khaPAcAAAAAElFTkSuQmCC|width=48,height=48)"
+ },
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "backslash"
+ }
+ },
+ {
+ "label": "badness",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "badness"
+ }
+ },
+ {
+ "label": "bar",
+ "kind": 1,
+ "detail": " ̄, built-in",
+ "documentation": {
+ "kind": "markdown",
+ "value": "![bar](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAA6CAIAAACvXpfTAAAHHklEQVR4nO2ZX0xSbxjHORxAkH8FEShCpU7DRI3RNHEul1uzrdRqtpazumrzprV1QReuedFFrbY229ja6kJbK7fanEsrK1saWGoFREA0Y0mioAiNA8HhnPO7YDudH3Dg6K/t14Xfu/fhfZ7zed/3Oc/7vgcAwzDaXyP6/w3wL23QkOvvoqFhJLp16xaLxQL/tM6cOZNIJMgeyshCiSAIgiB/dvAoimb5lZRGq9X29vb+8fe/qqqKTidND2Cj3pBqg4ZcGzTk2qAhF2n1oyIURSEI8vv9gUAgFovl5+fLZDKJRMJgrDPsOt0ikYjFYhkdHZ2YmHC73aFQCEEQJpMpk8n2799/+vRptVoNguBaw665FsMwbDKZDAbDixcvVlZWQBDcsWNHVVWVRCIJBoNWq9Xlcsnl8kuXLp04cYLJZGIY9vXr16GhoaWlpfr6+paWFjabTRqdbDvNKI/Ho9frt27dSqPR6HS6SqXq6+tzu92xWAxFURiGPR7PtWvXZDKZWCweGBhIJBIfP37UarXJvUkoFN6/fz9LfKo0CIKYTKampqbk/DMYjPb2dpvNhiBISk8Yhu/duycWi4uLiycnJ7u6ugAAwAd//vx5FEX/E00ikRgeHi4rK0vGZTAYXV1dCwsLZP1jsZher2cwGI2NjYWFhb/TAgCuXr2a5UG5aRAEefjwoVKpxCO2trZ6vd7sXk6ns6SkhE6nEyeGy+WOjY2tnwZF0adPn27fvh2PqFarP3/+nHMMMAx3d3en5Ghpaanb7V4/jdlsrqysxMMJBILBwcEsC0/Uo0eP8vLyiDStra3RaHSdND6f79ChQ/hUAwDQ1dUFQRAVFAzDZmdnxWIxMWmuXLmS3YWUBobhy5cvs1gsPJxUKjUajRRRMAwbGxvjcrm4O5/PHx8fz+5Cuk9NT08bDIZ4PI5bmpqaampqyPqnCMOw9+/fRyIR3FJUVFRWVpbdKzMNBEF9fX0/fvzALRwO5+jRoxwOhyJNLBZLTiRuUavVW7ZsWQ/N69evR0dHibFKSkr27t1LEYVGo/l8PpvN9vsxdLpOpyOuO1WaaDTa398fDAaJxsbGRqlUSp3G4XAsLCzgTYFAoNVqc3ploLFarS9fviRaOBxOc3Pzms4Jb9++jUajeFOpVJaUlKyZJlnulpeXiUa5XL57927qKNFodGpqirjQNTU1IpFozTSrq6vPnj1LuZ9WV1fLZDLqNF6v1263400QBHU6HZPJXDONy+VyOp3/6kGnNzQ0ZDuUpMluty8uLuLNTZs2UZzaVJqZmZnV1VWihcfjUUlAXBiGmUymX79+4RalUrlt27b10ExPTycSCaJFLpcXFxdTp4Eg6N27d8Skqays3Lx583povnz5kmIpLy8nbjc5tbCwQFxrEAT37NlDJWky0Ph8vhSLWq1O2Yqzy2azEYPw+XyNRkPRN5UGgiBik8lkqtVq6igoihqNxlgshlsyVhoURefm5lJeF1rOGwyXy6WYgEmFw+GZmRli0lRXV6cv9NLS0qlTpwKBAHH3oKXPTcqbLBQKJRIJdRqPx+NyufAmCIJ1dXXpSWO3281mc/qFK5UmeTvBJRAIeDwedRqLxeL3+4nu6ZUGw7CpqSkIgnQ6XQ4alUpFbHI4nJwbL654PP78+XPikUipVKZXh0gkMjExkZeXt2/fvhw0DQ0NxIml/lkUwzCj0Tg6Oko0qlSq9ErjdrutVqtCoUgvqqk09fX1crkcb4ZCoZS3jEwOh0Ov13u9XtwCAEBFRUXK1GIYNjk56fP5tFptUVFRDprS0tLm5mb8ZL68vOzxeHKieDyeCxcuzM7OEucVAADiwJKCIGh4eBgAgAMHDmQoY+lH5Tdv3uA7Np1Ov379evYry/z8/LFjx1gsVltbW0dHBx4ZBMG7d++mdH716pVIJNq5c+e3b9/SQ2WgicfjPT09+AzX1dUtLi5m5EBR1GKxtLS0sFisw4cPu93ux48fCwQCfCQGg4HYPxwOd3Z2giB48eLFjN/3M99gfD7f8ePHk/WAxWL19PSkX6OCwWB/f/+uXbvYbPbJkyfn5+cxDAuFQh0dHfhCd3d3wzCc7A/D8J07d/h8vlqtdjqdGZ9Lep+an5/v7OxMFkM+n3/u3LkPHz74/f7l5WWHwzEwMHDw4EEejyeVSnt7e1dWVnDHT58+1dbWJoEUCsXQ0JDf7//+/fvNmzcLCgokEsmDBw/Sv2zkoMEwLBAI3Lhxo6KigslkgiBYUFCg0Wg0Go1CoWCz2SKR6MiRI+Pj47FYjOiFoqjVam1vb8/Pz6fRaCKRSKPRlJeXczgcpVJ5+/btlP5E5fi2hSDI3NzcyMjIkydPHA7Hz58/QRAsLCzU6XRtbW21tbV4lqQoEAiMjIwMDg6azeZwOCwUChsaGs6ePVtbW5vltL/xrwe5NmjI9XfR/ANs1iTDg+2GBQAAAABJRU5ErkJggg==|width=48,height=48)"
+ },
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "bar"
+ }
+ },
+ {
+ "label": "baselineskip",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "baselineskip"
+ }
+ },
+ {
+ "label": "baselinestretch",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 2
+ }
+ },
+ "newText": "baselinestretch"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__citation.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation.snap
new file mode 100644
index 0000000000..1ccf0206c8
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation.snap
@@ -0,0 +1,54 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, tex_uri, 3, 6)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "foo:2019",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "Bar, F. (2019). *Baz Qux*."
+ },
+ "preselect": false,
+ "sortText": "00 foo:2019 @articlefoo:2019 author Foo Bar title Baz Qux year 2019",
+ "filterText": "foo:2019 @articlefoo:2019 author Foo Bar title Baz Qux year 2019",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 6
+ },
+ "end": {
+ "line": 3,
+ "character": 6
+ }
+ },
+ "newText": "foo:2019"
+ }
+ },
+ {
+ "label": "bar:2005",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "01 bar:2005 @articlebar:2005",
+ "filterText": "bar:2005 @articlebar:2005",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 6
+ },
+ "end": {
+ "line": 3,
+ "character": 6
+ }
+ },
+ "newText": "bar:2005"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_after.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_after.snap
new file mode 100644
index 0000000000..156b28dc02
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_after.snap
@@ -0,0 +1,9 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, tex_uri, 3, 7)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": []
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_open_brace.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_open_brace.snap
new file mode 100644
index 0000000000..ba2a1c7ce3
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_open_brace.snap
@@ -0,0 +1,34 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, tex_uri, 3, 9)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "FooBar",
+ "kind": 1,
+ "documentation": {
+ "kind": "markdown",
+ "value": "Bar, F. (2019). *Baz Qux*."
+ },
+ "preselect": false,
+ "sortText": "00 FooBar @articleFooBar author Foo Bar title Baz Qux year 2019",
+ "filterText": "FooBar @articleFooBar author Foo Bar title Baz Qux year 2019",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 6
+ },
+ "end": {
+ "line": 3,
+ "character": 9
+ }
+ },
+ "newText": "FooBar"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__class_command.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__class_command.snap
new file mode 100644
index 0000000000..ff214e764a
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__class_command.snap
@@ -0,0 +1,150 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 2, 5)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "chaptername",
+ "kind": 1,
+ "detail": "book.cls",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "chaptername"
+ }
+ },
+ {
+ "label": "chaptermark",
+ "kind": 1,
+ "detail": "book.cls",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "chaptermark"
+ }
+ },
+ {
+ "label": "chapter",
+ "kind": 1,
+ "detail": "book.cls",
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "chapter"
+ }
+ },
+ {
+ "label": "thechapter",
+ "kind": 1,
+ "detail": "book.cls",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "thechapter"
+ }
+ },
+ {
+ "label": "scshape",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "scshape"
+ }
+ },
+ {
+ "label": "fontchardp",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "fontchardp"
+ }
+ },
+ {
+ "label": "XeTeXcharglyph",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 1
+ },
+ "end": {
+ "line": 2,
+ "character": 5
+ }
+ },
+ "newText": "XeTeXcharglyph"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__class_environment.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__class_environment.snap
new file mode 100644
index 0000000000..c893498077
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__class_environment.snap
@@ -0,0 +1,30 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 4, 13)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "theindex",
+ "kind": 1,
+ "detail": "book.cls",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 7
+ },
+ "end": {
+ "line": 4,
+ "character": 13
+ }
+ },
+ "newText": "theindex"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__class_import.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__class_import.snap
new file mode 100644
index 0000000000..baf1218114
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__class_import.snap
@@ -0,0 +1,171 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 19)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "book",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "LaTeX is a widely-used macro package for TeX, providing many basic document formating commands extended by a wide range of packages. It is a development of Leslie Lamport's LaTeX 2.09, and superseded the older system in June 1994. The basic distribution is catalogued separately, at latex-base; apart from a large set of contributed packages and third-party documentation (elsewhere on the archive), the distribution includes: - a bunch of required packages, which LaTeX authors are \"entitled to assume\" will be present on any system running LaTeX; and - a minimal set of documentation detailing differences from the 'old' version of LaTeX in the areas of user commands, font selection and control, class and package writing, font encodings, configuration options and modification of LaTeX. For downloading details, see the linked catalogue entries above."
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "book"
+ }
+ },
+ {
+ "label": "bookcover",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "This class helps typesetting book covers and dust jackets."
+ },
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "bookcover"
+ }
+ },
+ {
+ "label": "bookest",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "The class extends the standard book class, in the areas of colour scheme management, document layout, headings and footers, front page layout, and other minor items."
+ },
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "bookest"
+ }
+ },
+ {
+ "label": "bbook",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "The bundle provides class files for writing Bangla and Assamese with LaTeX, and Metafont sources for fonts."
+ },
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "bbook"
+ }
+ },
+ {
+ "label": "basque-book",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "The class is derived from the LaTeX book class. The extensions solve grammatical and numeration issues that occur when book-type documents are written in Basque. The class is useful for writing books, PhD and Master Theses, etc., in Basque."
+ },
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "basque-book"
+ }
+ },
+ {
+ "label": "caesar_book",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "The package allows typesetting of texts with notes, figures, citations, captions and tables in the margin. This is common (for example) in science text books."
+ },
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "caesar_book"
+ }
+ },
+ {
+ "label": "tufte-book",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "Provided are two classes inspired, respectively, by handouts and books created by Edward Tufte."
+ },
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 15
+ },
+ "end": {
+ "line": 0,
+ "character": 19
+ }
+ },
+ "newText": "tufte-book"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color.snap
new file mode 100644
index 0000000000..5385f5c646
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color.snap
@@ -0,0 +1,105 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 18)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "gray",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 18
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "gray"
+ }
+ },
+ {
+ "label": "rgb",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 18
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "rgb"
+ }
+ },
+ {
+ "label": "RGB",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 18
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "RGB"
+ }
+ },
+ {
+ "label": "HTML",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 18
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "HTML"
+ }
+ },
+ {
+ "label": "cmyk",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 18
+ },
+ "end": {
+ "line": 1,
+ "character": 18
+ }
+ },
+ "newText": "cmyk"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color_set.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color_set.snap
new file mode 100644
index 0000000000..7e6f4a1de6
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__color_model_define_color_set.snap
@@ -0,0 +1,67 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 2, 17)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "RGB",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 16
+ },
+ "end": {
+ "line": 2,
+ "character": 17
+ }
+ },
+ "newText": "RGB"
+ }
+ },
+ {
+ "label": "rgb",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 16
+ },
+ "end": {
+ "line": 2,
+ "character": 17
+ }
+ },
+ "newText": "rgb"
+ }
+ },
+ {
+ "label": "gray",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 16
+ },
+ "end": {
+ "line": 2,
+ "character": 17
+ }
+ },
+ "newText": "gray"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__color_name.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__color_name.snap
new file mode 100644
index 0000000000..b34b32f5ac
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__color_name.snap
@@ -0,0 +1,143 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 9)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "red",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "red"
+ }
+ },
+ {
+ "label": "RedOrange",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "RedOrange"
+ }
+ },
+ {
+ "label": "Red",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "Red"
+ }
+ },
+ {
+ "label": "RedViolet",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "RedViolet"
+ }
+ },
+ {
+ "label": "OrangeRed",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "OrangeRed"
+ }
+ },
+ {
+ "label": "VioletRed",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "VioletRed"
+ }
+ },
+ {
+ "label": "BrickRed",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 7
+ },
+ "end": {
+ "line": 0,
+ "character": 9
+ }
+ },
+ "newText": "BrickRed"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__empty_document.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__empty_document.snap
new file mode 100644
index 0000000000..7f8638455c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__empty_document.snap
@@ -0,0 +1,9 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 0)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": []
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command.snap
new file mode 100644
index 0000000000..49f65f06ca
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command.snap
@@ -0,0 +1,30 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 0, 1)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "documentclass",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 1
+ },
+ "end": {
+ "line": 0,
+ "character": 14
+ }
+ },
+ "newText": "documentclass"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_environment.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_environment.snap
new file mode 100644
index 0000000000..8d01ea7b8d
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_environment.snap
@@ -0,0 +1,30 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 6, 10)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "document",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 7
+ },
+ "end": {
+ "line": 6,
+ "character": 10
+ }
+ },
+ "newText": "document"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_glyph.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_glyph.snap
new file mode 100644
index 0000000000..293b190176
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__kernel_command_glyph.snap
@@ -0,0 +1,34 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 7, 7)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "varepsilon",
+ "kind": 1,
+ "detail": "ε, built-in",
+ "documentation": {
+ "kind": "markdown",
+ "value": "![varepsilon](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAA6CAIAAACSzPa1AAAHu0lEQVR4nO2ZX0hTXxzA77n37p933rmmzmQxYaZmKlOzNKQQJEyJMqgQKn2Q/gjmQ3+ECLEXIxRJkx4CQYJ6SSoffFGaYEgoTW0G/kPMNd1ya5v7d2/bvef+Hm6YLHV/Muvh93nbzrnnfHZ2zvd87zmA4zjknwT92wJb8r9Z5Py7ZvhONRQIBOx2++Li4vz8/PT0tNFoNJvNbrebpmkMw+Li4vbt25eZmZmbm5uZmZmUlCQQCP6sWSAQMJlMo6OjOp1uYmLCaDSura0FAgEI4a+VMQyTSqVqtbq4uLiysvLw4cMkSW7ZNBctHo9Hp9Ndv359//79IpEoot8DAJDJZGVlZX19fV6vd9P2ozGjKGpgYODs2bNyuRwAEOkwb4QkyZqamrm5OQhhUC+AiyTSchw3NzfX3t7+8uVLh8MRVIphmEgkIghCKpUSBCEWizEMgxD6/X6n02m3271e76//MoqiRUVFjx8/zs3N3fh9BGZ+v7+/v//+/ftTU1PrHeA4rlAoUlNTs7Ozs7KyUlNTlUplXFycRCIRCAQYhnEc5/f73W73ly9fxsbGBgcH9Xq90+nc2C8A4MyZM69evQoehnDw+XyPHj1KTExcbys+Pr6ioqKrq2t8fNxutzMME7IRCKHT6RwYGLhw4ULQ3C8rKwuqHJYZRVGtra0ymYx3SkpKunbt2rt379xu96/zIxxcLteLFy9yc3NRFAUAaDSa/v7+iM1Yln327NmePXsQBBEKhRUVFcPDwzRNRyG0EQjh3NxcU1PT7du3379//+uQhzYzGAxpaWkIghAE0djYaLVaf9NpIyzLsiy7aVEIM5qmr169CgAQiUT37t3zeDw7qLU9IcwMBoNKpUIQpKKiwmaz7Y4TT4gdfXR01Gw2EwRRW1urUCjCjC87wnZmEMLJyUmWZZOTk7Va7W4p/SDEmPGBniRJqVS6Kz4/CWHGxzCfz0fT9K74/GQ7MxRFs7OzMQxbWVmZnZ3dNacfvW9ffOzYMZVK5XK5enp63G73NjWDVtbvm4XIHNPS0qqqqtra2l6/fq3Vauvq6iQSCV/EMIzD4TCZTCaTyWKxrK6u+nw+lmVFIpFIJJLL5SqVKj09Xa1WR5q9/SBkXFlaWiopKeFzvbt375pMpuXl5d7e3itXruTl5SUkJIjFYhQNHnsURSUSSUpKyo0bNywWSxTxLHQWxHHc5ORkXV3d2NgYhmE5OTkQwpmZGYqiUBSVyWSJiYl85kMQBIqiDMO43W6z2by0tORwODAMa2tra2hoiHTIQr8HAAC0Wu2DBw9qamqWlpb0ev36qGi12qqqqry8PKVSKZFIUBTlOA5C6PV6p6enu7u7dTodwzA2my1SrbDMGIYZHh5uaWkxm80oiu7du5emabvdDiE0GAyLi4tSqZRPXwEAEEIIIUVRLpeL32TT09NPnToVhVmIf9Pr9XZ3dz98+NBsNickJFy+fLm6utrr9ep0upGRkYWFBbvdTtM0wzB8lgsAAAAIBAKpVKpSqYqLiy9evJiTk/PrRPwtM5fL1dLS0tXVRdP0kSNHmpubjx8/LhQKEQThOO779+8Oh8Nut7vdbo/HEwgEOI7DMIzXksvl8fHxMpksCqcfbLU0PB5PY2OjWCwWCATnz59fWFiIYn39DpubBQKBjo4OgiBwHL906ZLZbN5lLW4rs6GhoeTkZABAeXm5yWTaZSeeTcxsNltZWRmCIBqNRq/X774TT7AZhLCnp0cikQiFwvb29q2S9F0g2Ozbt2+lpaUIghw6dOivTK91gpf0hw8f9Ho9iqLnzp1TKpVRLvidINhsaGhobW1NLpfzu/hfceIJNtPr9RDC5ORktVr9V4TWCTZbXl5GECQ2NjbKpGrnCDZjWRZBEJ/PFwgE/obPT4LN5HI5giBfv361WCx/qMvZ2dnOzs6FhYXIzA4ePAgAsFqtOp2O+wPXKzab7datWzdv3nzz5k2I9oOiyPPnz2NiYhAEycrKmpmZ2dkQRVFUc3OzSCRSKBRDQ0PbVw42MxqN+fn5CIKgKHr69OnPnz/vlJbX6+3o6JDL5TiONzQ0UBQVmRnLsp2dnfzCxDCspKREp9OFbGV7GIaZnZ2tr68nSRIAcOLECaPRGPKpTXb01dXV8vJyPswCAJRKZW1t7eDgoNVqDefIcx2WZZ1O59jYWFNT04EDB/h0vLi42GAwhPP45jntxMRETU2NwWDgPwIASJLMyMgoKCjIz8/XaDTx8fGxsbESiQTHcT5rZVnW7/fTNO3xeKxW6+LiosFgGB8fn56ettlsEEIcx0tLS1tbW/lFFnKtbG7GcdzIyEh9ff3Hjx+DKuA4HhMTQxAESZIEQQgEAhzHIYQsy9I0TVGU2+32er0URfF5Cv8USZLV1dV37tzhT+PCYqvBhBBOTU1VVlaKxeJw29oMoVBYVFTU29vr8/nCnwlcyDNHh8Px9OnTgoKCSP0AAFKp9OjRo0+ePDGbzVEcgYf1jm6xWN6+fdvX1zc+Pm6xWGia3vTCCwCA4zhJkmq1urCw8OTJk4WFhQqFIrqcJYI7FJ/PZzQaP336NDk5OT8/v7Ky4nK5AoGAQCCIiYlJSEhISUnJyMjIzs7WaDSJiYk4/lsXgZHdO+0m/+6d8P9mkfPvmv0HfL2v3IpRQCcAAAAASUVORK5CYII=|width=48,height=48)"
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 7,
+ "character": 1
+ },
+ "end": {
+ "line": 7,
+ "character": 7
+ }
+ },
+ "newText": "varepsilon"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__label.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__label.snap
new file mode 100644
index 0000000000..efcaa02ce1
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__label.snap
@@ -0,0 +1,137 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 4, 5)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "sec:bar",
+ "kind": 1,
+ "detail": "Section 2 (Bar)",
+ "preselect": false,
+ "sortText": "00 sec:bar Section 2 (Bar)",
+ "filterText": "sec:bar Section 2 (Bar)",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 5
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "newText": "sec:bar"
+ }
+ },
+ {
+ "label": "sec:foo",
+ "kind": 1,
+ "detail": "Section 1 (Foo)",
+ "preselect": false,
+ "sortText": "01 sec:foo Section 1 (Foo)",
+ "filterText": "sec:foo Section 1 (Foo)",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 5
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "newText": "sec:foo"
+ }
+ },
+ {
+ "label": "eq:foo",
+ "kind": 1,
+ "detail": "Equation (1)",
+ "preselect": false,
+ "sortText": "02 eq:foo Equation (1)",
+ "filterText": "eq:foo Equation (1)",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 5
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "newText": "eq:foo"
+ }
+ },
+ {
+ "label": "eq:bar",
+ "kind": 1,
+ "detail": "Equation (2)",
+ "preselect": false,
+ "sortText": "03 eq:bar Equation (2)",
+ "filterText": "eq:bar Equation (2)",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 5
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "newText": "eq:bar"
+ }
+ },
+ {
+ "label": "fig:baz",
+ "kind": 1,
+ "detail": "Figure 1",
+ "documentation": "Baz",
+ "preselect": false,
+ "sortText": "04 fig:baz Figure 1: Baz",
+ "filterText": "fig:baz Figure 1: Baz",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 5
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "newText": "fig:baz"
+ }
+ },
+ {
+ "label": "thm:foo",
+ "kind": 1,
+ "detail": "Lemma 1",
+ "preselect": false,
+ "sortText": "05 thm:foo Lemma 1",
+ "filterText": "thm:foo Lemma 1",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 5
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "newText": "thm:foo"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__package_command.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__package_command.snap
new file mode 100644
index 0000000000..6a260fe387
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__package_command.snap
@@ -0,0 +1,34 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 3, 7)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "varDelta",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "documentation": {
+ "kind": "markdown",
+ "value": "![varDelta](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA4CAIAAAAjEXx0AAAF60lEQVR4nO2ab0gTfxzHb0PvNjfERqXOqWyIjaRCUUzc0FUoJaWooEUQPSiIIaFIiaKGYE96IIlECyrBCltqjSwVI9AHJiJapmu1NGkYkXP/0bndnx4Y8u1st+/Nbf5+4Ovh3efzude+9952dxuHoijk/wN3pwXYsasbSnZ1/TE/P3/69GmxWHz9+nWv18uumQovFovl3LlzXC4XQZC0tLSlpSVW7WFdXa/Xe/fu3d7eXpIkEQQxmUxGo5HVhPDpUhQ1ODjY1ta2vr6+scXlck1OTrKeEh7m5uaOHDlCO3pZWZnb7YYfEibdlZWV8vJyLpfL4XBAXblcbjKZ4OeEIwwej6ejo+Ply5cKheLAgQPgrqWlpS9fvsCPCrkuRVH9/f3t7e0ymaytrS0vLw/cyzq+ITv/f5iZmUlLSxOJRFqtliCIzs7OyMhIUKCkpAQ+vqHV/fXrV3FxMYZhTU1NG07T09P79+8HdVNTU79//w45MIS6bre7oaEBRdHS0lKz2byx0WKxHD16FNQVCATDw8OQM0OlSxBEd3f3nj17Dh8+PDs7u7kdx/ErV66AuhwO5+bNm5BjQ6U7NTUll8v37dun0+lIkgR3dXV1RUREgMZnzpxZW1uDGRsS3Z8/f546dYrH47W2tno8HtreDx8+xMbGgropKSmLi4swk4Ovu7a2du3aNRRFKysrLRbL1gKr1ZqTk0OL79DQEMzwIOsSBNHV1RUTE5ORkWEwGHzVqNVqWnxbWlpomQmH7sTEREpKSlxc3MDAAMPhHz16RPv0LSoqWl1d9Ts/mLo/fvwoKCjg8/m3bt3aGlmQmZmZuLg4UFcmky0sLPg9RNB0V1dXq6urURS9cOGCzWZjLrZarbm5uaBuVFTU69ev/R4lOLoEQTx48CA6Ojo7O3t+fh6mvqqqihbfGzdu+I1vcHTHxsakUqlYLH7z5g3MO4aiqCdPnqAoChqfPHnSb3yDoGsymVQqlUAgaG9v93q9kF2zs7Px8fGgrlQq9XtmtqvrcrnUajWKopcuXXI4HPCNNptNoVCAunw+v7+/n7lrW7o4jms0GqFQqFAoIL+WNiEI4urVq7T4NjY2MmdpW7qjo6NJSUlJSUkjIyMBtHd3d9PiW1hY6HK5GFoC111cXFQqlUKhUKPR4DgewIS5uTlafJOTk41GI0NLgLpOp/Py5csoiqrVaub1YMButyuVSlCXx+PpdDqGlkB0cRzv6OgQCAQqlYrVfSwNgiCqq6uRv6mvr2eIL2tdkiTfvn0rkUhkMtnY2FjArhtotVpafE+cOOF0On3Vs9ZdWFjIycmJjo5++PAhQRDbs6X0en1CQgKom5iY+PnzZ1/17HQdDsfFixcxDKupqYG5gPKL3W7Pz88HdTEMe/78ua96Fs8ZcBy/f//+06dP8/Pza2tr+Xw+fK8vhEJhZmYmuGV9fX18fJzy9YsJ5DKQJDk0NBQfH5+amjo5Obn9dd2kp6cHwzBQ6dixY77iC6trNBqzsrJiYmIeP368/ciCfPr0SSKRgLoSicTXnQiUrs1mO3/+PIZhdXV1kLes8DgcDpVKBepiGNbT0/PPYv/Z9Xq9Go2mt7e3oKCgpqaGx+NB5hISX/HdeGRNh/mlkyT56tWr2NjYgwcPvn//PrjruklfXx8tvnl5eXa7fWulH12DwZCeni4SiZ49ewZ53R0ABoMhMTER1BWLxXq9fmslk67FYqmoqODxeM3NzayecbPF6XQeP34c1EVRVKvVbq30mV2Px3Pnzh2dTldUVFRVVUU7WcElKioqKysLfLDu8XjevXv3j/j+8+WSJPnixYu9e/ceOnTo48ePROjp6+ujvYmVSqXVaqWJRdD1EQRBEL1e39jYaDabExISbt++TftBIRQsLy9Tf3+Tff369du3b+np6X/VbV1as9lcWloaBkVmUBS9d+8ezY2u63a7m5qaaBd1O8XZs2f96HZ2dopEop32/INUKvWjK5fLdzwGG3A4HIlEQtPjUL4u1f6T7P6fIZTs6oaS3/oaUpPRFnIuAAAAAElFTkSuQmCC|width=48,height=48)"
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 1
+ },
+ "end": {
+ "line": 3,
+ "character": 7
+ }
+ },
+ "newText": "varDelta"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__package_environment.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__package_environment.snap
new file mode 100644
index 0000000000..7dbe95a81b
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__package_environment.snap
@@ -0,0 +1,150 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 5, 5)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "alignedat",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "alignedat"
+ }
+ },
+ {
+ "label": "aligned",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "aligned"
+ }
+ },
+ {
+ "label": "alignat",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "alignat"
+ }
+ },
+ {
+ "label": "align",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "align"
+ }
+ },
+ {
+ "label": "align*",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "align*"
+ }
+ },
+ {
+ "label": "alignat*",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "alignat*"
+ }
+ },
+ {
+ "label": "flalign",
+ "kind": 1,
+ "detail": "amsmath.sty",
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 5
+ },
+ "end": {
+ "line": 5,
+ "character": 9
+ }
+ },
+ "newText": "flalign"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__package_import.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__package_import.snap
new file mode 100644
index 0000000000..992ea91692
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__package_import.snap
@@ -0,0 +1,102 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 15)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "amsmath",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "The package provides the principal packages in the AMS-LaTeX distribution. It adapts for use in LaTeX most of the mathematical features found in AMS-TeX; it is highly recommended as an adjunct to serious mathematical typesetting in LaTeX. When amsmath is loaded, AMS-LaTeX packages amsbsy (for bold symbols), amsopn (for operator names) and amstext (for text embedded in mathematics) are also loaded. amsmath is part of the LaTeX required distribution; however, several contributed packages add still further to its appeal; examples are empheq, which provides functions for decorating and highlighting mathematics, and ntheorem, for specifying theorem (and similar) definitions."
+ },
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 12
+ },
+ "end": {
+ "line": 1,
+ "character": 19
+ }
+ },
+ "newText": "amsmath"
+ }
+ },
+ {
+ "label": "lwarp-amsmath",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "This package converts LaTeX to HTML by using LaTeX to process the user's document and generate HTML tags. External utility programs are only used for the final conversion of text and images. Math may be represented by SVG files or MathJax. Hundreds of LaTeX packages are supported, and their load order is automatically verified. Documents may be produced by LaTeX, LuaLaTeX, XeLaTeX, and by several CJK engines, classes, and packages. A texlua script automates compilation, index, glossary, and batch image processing, and also supports latexmk. Configuration is semi-automatic at the first manual compile. Support files are self-generated. Print and HTML versions of each document may coexist. Assistance is provided for HTML import into EPUB conversion software and word processors. Requirements include the commonly-available Poppler utilities, and Perl. Detailed installation instructions are included for each of the major operating systems and TeX distributions. A quick-start tutorial is provided."
+ },
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 12
+ },
+ "end": {
+ "line": 1,
+ "character": 19
+ }
+ },
+ "newText": "lwarp-amsmath"
+ }
+ },
+ {
+ "label": "simurgh-amsmath",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "The package provides an automatic and unified interface for Parsi typesetting in LaTeX, using the LuaTeX engine. The project to produce this system is dedicated to Ferdowsi The Great."
+ },
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 12
+ },
+ "end": {
+ "line": 1,
+ "character": 19
+ }
+ },
+ "newText": "simurgh-amsmath"
+ }
+ },
+ {
+ "label": "onlyamsmath",
+ "kind": 1,
+ "documentation": {
+ "kind": "plaintext",
+ "value": "This package inhibits the usage of plain TeX and (on demand) of standard LaTeX mathematics environments. This is useful for class writers who want to encourage their users to use the environments provided by the amsmath package."
+ },
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 12
+ },
+ "end": {
+ "line": 1,
+ "character": 19
+ }
+ },
+ "newText": "onlyamsmath"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__pgf_library.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__pgf_library.snap
new file mode 100644
index 0000000000..da34563c8d
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__pgf_library.snap
@@ -0,0 +1,143 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 15)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "arrows",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "arrows"
+ }
+ },
+ {
+ "label": "arrows.meta",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "arrows.meta"
+ }
+ },
+ {
+ "label": "arrows.spaced",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "arrows.spaced"
+ }
+ },
+ {
+ "label": "curvilinear",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "curvilinear"
+ }
+ },
+ {
+ "label": "datavisualization.barcharts",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "datavisualization.barcharts"
+ }
+ },
+ {
+ "label": "datavisualization.formats.functions",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "datavisualization.formats.functions"
+ }
+ },
+ {
+ "label": "datavisualization.polar",
+ "kind": 1,
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 15
+ },
+ "end": {
+ "line": 1,
+ "character": 15
+ }
+ },
+ "newText": "datavisualization.polar"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__preselect_environment.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__preselect_environment.snap
new file mode 100644
index 0000000000..791f045476
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__preselect_environment.snap
@@ -0,0 +1,150 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 5)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "document",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": true,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "document"
+ }
+ },
+ {
+ "label": "abstract",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "abstract"
+ }
+ },
+ {
+ "label": "array",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "array"
+ }
+ },
+ {
+ "label": "center",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "center"
+ }
+ },
+ {
+ "label": "csname",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "csname"
+ }
+ },
+ {
+ "label": "description",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "description"
+ }
+ },
+ {
+ "label": "displaymath",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "06",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 5
+ },
+ "end": {
+ "line": 1,
+ "character": 5
+ }
+ },
+ "newText": "displaymath"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__theorem_environment.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__theorem_environment.snap
new file mode 100644
index 0000000000..cc0b336e9f
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__theorem_environment.snap
@@ -0,0 +1,130 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 3, 7)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "figure",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 7
+ },
+ "end": {
+ "line": 3,
+ "character": 8
+ }
+ },
+ "newText": "figure"
+ }
+ },
+ {
+ "label": "filecontents",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 7
+ },
+ "end": {
+ "line": 3,
+ "character": 8
+ }
+ },
+ "newText": "filecontents"
+ }
+ },
+ {
+ "label": "flushleft",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "02",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 7
+ },
+ "end": {
+ "line": 3,
+ "character": 8
+ }
+ },
+ "newText": "flushleft"
+ }
+ },
+ {
+ "label": "flushright",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "03",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 7
+ },
+ "end": {
+ "line": 3,
+ "character": 8
+ }
+ },
+ "newText": "flushright"
+ }
+ },
+ {
+ "label": "foo",
+ "kind": 1,
+ "detail": "user-defined",
+ "preselect": false,
+ "sortText": "04",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 7
+ },
+ "end": {
+ "line": 3,
+ "character": 8
+ }
+ },
+ "newText": "foo"
+ }
+ },
+ {
+ "label": "proof",
+ "kind": 1,
+ "detail": "amsthm.sty",
+ "preselect": false,
+ "sortText": "05",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 7
+ },
+ "end": {
+ "line": 3,
+ "character": 8
+ }
+ },
+ "newText": "proof"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__user_command.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__user_command.snap
new file mode 100644
index 0000000000..f2f2eef4a5
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__user_command.snap
@@ -0,0 +1,30 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 1, 3)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "foobar",
+ "kind": 1,
+ "detail": "user-defined",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 1
+ },
+ "end": {
+ "line": 1,
+ "character": 6
+ }
+ },
+ "newText": "foobar"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__user_environment.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__user_environment.snap
new file mode 100644
index 0000000000..0f85b3fa56
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__user_environment.snap
@@ -0,0 +1,50 @@
+---
+source: tests/integration/completion.rs
+expression: "complete_and_resolve(&server, uri, 4, 7)?"
+
+---
+{
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "foo",
+ "kind": 1,
+ "detail": "user-defined",
+ "preselect": false,
+ "sortText": "00",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 7
+ },
+ "end": {
+ "line": 4,
+ "character": 9
+ }
+ },
+ "newText": "foo"
+ }
+ },
+ {
+ "label": "filecontents",
+ "kind": 1,
+ "detail": "built-in",
+ "preselect": false,
+ "sortText": "01",
+ "textEdit": {
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 7
+ },
+ "end": {
+ "line": 4,
+ "character": 9
+ }
+ },
+ "newText": "filecontents"
+ }
+ }
+ ]
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_flat.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_flat.snap
new file mode 100644
index 0000000000..1f042106a2
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_flat.snap
@@ -0,0 +1,97 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Enumerate",
+ "kind": 10,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 9,
+ "character": 15
+ }
+ }
+ }
+ },
+ {
+ "name": "1",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 4
+ },
+ "end": {
+ "line": 5,
+ "character": 27
+ }
+ }
+ }
+ },
+ {
+ "name": "Item",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 4
+ },
+ "end": {
+ "line": 6,
+ "character": 27
+ }
+ }
+ }
+ },
+ {
+ "name": "Baz",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 7,
+ "character": 4
+ },
+ "end": {
+ "line": 7,
+ "character": 18
+ }
+ }
+ }
+ },
+ {
+ "name": "2",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 4
+ },
+ "end": {
+ "line": 8,
+ "character": 32
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_nested.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_nested.snap
new file mode 100644
index 0000000000..2584b7ef50
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__enumerate_nested.snap
@@ -0,0 +1,141 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Enumerate",
+ "kind": 10,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 9,
+ "character": 15
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 9,
+ "character": 15
+ }
+ },
+ "children": [
+ {
+ "name": "1",
+ "detail": "it:foo",
+ "kind": 22,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 4
+ },
+ "end": {
+ "line": 5,
+ "character": 27
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 5,
+ "character": 9
+ },
+ "end": {
+ "line": 5,
+ "character": 23
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Item",
+ "detail": "it:bar",
+ "kind": 22,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 4
+ },
+ "end": {
+ "line": 6,
+ "character": 27
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 6,
+ "character": 9
+ },
+ "end": {
+ "line": 6,
+ "character": 23
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Baz",
+ "kind": 22,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 7,
+ "character": 4
+ },
+ "end": {
+ "line": 7,
+ "character": 18
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 7,
+ "character": 4
+ },
+ "end": {
+ "line": 7,
+ "character": 18
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "2",
+ "detail": "it:qux",
+ "kind": 22,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 4
+ },
+ "end": {
+ "line": 8,
+ "character": 32
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 8,
+ "character": 14
+ },
+ "end": {
+ "line": 8,
+ "character": 28
+ }
+ },
+ "children": []
+ }
+ ]
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__equation_flat.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__equation_flat.snap
new file mode 100644
index 0000000000..1f4b3bfe4d
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__equation_flat.snap
@@ -0,0 +1,61 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Equation (1)",
+ "kind": 14,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 6,
+ "character": 14
+ }
+ }
+ }
+ },
+ {
+ "name": "Equation",
+ "kind": 14,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 0
+ },
+ "end": {
+ "line": 10,
+ "character": 14
+ }
+ }
+ }
+ },
+ {
+ "name": "Equation",
+ "kind": 14,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 12,
+ "character": 0
+ },
+ "end": {
+ "line": 14,
+ "character": 14
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__equation_nested.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__equation_nested.snap
new file mode 100644
index 0000000000..9ffb191b89
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__equation_nested.snap
@@ -0,0 +1,87 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Equation (1)",
+ "detail": "eq:foo",
+ "kind": 14,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 6,
+ "character": 14
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 4,
+ "character": 16
+ },
+ "end": {
+ "line": 4,
+ "character": 30
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Equation",
+ "detail": "eq:bar",
+ "kind": 14,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 0
+ },
+ "end": {
+ "line": 10,
+ "character": 14
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 8,
+ "character": 16
+ },
+ "end": {
+ "line": 8,
+ "character": 30
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Equation",
+ "kind": 14,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 12,
+ "character": 0
+ },
+ "end": {
+ "line": 14,
+ "character": 14
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 12,
+ "character": 0
+ },
+ "end": {
+ "line": 14,
+ "character": 14
+ }
+ },
+ "children": []
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__float_flat.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__float_flat.snap
new file mode 100644
index 0000000000..c7465ddcc0
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__float_flat.snap
@@ -0,0 +1,61 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Figure 1: Foo",
+ "kind": 6,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 7,
+ "character": 12
+ }
+ }
+ }
+ },
+ {
+ "name": "Figure: Bar",
+ "kind": 6,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 9,
+ "character": 0
+ },
+ "end": {
+ "line": 12,
+ "character": 12
+ }
+ }
+ }
+ },
+ {
+ "name": "Figure: Baz",
+ "kind": 6,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 14,
+ "character": 0
+ },
+ "end": {
+ "line": 17,
+ "character": 12
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__float_nested.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__float_nested.snap
new file mode 100644
index 0000000000..886ffc560c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__float_nested.snap
@@ -0,0 +1,87 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Figure 1: Foo",
+ "detail": "fig:foo",
+ "kind": 6,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 7,
+ "character": 12
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 6,
+ "character": 17
+ },
+ "end": {
+ "line": 6,
+ "character": 32
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Figure: Bar",
+ "detail": "fig:bar",
+ "kind": 6,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 9,
+ "character": 0
+ },
+ "end": {
+ "line": 12,
+ "character": 12
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 11,
+ "character": 17
+ },
+ "end": {
+ "line": 11,
+ "character": 32
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Figure: Baz",
+ "kind": 6,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 14,
+ "character": 0
+ },
+ "end": {
+ "line": 17,
+ "character": 12
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 14,
+ "character": 0
+ },
+ "end": {
+ "line": 17,
+ "character": 12
+ }
+ },
+ "children": []
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__section_flat.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__section_flat.snap
new file mode 100644
index 0000000000..2f7ad319a7
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__section_flat.snap
@@ -0,0 +1,61 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Foo",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 4,
+ "character": 13
+ }
+ }
+ }
+ },
+ {
+ "name": "2 Bar",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 0
+ },
+ "end": {
+ "line": 8,
+ "character": 31
+ }
+ }
+ }
+ },
+ {
+ "name": "Baz",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 0
+ },
+ "end": {
+ "line": 8,
+ "character": 31
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__section_nested.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__section_nested.snap
new file mode 100644
index 0000000000..d5b5eb4b0c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__section_nested.snap
@@ -0,0 +1,88 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Foo",
+ "kind": 2,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 4,
+ "character": 13
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 4,
+ "character": 0
+ },
+ "end": {
+ "line": 4,
+ "character": 13
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "2 Bar",
+ "detail": "sec:bar",
+ "kind": 2,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 0
+ },
+ "end": {
+ "line": 8,
+ "character": 31
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 6,
+ "character": 13
+ },
+ "end": {
+ "line": 6,
+ "character": 28
+ }
+ },
+ "children": [
+ {
+ "name": "Baz",
+ "detail": "sec:baz",
+ "kind": 2,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 0
+ },
+ "end": {
+ "line": 8,
+ "character": 31
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 8,
+ "character": 16
+ },
+ "end": {
+ "line": 8,
+ "character": 31
+ }
+ },
+ "children": []
+ }
+ ]
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_flat.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_flat.snap
new file mode 100644
index 0000000000..8ce3824bea
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_flat.snap
@@ -0,0 +1,79 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Lemma 1 (Foo)",
+ "kind": 13,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 0
+ },
+ "end": {
+ "line": 8,
+ "character": 11
+ }
+ }
+ }
+ },
+ {
+ "name": "Lemma 2",
+ "kind": 13,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 10,
+ "character": 0
+ },
+ "end": {
+ "line": 12,
+ "character": 11
+ }
+ }
+ }
+ },
+ {
+ "name": "Lemma",
+ "kind": 13,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 14,
+ "character": 0
+ },
+ "end": {
+ "line": 16,
+ "character": 11
+ }
+ }
+ }
+ },
+ {
+ "name": "Lemma (Qux)",
+ "kind": 13,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 18,
+ "character": 0
+ },
+ "end": {
+ "line": 20,
+ "character": 11
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_nested.snap b/support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_nested.snap
new file mode 100644
index 0000000000..052f62fec7
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__document_symbol__theorem_nested.snap
@@ -0,0 +1,114 @@
+---
+source: tests/integration/document_symbol.rs
+expression: server.find_document_symbols(uri)?
+
+---
+[
+ {
+ "name": "Lemma 1 (Foo)",
+ "detail": "thm:foo",
+ "kind": 13,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 0
+ },
+ "end": {
+ "line": 8,
+ "character": 11
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 6,
+ "character": 18
+ },
+ "end": {
+ "line": 6,
+ "character": 33
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Lemma 2",
+ "detail": "thm:bar",
+ "kind": 13,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 10,
+ "character": 0
+ },
+ "end": {
+ "line": 12,
+ "character": 11
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 10,
+ "character": 13
+ },
+ "end": {
+ "line": 10,
+ "character": 28
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Lemma",
+ "detail": "thm:baz",
+ "kind": 13,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 14,
+ "character": 0
+ },
+ "end": {
+ "line": 16,
+ "character": 11
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 14,
+ "character": 13
+ },
+ "end": {
+ "line": 14,
+ "character": 28
+ }
+ },
+ "children": []
+ },
+ {
+ "name": "Lemma (Qux)",
+ "kind": 13,
+ "deprecated": false,
+ "range": {
+ "start": {
+ "line": 18,
+ "character": 0
+ },
+ "end": {
+ "line": 20,
+ "character": 11
+ }
+ },
+ "selectionRange": {
+ "start": {
+ "line": 18,
+ "character": 0
+ },
+ "end": {
+ "line": 20,
+ "character": 11
+ }
+ },
+ "children": []
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__hover__empty_bibtex_document.snap b/support/texlab/tests/integration/snapshots/integration__hover__empty_bibtex_document.snap
new file mode 100644
index 0000000000..e064602aa1
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__hover__empty_bibtex_document.snap
@@ -0,0 +1,6 @@
+---
+source: tests/integration/hover.rs
+expression: "server.hover(uri, 0, 0)?"
+
+---
+null
diff --git a/support/texlab/tests/integration/snapshots/integration__hover__empty_labtex_document.snap b/support/texlab/tests/integration/snapshots/integration__hover__empty_labtex_document.snap
new file mode 100644
index 0000000000..e064602aa1
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__hover__empty_labtex_document.snap
@@ -0,0 +1,6 @@
+---
+source: tests/integration/hover.rs
+expression: "server.hover(uri, 0, 0)?"
+
+---
+null
diff --git a/support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file.snap b/support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file.snap
new file mode 100644
index 0000000000..758c89cfac
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file.snap
@@ -0,0 +1,21 @@
+---
+source: tests/integration/hover.rs
+expression: "server.hover(uri, 3, 8)?"
+
+---
+{
+ "contents": {
+ "kind": "plaintext",
+ "value": "Lemma"
+ },
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 5
+ },
+ "end": {
+ "line": 3,
+ "character": 12
+ }
+ }
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file_mumber.snap b/support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file_mumber.snap
new file mode 100644
index 0000000000..43737f72a1
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__hover__label_theorem_child_file_mumber.snap
@@ -0,0 +1,21 @@
+---
+source: tests/integration/hover.rs
+expression: "server.hover(uri, 3, 8)?"
+
+---
+{
+ "contents": {
+ "kind": "plaintext",
+ "value": "Lemma 1 (Foo)"
+ },
+ "range": {
+ "start": {
+ "line": 3,
+ "character": 5
+ },
+ "end": {
+ "line": 3,
+ "character": 12
+ }
+ }
+}
diff --git a/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_bibtex.snap b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_bibtex.snap
new file mode 100644
index 0000000000..bac8d65144
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_bibtex.snap
@@ -0,0 +1,43 @@
+---
+source: tests/integration/workspace_symbol.rs
+expression: "run(\"bibtex\")?"
+
+---
+[
+ {
+ "name": "foo",
+ "kind": 24,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.bib",
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 0
+ },
+ "end": {
+ "line": 0,
+ "character": 14
+ }
+ }
+ }
+ },
+ {
+ "name": "bar",
+ "kind": 15,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.bib",
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 0
+ },
+ "end": {
+ "line": 2,
+ "character": 20
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_figure.snap b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_figure.snap
new file mode 100644
index 0000000000..8842d02f7d
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_figure.snap
@@ -0,0 +1,25 @@
+---
+source: tests/integration/workspace_symbol.rs
+expression: "run(\"figure\")?"
+
+---
+[
+ {
+ "name": "Figure 1: Bar",
+ "kind": 6,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 15,
+ "character": 0
+ },
+ "end": {
+ "line": 19,
+ "character": 12
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_item.snap b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_item.snap
new file mode 100644
index 0000000000..3434eaff9c
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_item.snap
@@ -0,0 +1,61 @@
+---
+source: tests/integration/workspace_symbol.rs
+expression: "run(\"item\")?"
+
+---
+[
+ {
+ "name": "1",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 24,
+ "character": 4
+ },
+ "end": {
+ "line": 24,
+ "character": 28
+ }
+ }
+ }
+ },
+ {
+ "name": "2",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 25,
+ "character": 4
+ },
+ "end": {
+ "line": 25,
+ "character": 28
+ }
+ }
+ }
+ },
+ {
+ "name": "3",
+ "kind": 22,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 26,
+ "character": 4
+ },
+ "end": {
+ "line": 26,
+ "character": 28
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_math.snap b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_math.snap
new file mode 100644
index 0000000000..d2b7550efe
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_math.snap
@@ -0,0 +1,43 @@
+---
+source: tests/integration/workspace_symbol.rs
+expression: "run(\"math\")?"
+
+---
+[
+ {
+ "name": "Equation (1)",
+ "kind": 14,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 9,
+ "character": 0
+ },
+ "end": {
+ "line": 11,
+ "character": 14
+ }
+ }
+ }
+ },
+ {
+ "name": "Lemma 1 (Qux)",
+ "kind": 13,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 33,
+ "character": 0
+ },
+ "end": {
+ "line": 35,
+ "character": 11
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_section.snap b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_section.snap
new file mode 100644
index 0000000000..e221d55dcb
--- /dev/null
+++ b/support/texlab/tests/integration/snapshots/integration__workspace_symbol__filter_type_section.snap
@@ -0,0 +1,79 @@
+---
+source: tests/integration/workspace_symbol.rs
+expression: "run(\"section\")?"
+
+---
+[
+ {
+ "name": "1 Foo",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 7,
+ "character": 0
+ },
+ "end": {
+ "line": 11,
+ "character": 14
+ }
+ }
+ }
+ },
+ {
+ "name": "2 Bar",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 13,
+ "character": 0
+ },
+ "end": {
+ "line": 19,
+ "character": 12
+ }
+ }
+ }
+ },
+ {
+ "name": "3 Baz",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 21,
+ "character": 0
+ },
+ "end": {
+ "line": 27,
+ "character": 15
+ }
+ }
+ }
+ },
+ {
+ "name": "4 Qux",
+ "kind": 2,
+ "deprecated": false,
+ "location": {
+ "uri": "http://www.example.com/main.tex",
+ "range": {
+ "start": {
+ "line": 29,
+ "character": 0
+ },
+ "end": {
+ "line": 35,
+ "character": 11
+ }
+ }
+ }
+ }
+]
diff --git a/support/texlab/tests/integration/workspace_symbol.rs b/support/texlab/tests/integration/workspace_symbol.rs
index 5eb8e1ace7..54a0a8808d 100644
--- a/support/texlab/tests/integration/workspace_symbol.rs
+++ b/support/texlab/tests/integration/workspace_symbol.rs
@@ -1,228 +1,119 @@
-use indoc::indoc;
-use texlab::{
- protocol::{Location, Range, RangeExt, SymbolInformation, WorkspaceSymbolParams},
- test::{TestBed, TestBedBuilder, TestLspClient, PULL_CAPABILITIES},
-};
-
-pub fn verify_symbol_info(
- symbol: &SymbolInformation,
- test_bed: &TestBed,
- relative_path: &str,
- name: &str,
- start_line: u64,
- start_character: u64,
- end_line: u64,
- end_character: u64,
-) {
- assert_eq!(symbol.name, name);
- let range = Range::new_simple(start_line, start_character, end_line, end_character);
- assert_eq!(
- symbol.location,
- Location::new(test_bed.uri(relative_path).into(), range)
- );
-}
+use anyhow::Result;
+use insta::assert_json_snapshot;
+use lsp_types::{ClientCapabilities, SymbolInformation, Url};
+
+use crate::common::ServerTester;
+
+fn run(query: &str) -> Result<Vec<SymbolInformation>> {
+ let server = ServerTester::launch_new_instance()?;
+ server.initialize(ClientCapabilities::default(), None)?;
+ let uri = Url::parse("http://www.example.com/main.tex")?;
+ server.open_memory(
+ uri.clone(),
+ r#"
+ \documentclass{article}
+ \usepackage{caption}
+ \usepackage{amsmath}
+ \usepackage{amsthm}
+
+ \begin{document}
+
+ \section{Foo}\label{sec:foo}
+
+ \begin{equation}\label{eq:foo}
+ Foo
+ \end{equation}
+
+ \section{Bar}\label{sec:bar}
+
+ \begin{figure}
+ Bar
+ \caption{Bar}
+ \label{fig:bar}
+ \end{figure}
+
+ \section{Baz}\label{sec:baz}
+
+ \begin{enumerate}
+ \item\label{itm:foo} Foo
+ \item\label{itm:bar} Bar
+ \item\label{itm:baz} Baz
+ \end{enumerate}
+
+ \section{Qux}\label{sec:qux}
+
+ \newtheorem{lemma}{Lemma}
+
+ \begin{lemma}[Qux]\label{thm:qux}
+ Qux
+ \end{lemma}
+
+ \end{document}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.aux")?,
+ r#"
+ \relax
+ \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Bar\relax }}{1}\protected@file@percent }
+ \providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}}
+ \newlabel{fig:bar}{{1}{1}}
+ \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
+ \newlabel{sec:foo}{{1}{1}}
+ \newlabel{eq:foo}{{1}{1}}
+ \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{1}\protected@file@percent }
+ \newlabel{sec:bar}{{2}{1}}
+ \@writefile{toc}{\contentsline {section}{\numberline {3}Baz}{1}\protected@file@percent }
+ \newlabel{sec:baz}{{3}{1}}
+ \newlabel{itm:foo}{{1}{1}}
+ \newlabel{itm:bar}{{2}{1}}
+ \newlabel{itm:baz}{{3}{1}}
+ \@writefile{toc}{\contentsline {section}{\numberline {4}Qux}{1}\protected@file@percent }
+ \newlabel{sec:qux}{{4}{1}}
+ \newlabel{thm:qux}{{1}{1}}
+ "#,
+ "latex",
+ )?;
+ server.open_memory(
+ Url::parse("http://www.example.com/main.bib")?,
+ r#"
+ @article{foo,}
+
+ @string{bar = "bar"}
+ "#,
+ "bibtex",
+ )?;
-async fn run(query: &str) -> (TestBed, Vec<SymbolInformation>) {
- let mut test_bed = TestBedBuilder::new()
- .file(
- "foo.tex",
- indoc!(
- r#"
- \documentclass{article}
- \usepackage{caption}
- \usepackage{amsmath}
- \usepackage{amsthm}
- %
- \begin{document}
- %
- \section{Foo}\label{sec:foo}
- %
- \begin{equation}\label{eq:foo}
- Foo
- \end{equation}
- %
- \section{Bar}\label{sec:bar}
- %
- \begin{figure}
- Bar
- \caption{Bar}
- \label{fig:bar}
- \end{figure}
- %
- \section{Baz}\label{sec:baz}
- %
- \begin{enumerate}
- \item\label{itm:foo} Foo
- \item\label{itm:bar} Bar
- \item\label{itm:baz} Baz
- \end{enumerate}
- %
- \section{Qux}\label{sec:qux}
- %
- \newtheorem{lemma}{Lemma}
- %
- \begin{lemma}[Qux]\label{thm:qux}
- Qux
- \end{lemma}
- %
- \end{document}
- "#
- ),
- )
- .file(
- "foo.aux",
- indoc!(
- r#"
- \relax
- \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Bar\relax }}{1}\protected@file@percent }
- \providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}}
- \newlabel{fig:bar}{{1}{1}}
- \@writefile{toc}{\contentsline {section}{\numberline {1}Foo}{1}\protected@file@percent }
- \newlabel{sec:foo}{{1}{1}}
- \newlabel{eq:foo}{{1}{1}}
- \@writefile{toc}{\contentsline {section}{\numberline {2}Bar}{1}\protected@file@percent }
- \newlabel{sec:bar}{{2}{1}}
- \@writefile{toc}{\contentsline {section}{\numberline {3}Baz}{1}\protected@file@percent }
- \newlabel{sec:baz}{{3}{1}}
- \newlabel{itm:foo}{{1}{1}}
- \newlabel{itm:bar}{{2}{1}}
- \newlabel{itm:baz}{{3}{1}}
- \@writefile{toc}{\contentsline {section}{\numberline {4}Qux}{1}\protected@file@percent }
- \newlabel{sec:qux}{{4}{1}}
- \newlabel{thm:qux}{{1}{1}}
- "#
- ),
- )
- .file(
- "bar.bib",
- indoc!(
- r#"
- @article{foo,}
- %
- @string{bar = "bar"}
- "#
- ),
- )
- .build()
- .await;
- test_bed.spawn();
- test_bed.initialize(PULL_CAPABILITIES.clone()).await;
- test_bed.open("foo.tex").await;
- test_bed.open("foo.aux").await;
- test_bed.open("bar.bib").await;
-
- let params = WorkspaceSymbolParams {
- query: query.into(),
- ..WorkspaceSymbolParams::default()
- };
- let actual_symbols = test_bed.client.workspace_symbol(params).await.unwrap();
-
- test_bed.shutdown().await;
-
- (test_bed, actual_symbols)
+ server.find_workspace_symbols(query)
}
-#[tokio::test]
-async fn filter_type_section() {
- let (test_bed, actual_symbols) = run("section").await;
- assert_eq!(actual_symbols.len(), 4);
- verify_symbol_info(
- &actual_symbols[0],
- &test_bed,
- "foo.tex",
- "1 Foo",
- 7,
- 0,
- 13,
- 0,
- );
- verify_symbol_info(
- &actual_symbols[1],
- &test_bed,
- "foo.tex",
- "2 Bar",
- 13,
- 0,
- 21,
- 0,
- );
- verify_symbol_info(
- &actual_symbols[2],
- &test_bed,
- "foo.tex",
- "3 Baz",
- 21,
- 0,
- 29,
- 0,
- );
- verify_symbol_info(
- &actual_symbols[3],
- &test_bed,
- "foo.tex",
- "4 Qux",
- 29,
- 0,
- 37,
- 0,
- );
+#[test]
+fn test_filter_type_section() -> Result<()> {
+ assert_json_snapshot!(run("section")?);
+ Ok(())
}
-#[tokio::test]
-async fn filter_type_figure() {
- let (test_bed, actual_symbols) = run("figure").await;
- assert_eq!(actual_symbols.len(), 1);
- verify_symbol_info(
- &actual_symbols[0],
- &test_bed,
- "foo.tex",
- "Figure 1: Bar",
- 15,
- 0,
- 19,
- 12,
- );
+#[test]
+fn test_filter_type_figure() -> Result<()> {
+ assert_json_snapshot!(run("figure")?);
+ Ok(())
}
-#[tokio::test]
-async fn filter_type_item() {
- let (test_bed, actual_symbols) = run("item").await;
- assert_eq!(actual_symbols.len(), 3);
- verify_symbol_info(&actual_symbols[0], &test_bed, "foo.tex", "1", 24, 4, 25, 4);
- verify_symbol_info(&actual_symbols[1], &test_bed, "foo.tex", "2", 25, 4, 26, 4);
- verify_symbol_info(&actual_symbols[2], &test_bed, "foo.tex", "3", 26, 4, 27, 0);
+#[test]
+fn test_filter_type_item() -> Result<()> {
+ assert_json_snapshot!(run("item")?);
+ Ok(())
}
-#[tokio::test]
-async fn filter_type_math() {
- let (test_bed, actual_symbols) = run("math").await;
- assert_eq!(actual_symbols.len(), 2);
- verify_symbol_info(
- &actual_symbols[0],
- &test_bed,
- "foo.tex",
- "Equation (1)",
- 9,
- 0,
- 11,
- 14,
- );
- verify_symbol_info(
- &actual_symbols[1],
- &test_bed,
- "foo.tex",
- "Lemma 1 (Qux)",
- 33,
- 0,
- 35,
- 11,
- );
+#[test]
+fn test_filter_type_math() -> Result<()> {
+ assert_json_snapshot!(run("math")?);
+ Ok(())
}
-#[tokio::test]
-async fn filter_bibtex() {
- let (test_bed, actual_symbols) = run("bibtex").await;
- assert_eq!(actual_symbols.len(), 2);
- verify_symbol_info(&actual_symbols[0], &test_bed, "bar.bib", "foo", 0, 0, 0, 14);
- verify_symbol_info(&actual_symbols[1], &test_bed, "bar.bib", "bar", 2, 0, 2, 20);
+#[test]
+fn test_filter_bibtex() -> Result<()> {
+ assert_json_snapshot!(run("bibtex")?);
+ Ok(())
}
diff --git a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
index b5a632d5fc..7a04340811 100644
--- a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
+++ b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
@@ -17,7 +17,6 @@ $mirrors = {
'https://mirror.bjtu.edu.cn/CTAN/' => 1,
'https://mirrors.aliyun.com/CTAN/' => 1,
'https://mirrors.bfsu.edu.cn/CTAN/' => 1,
- 'https://mirrors.cqu.edu.cn/CTAN/' => 1,
'https://mirrors.dgut.edu.cn/CTAN/' => 1,
'https://mirrors.hit.edu.cn/CTAN/' => 1,
'https://mirrors.nju.edu.cn/CTAN/' => 1,
@@ -51,12 +50,10 @@ $mirrors = {
'https://cran.asia/tex/' => 1,
'https://ftp.harukasan.org/CTAN/' => 1,
'https://ftp.kaist.ac.kr/pub/tex-archive/' => 1,
+ 'https://mirror.kakao.com/CTAN/' => 1,
'https://mirror.navercorp.com/CTAN/' => 1,
'https://mirror.yongbok.net/ctan/' => 1,
},
- 'Philippines' => {
- 'https://mirror.pregi.net/tex-archive/' => 1,
- },
'Singapore' => {
'https://download.nus.edu.sg/mirror/ctan/' => 1,
},
@@ -150,9 +147,6 @@ $mirrors = {
'Serbia' => {
'http://ctan.mirror.ftn.uns.ac.rs/' => 1,
},
- 'Slovenia' => {
- 'https://ctan.ijs.si/tex-archive/' => 1,
- },
'Spain' => {
'https://ctan.javinator9889.com/' => 1,
'https://osl.ugr.es/CTAN/' => 1,
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
index 8c49cc6468..47979751d9 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
@@ -26,11 +26,11 @@ depend container_split_src_files/1
depend frozen/0
depend minrelease/2016
depend release/2021
-depend revision/59300
+depend revision/59310
name 00texlive.image
category TLCore
-revision 59295
+revision 59310
shortdesc TeX Live files only in the source repository
longdesc The files here are not copied by the installer and containers
longdesc are not built for them; they exist only in the source
@@ -828,6 +828,7 @@ runfiles size=13872
tlpkg/tlpsrc/bloques.tlpsrc
tlpkg/tlpsrc/blowup.tlpsrc
tlpkg/tlpsrc/blox.tlpsrc
+ tlpkg/tlpsrc/bmstu-iu8.tlpsrc
tlpkg/tlpsrc/bnumexpr.tlpsrc
tlpkg/tlpsrc/bodegraph.tlpsrc
tlpkg/tlpsrc/bohr.tlpsrc
@@ -4391,7 +4392,7 @@ depend setting_available_architectures:aarch64-linux amd64-freebsd amd64-netbsd
name 00texlive.installer
category TLCore
-revision 59290
+revision 59302
shortdesc TeX Live standalone installer package
longdesc This package defines the files to go into the installer
longdesc archives (install-tl-unx.tar.gz, install-tl.zip) built by the
@@ -34073,16 +34074,16 @@ catalogue-topics class book-pub chinese
name beebe
category Package
-revision 59190
+revision 59302
catalogue biblio
shortdesc A collection of bibliographies
relocated 1
longdesc A collection of BibTeX bibliographies on TeX-related topics
longdesc (including, for example, spell-checking and SGML). Each
longdesc includes a LaTeX wrapper file to typeset the bibliography.
-containersize 878372
-containerchecksum d4a8b266ca8358081c01d9b01170b5aa7040d036790680094e0ac14cc8559113a8109be61d3a6db18a4d5a10caf75c549d2cc18764f61590c293c26558f3f0a6
-runfiles size=2181
+containersize 880688
+containerchecksum 7f8d0894e8d149c827e3b1c5a7eb984c02f66a2d5395e68018587f55b815b4d6c4b1de44d3dbdd6d91b4656953fbac13e0fa8332c91c62bec8d7aaf31befe6b4
+runfiles size=2189
RELOC/bibtex/bib/beebe/epodd.bib
RELOC/bibtex/bib/beebe/font.bib
RELOC/bibtex/bib/beebe/printing-history.bib
@@ -41032,6 +41033,56 @@ catalogue-license lppl1.3
catalogue-topics graphics diagram-block pgf-tikz
catalogue-version 2.51
+name bmstu-iu8
+category Package
+revision 59310
+shortdesc A class for IU8 reports
+relocated 1
+longdesc This package consist of a class file and style files for
+longdesc writing reports at the IU8 department of IU faculty of BMSTU
+longdesc (Bauman Moscow State Technical University).
+containersize 12584
+containerchecksum 8305bda33fea16ba81c9c20906a0dd946fb52dd630d44f08fd36916cb1bc6988990eedd22e145f70690491779282cbebd0fb3b60c8b0a6c09ca22c66a29356db
+doccontainersize 227952
+doccontainerchecksum e93b0b13270f4b6588344d4a496f20fa53b1e4376945e71a11681362ee3dd3db529d5efb18e45f7327bf9ca97eb6b374c51db745ffd9c0294da22d3d1d91c93e
+docfiles size=64
+ RELOC/doc/latex/bmstu-iu8/LICENSE
+ RELOC/doc/latex/bmstu-iu8/README.md details="Readme"
+ RELOC/doc/latex/bmstu-iu8/bmstu.png
+ RELOC/doc/latex/bmstu-iu8/example.pdf details="Example of use" language="ru"
+ RELOC/doc/latex/bmstu-iu8/example.tex
+runfiles size=26
+ RELOC/tex/latex/bmstu-iu8/01-IU8-base.sty
+ RELOC/tex/latex/bmstu-iu8/02-IU8-construction.sty
+ RELOC/tex/latex/bmstu-iu8/03-IU8-numbering.sty
+ RELOC/tex/latex/bmstu-iu8/04-IU8-section-numbering.sty
+ RELOC/tex/latex/bmstu-iu8/05-IU8-figures.sty
+ RELOC/tex/latex/bmstu-iu8/06-IU8-tables.sty
+ RELOC/tex/latex/bmstu-iu8/07-IU8-footnotes.sty
+ RELOC/tex/latex/bmstu-iu8/08-IU8-formulas.sty
+ RELOC/tex/latex/bmstu-iu8/09-IU8-cites.sty
+ RELOC/tex/latex/bmstu-iu8/10-IU8-titlepage.sty
+ RELOC/tex/latex/bmstu-iu8/11-IU8-performers.sty
+ RELOC/tex/latex/bmstu-iu8/12-IU8-abstract.sty
+ RELOC/tex/latex/bmstu-iu8/13-IU8-contents.sty
+ RELOC/tex/latex/bmstu-iu8/14-IU8-terms-and-definitions.sty
+ RELOC/tex/latex/bmstu-iu8/15-IU8-list-of-abbreviations.sty
+ RELOC/tex/latex/bmstu-iu8/16-IU8-references.sty
+ RELOC/tex/latex/bmstu-iu8/17-IU8-appendices.sty
+ RELOC/tex/latex/bmstu-iu8/18-IU8-extra.sty
+ RELOC/tex/latex/bmstu-iu8/19-IU8-counters.sty
+ RELOC/tex/latex/bmstu-iu8/20-IU8-listing.sty
+ RELOC/tex/latex/bmstu-iu8/21-IU8-math.sty
+ RELOC/tex/latex/bmstu-iu8/22-IU8-algorithms.sty
+ RELOC/tex/latex/bmstu-iu8/BMSTU-IU8.cls
+catalogue-contact-bugs https://github.com/CatInCosmicSpace/latex-template/issues
+catalogue-contact-repository https://github.com/CatInCosmicSpace/latex-template
+catalogue-contact-support https://t.me/catincosmicspace
+catalogue-ctan /macros/latex/contrib/bmstu-iu8
+catalogue-license mit
+catalogue-topics class report-like
+catalogue-version 1.0
+
name bnumexpr
category Package
revision 59244
@@ -69447,7 +69498,7 @@ containerchecksum 653143f95761352dc349c66f618b01a77650b20bf8b2cf45137e72b2f05ba3
name collection-publishers
category Collection
-revision 59002
+revision 59310
shortdesc Publisher styles, theses, etc.
relocated 1
depend IEEEconf
@@ -69485,6 +69536,7 @@ depend beamer-FUBerlin
depend beamer-verona
depend beilstein
depend bgteubner
+depend bmstu-iu8
depend br-lex
depend brandeis-dissertation
depend brandeis-problemset
@@ -69692,8 +69744,8 @@ depend xmuthesis
depend yathesis
depend yazd-thesis
depend york-thesis
-containersize 1548
-containerchecksum 431f3c14b442940da7bc1cbc9c50afe2ca72120a90987890b4eb441faf8342b6658b6a8bf176fc6ac4f4d0483fa7d5f2268a6aa5d4b491b03536c1f5031c377f
+containersize 1552
+containerchecksum c91bf8eecc4abc704dc2e9cf666d327908290c2c32f5aa1d336bc482389e09cd3397531256f09b695668b31a1076653a76b8cbfef56a7947333ec02826617521
name collection-texworks
category Collection
@@ -98742,20 +98794,20 @@ catalogue-topics notes editorial
name easybook
category Package
-revision 59278
+revision 59306
shortdesc Typeset Chinese books or notes
relocated 1
longdesc Easybook is a minimalist style template based on the ctexbook
longdesc book document class.
-containersize 13712
-containerchecksum d4b02c5aaba2c7a1fa165f28c8b2adb0b1a14bdd5d7d6e36285ee45bf4b196bcd9a9f77e47b4c563029ed772c977a7382d44fbbfc068d40d436d4b3db6de9a46
-doccontainersize 311580
-doccontainerchecksum 72cc5ba6a296ff00a2b8b45aea75241d4c5add1865b9c7e75c1cc2c0750f7b39dc82c98db6d86d069c31fbdfc3b48766b22831ed49971236a57999daa6e30059
+containersize 13756
+containerchecksum cfbe10b38dfa7a53d4a8d133fb14d73c7ada77445854afcdf58c1bb6dcfa43f1c97f429aed2261a696587a0cafba8fae3b3c5de17cc1f6b9e9fbb27ada2bebf6
+doccontainersize 311684
+doccontainerchecksum dfceeacdf6505c426b2f0ec0dc02fef599c85440519589f118da5182379d8ac4afad1b6b41228db184fe076c20562a1ef46f479ff63b27e6ccfaf7911deae395
docfiles size=78
RELOC/doc/latex/easybook/README.md details="Readme"
RELOC/doc/latex/easybook/easybook.pdf details="Package documentation" language="zh"
srccontainersize 30100
-srccontainerchecksum 98d680dee88f39cda1f0a55809879a056dceb497e5c834c547f7ca336726a7f74bccf25d6432ed0ee75128ef4520cbd480886ade2138740cc6a30c728cd195ed
+srccontainerchecksum 0d11601957411ddc3d5211319b52101189bdf73d5573c53dbdaa6d8b7d5450cdf484953c729de26b5292c9cbdea06a5c836c7c134d47e4309bd8335be0b3a3c9
srcfiles size=32
RELOC/source/latex/easybook/easybook.dtx
RELOC/source/latex/easybook/easybook.ins
@@ -98766,7 +98818,7 @@ catalogue-contact-repository https://gitee.com/texl3/easybook
catalogue-ctan /macros/latex/contrib/easybook
catalogue-license cc-by-4
catalogue-topics book-pub class chinese expl3
-catalogue-version 1.25m
+catalogue-version 1.25n
name easyfig
category Package
@@ -160425,7 +160477,7 @@ catalogue-version 3.33
name kpfonts-otf
category Package
-revision 58435
+revision 59304
shortdesc OTF version of the Kp-fonts
relocated 1
longdesc This bundle provides OpenType versions of the Type1 Kp-fonts
@@ -160439,11 +160491,11 @@ longdesc st), ancient long-s and a long-tailed capital Q are available
longdesc via font features. Math fonts cover all usual symbols including
longdesc AMS'; a full list of available symbols is provided, see the
longdesc 'List of glyphs'.
-containersize 1084240
-containerchecksum 7daa6cf5fcdedce50ad5fac45abe82c69f695d8f42c95bece738ca161b6b494ef4b008a769f3989ac800d9970888e5c205d87ef7c33ba19a56883547f2957c61
-doccontainersize 2057708
-doccontainerchecksum 29affa9fa075b00abc05332a214ed6abb5c0a8e79a07527461b813d335ace02e3e2e04e32abf823d2a327721b69affc4a2a065ba6b1392afa04542ab37cd9efc
-docfiles size=554
+containersize 1080356
+containerchecksum e873a4b92545b4a081545e4afc19549ff70e3fe9344020890f98ce2ae9f140dbc1427b59e040a9e53f74a9a66542580ba3bc8aae1597011880fdc29150eaf2d2
+doccontainersize 2071840
+doccontainerchecksum 71dda5f31fda3a3cdffd60eeb778e0a3a3233e5b9eb699aa2c78bacb1f2585c5c3c42d72de25c9e51f358a80a4b4a60126122675c2658dc5b8d1d67308ade610
+docfiles size=555
RELOC/doc/fonts/kpfonts-otf/Kpfonts-OTF-Doc-English.ltx
RELOC/doc/fonts/kpfonts-otf/Kpfonts-OTF-Doc-English.pdf details="Package documentation (English)" language="en"
RELOC/doc/fonts/kpfonts-otf/Kpfonts-OTF-Doc-French.ltx
@@ -160482,7 +160534,7 @@ catalogue-also kpfonts
catalogue-ctan /fonts/kpfonts-otf
catalogue-license ofl lppl1.3
catalogue-topics font font-body font-serif font-sans font-proportional font-mono font-maths font-otf font-supp
-catalogue-version 0.35
+catalogue-version 0.36
name ksfh_nat
category Package
@@ -183369,7 +183421,7 @@ catalogue-version 0.2.0
name ltximg
category Package
-revision 57521
+revision 59309
shortdesc Extract LaTeX environments into separate image files
longdesc ltximg is a Perl script that automates the process of
longdesc extracting and converting environments provided by TikZ,
@@ -183379,10 +183431,10 @@ longdesc generates a file with only extracted environments and another
longdesc with all extracted environments converted to \includegraphics.
depend ltximg.ARCH
containersize 26344
-containerchecksum 9aa5aacc687d31bc76fd81a2c26cef98fb9328b90c1d97c439f323fe7962184eab2b571431fe208823a6e42fea6c036128414474ca815517421989916a94eeee
-doccontainersize 242252
-doccontainerchecksum 5fbf8faf7bfd95b4f35e755ec1507f155647376be9311b97dd7c2924c9958fb0c42351eb43728018bc95e12cdec1b2b8ef89a7a2245e532dc8a49b4c583f54b9
-docfiles size=112
+containerchecksum cd72810a146e44d8c56306d1b1f16f89429702f4d740985e16116d1ed14d1d998561bd7e16338c3cd52ccfabca28adb35f93282333b8f175b36d7cb112bb672d
+doccontainersize 245504
+doccontainerchecksum 3c5a1fcd05148b2835f0a7ef82e4cf85c61ec041451ad7c1b5238c413a6cd32948cfb9636372e51cca2c8de7e42e08109e624bf0e731464881fd75cc7ac84784
+docfiles size=113
texmf-dist/doc/support/ltximg/README.md details="Readme"
texmf-dist/doc/support/ltximg/ltximg-doc.pdf details="Package documentation"
texmf-dist/doc/support/ltximg/ltximg-doc.tex
@@ -183395,7 +183447,7 @@ catalogue-contact-support https://github.com/pablgonz/ltximg/issues
catalogue-ctan /support/ltximg
catalogue-license gpl3+
catalogue-topics chunks graphics subdocs
-catalogue-version 2.0
+catalogue-version 2.1
name ltximg.aarch64-linux
category Package
@@ -197208,23 +197260,23 @@ catalogue-version 1.02
name mindflow
category Package
-revision 59137
+revision 59307
shortdesc Write your ideas in a clear way
relocated 1
longdesc This package provides an environment that is separated from the
longdesc main text and has its own line numbers, for writing ideas or
longdesc annotations.
-containersize 1880
-containerchecksum 381f5345613e0fc3c23f41f32c3a8958299635c092dfa916c0f2c8374afc03a01c02b0f8e791a99ae15e15782e0e844164e66fd443b452a394595ad258ae711c
-doccontainersize 186516
-doccontainerchecksum 213aaadb7e5f51cf81cc1c7769659f973326f06116a98f38c2b0842d6fb02555f917998a95a9a6a5a1c89748d7ddb891f40f3d77cc0e33b9780f582cffd40656
-docfiles size=50
+containersize 1872
+containerchecksum 724fd53ebee8cf0423e705e9b0c9428975177ff66d19b7d9d555898dc46c1b4da95540b678c1cf203dce5fd59bd3be7d41c4b3cf6c45eb0666d63ee8fad4f531
+doccontainersize 193672
+doccontainerchecksum b85067752f3706edbd6f83953b8240213f46314b38e9c7f623387e3bfdb17cc335432174f9d0fa9b0308b3aa95c54b62f48f5402678ca1590a101f6632b91af5
+docfiles size=52
RELOC/doc/latex/mindflow/LICENSE
RELOC/doc/latex/mindflow/README.md details="Readme"
RELOC/doc/latex/mindflow/mindflow.pdf details="Package documentation"
-srccontainersize 3940
-srccontainerchecksum cab3dd01f25ac6a42c46a8571367d7b9ef29bbe47935d2ac6baf99f0e88740a29d013db5a55d3ce6681772b8e2f189bd693e243e9af148c9eef17a18a20189a8
-srcfiles size=4
+srccontainersize 4484
+srccontainerchecksum 71d5fe2ec3993119f08c0f0be195bec6709edb8e5f1b4fa3f05d9fa0dab96edac9d099e45d159057fa3fc51236999280fd4327eb3a2d015add8def0a7755838a
+srcfiles size=5
RELOC/source/latex/mindflow/mindflow.dtx
RELOC/source/latex/mindflow/mindflow.ins
runfiles size=2
@@ -212117,7 +212169,7 @@ catalogue-version 0.51
name newpx
category Package
-revision 58838
+revision 59303
shortdesc Alternative uses of the PX fonts, with improved metrics
relocated 1
longdesc This package, initially based on pxfonts, provides many fixes
@@ -212128,11 +212180,11 @@ longdesc options. For proper operation, the packages require that the
longdesc packages newtxmath, pxfonts, and TeXGyrePagella be installed
longdesc and their map files enabled.
execute addMap newpx.map
-containersize 1637012
-containerchecksum 0646add23d044178eb3b9727157033c7248e3ad5013b2410b0ee50cbd6a02d4b5378adb9dbe144c21b3515600ed75d8266c4018ddd55bc20d4bcbdfb44c63629
-doccontainersize 452920
-doccontainerchecksum da3c764db5f34c63ac8d6ccb6fc322385f09e41f5a50fce465f6f0792a423aa8ca5976356bdb4ca7252d556369fd073fb463b1109d27ba3f513ada88007986ad
-docfiles size=220
+containersize 2068388
+containerchecksum 161e0763dd9f513132a39e8a7e2f663894655651b87b5d9ba4e8dde60459baf9181778d8d9e0e7b9d42723940e7c82e9b48a556f1444dc440fc77002370b72be
+doccontainersize 455048
+doccontainerchecksum 7736afeff29cfc13361d37f7cf68036ef00d2c2075c0d115496ac7b9164954a119fa6270d5482bf8d5804bebc3e4a4a08684614960ed98f361fe4dba0464bf78
+docfiles size=221
RELOC/doc/fonts/newpx/ChangesInV1.4.txt
RELOC/doc/fonts/newpx/MANIFEST-newpx.txt
RELOC/doc/fonts/newpx/README details="Readme"
@@ -212140,7 +212192,7 @@ docfiles size=220
RELOC/doc/fonts/newpx/newpxdoc.tex
RELOC/doc/fonts/newpx/newpxeg-crop.pdf
RELOC/doc/fonts/newpx/pxfontseg-crop.pdf
-runfiles size=1791
+runfiles size=2200
RELOC/fonts/afm/public/newpx/NewPXBMI.afm
RELOC/fonts/afm/public/newpx/NewPXBMI_gnu.afm
RELOC/fonts/afm/public/newpx/NewPXMI.afm
@@ -212160,8 +212212,10 @@ runfiles size=1791
RELOC/fonts/afm/public/newpx/pxsys.afm
RELOC/fonts/afm/public/newpx/zplb.afm
RELOC/fonts/afm/public/newpx/zplbi.afm
+ RELOC/fonts/afm/public/newpx/zplbsl.afm
RELOC/fonts/afm/public/newpx/zplr.afm
RELOC/fonts/afm/public/newpx/zplri.afm
+ RELOC/fonts/afm/public/newpx/zplrsl.afm
RELOC/fonts/enc/dvips/newpx/npxsups_ly1.enc
RELOC/fonts/enc/dvips/newpx/npxsups_ot1.enc
RELOC/fonts/enc/dvips/newpx/npxsups_t1.enc
@@ -212263,6 +212317,30 @@ runfiles size=1791
RELOC/fonts/tfm/public/newpx/zpl-BoldItalic-tosf-scl-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-BoldItalic-tosf-scl-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-BoldItalic-tosf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-lf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-lf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-lf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-lf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-lf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-lf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-osf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-osf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-osf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-osf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-osf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-osf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tlf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tlf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tlf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tlf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tlf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tlf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tosf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tosf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tosf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tosf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tosf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-BoldSlanted-tosf-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-lf-ly1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-lf-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-lf-sc-ly1.tfm
@@ -212281,9 +212359,6 @@ runfiles size=1791
RELOC/fonts/tfm/public/newpx/zpl-Italic-osf-scl-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-osf-scl-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-osf-t1.tfm
- RELOC/fonts/tfm/public/newpx/zpl-Italic-osf-th-ly1.tfm
- RELOC/fonts/tfm/public/newpx/zpl-Italic-osf-th-ot1.tfm
- RELOC/fonts/tfm/public/newpx/zpl-Italic-osf-th-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-ly1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-sc-ly1.tfm
@@ -212293,9 +212368,6 @@ runfiles size=1791
RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-scl-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-scl-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-t1.tfm
- RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-th-ly1.tfm
- RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-th-ot1.tfm
- RELOC/fonts/tfm/public/newpx/zpl-Italic-tlf-th-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tosf-ly1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tosf-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Italic-tosf-sc-ly1.tfm
@@ -212341,6 +212413,30 @@ runfiles size=1791
RELOC/fonts/tfm/public/newpx/zpl-Regular-tosf-scl-ot1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Regular-tosf-scl-t1.tfm
RELOC/fonts/tfm/public/newpx/zpl-Regular-tosf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-lf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-lf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-lf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-lf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-lf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-lf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-osf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-osf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-osf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-osf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-osf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-osf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tlf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tlf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tlf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tlf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tlf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tlf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tosf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tosf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tosf-sc-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tosf-sc-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tosf-sc-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zpl-Slanted-tosf-t1.tfm
RELOC/fonts/tfm/public/newpx/zplb-x.tfm
RELOC/fonts/tfm/public/newpx/zplbexa.tfm
RELOC/fonts/tfm/public/newpx/zplbexx.tfm
@@ -212372,6 +212468,12 @@ runfiles size=1791
RELOC/fonts/tfm/public/newpx/zplsy.tfm
RELOC/fonts/tfm/public/newpx/zplsyc.tfm
RELOC/fonts/tfm/public/newpx/zplsym.tfm
+ RELOC/fonts/tfm/public/newpx/zplth-Italic-osf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zplth-Italic-osf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zplth-Italic-osf-t1.tfm
+ RELOC/fonts/tfm/public/newpx/zplth-Italic-tlf-ly1.tfm
+ RELOC/fonts/tfm/public/newpx/zplth-Italic-tlf-ot1.tfm
+ RELOC/fonts/tfm/public/newpx/zplth-Italic-tlf-t1.tfm
RELOC/fonts/type1/public/newpx/NewPXBMI.pfb
RELOC/fonts/type1/public/newpx/NewPXBMI_gnu.pfb
RELOC/fonts/type1/public/newpx/NewPXMI.pfb
@@ -212386,8 +212488,10 @@ runfiles size=1791
RELOC/fonts/type1/public/newpx/pxsys.pfb
RELOC/fonts/type1/public/newpx/zplb.pfb
RELOC/fonts/type1/public/newpx/zplbi.pfb
+ RELOC/fonts/type1/public/newpx/zplbsl.pfb
RELOC/fonts/type1/public/newpx/zplr.pfb
RELOC/fonts/type1/public/newpx/zplri.pfb
+ RELOC/fonts/type1/public/newpx/zplrsl.pfb
RELOC/fonts/type1/public/newpx/zplx-bold.pfb
RELOC/fonts/type1/public/newpx/zplx-regular.pfb
RELOC/fonts/vf/public/newpx/zpl-Bold-lf-scl-ly1.vf
@@ -212462,6 +212566,10 @@ runfiles size=1791
RELOC/tex/latex/newpx/ly1zpllf.fd
RELOC/tex/latex/newpx/ly1zplosf.fd
RELOC/tex/latex/newpx/ly1zplsups.fd
+ RELOC/tex/latex/newpx/ly1zplth-lf.fd
+ RELOC/tex/latex/newpx/ly1zplth-osf.fd
+ RELOC/tex/latex/newpx/ly1zplth-tlf.fd
+ RELOC/tex/latex/newpx/ly1zplth-tosf.fd
RELOC/tex/latex/newpx/ly1zpltlf.fd
RELOC/tex/latex/newpx/ly1zpltosf.fd
RELOC/tex/latex/newpx/newpx-subs.tex
@@ -212472,12 +212580,20 @@ runfiles size=1791
RELOC/tex/latex/newpx/ot1zpllf.fd
RELOC/tex/latex/newpx/ot1zplosf.fd
RELOC/tex/latex/newpx/ot1zplsups.fd
+ RELOC/tex/latex/newpx/ot1zplth-lf.fd
+ RELOC/tex/latex/newpx/ot1zplth-osf.fd
+ RELOC/tex/latex/newpx/ot1zplth-tlf.fd
+ RELOC/tex/latex/newpx/ot1zplth-tosf.fd
RELOC/tex/latex/newpx/ot1zpltlf.fd
RELOC/tex/latex/newpx/ot1zpltosf.fd
RELOC/tex/latex/newpx/t1npxtt.fd
RELOC/tex/latex/newpx/t1zpllf.fd
RELOC/tex/latex/newpx/t1zplosf.fd
RELOC/tex/latex/newpx/t1zplsups.fd
+ RELOC/tex/latex/newpx/t1zplth-lf.fd
+ RELOC/tex/latex/newpx/t1zplth-osf.fd
+ RELOC/tex/latex/newpx/t1zplth-tlf.fd
+ RELOC/tex/latex/newpx/t1zplth-tosf.fd
RELOC/tex/latex/newpx/t1zpltlf.fd
RELOC/tex/latex/newpx/t1zpltosf.fd
RELOC/tex/latex/newpx/ts1npxtt.fd
@@ -212495,7 +212611,7 @@ catalogue-also pxfonts
catalogue-ctan /fonts/newpx
catalogue-license lppl
catalogue-topics font font-body font-maths font-serif font-proportional font-type1 font-otf font-supp font-t1enc
-catalogue-version 1.415
+catalogue-version 1.42
name newsletr
category Package
@@ -273810,7 +273926,7 @@ catalogue-version 1.0
name siunitx
category Package
-revision 59292
+revision 59308
shortdesc A comprehensive (SI) units package
relocated 1
longdesc Typesetting values with units requires care to ensure that the
@@ -273835,17 +273951,17 @@ longdesc The package relies on LaTeX 3 support from the l3kernel and
longdesc l3packages bundles.
depend l3kernel
depend l3packages
-containersize 60464
-containerchecksum 48731a1a77147343b875207a2776ab13597297145ac87e4459eb2c8655bbba0dec4a209fbe553ca6c8af126e1bfbb8e7d6e0bf25791cf4a9e650a92e86ab8728
-doccontainersize 1958700
-doccontainerchecksum 5c6740788a326ef6f4cdd75e00b2b441aead27418e5d4ab9d9c703488866c6a10863cc5029340773e243db93d70ad4ccd10be09017c7b768d0e60a29663af8b0
-docfiles size=511
+containersize 60480
+containerchecksum ece31f91adbd9e4b5cf619bd07bf8ba966e8bac1a7df44bac0d3f8900e733bbcc4906123e5f37741c93f0ce44f8e9af9f1672b6d12e38e467754b0549f7ada53
+doccontainersize 1959620
+doccontainerchecksum 3e123d615c185cce591a04ae0cb8da7e95c3c97d34ee577b90ef8ced0bd80db4f312320f81952e052d3f2d154a38d7c71bd43754c26fcf1867e859cb8733f605
+docfiles size=512
RELOC/doc/latex/siunitx/CHANGELOG.md
RELOC/doc/latex/siunitx/README.md details="Readme"
RELOC/doc/latex/siunitx/siunitx-code.pdf details="Code documentation"
RELOC/doc/latex/siunitx/siunitx.pdf details="User manual"
-srccontainersize 102144
-srccontainerchecksum 7cacbda9d18ca5ca9e43eb549d06a7da74d0f58a58b0a36b5eca5710bded2550cce533898eb8b642c624b6c483f52827e963ca558e39b00f2b30cdabc6425bf2
+srccontainersize 102228
+srccontainerchecksum 80337911303e40576978d8f7702de1b1df78efc86f6e53747a95ec5d2febcf5a96805668258361242f2c12e62f13ff8234cc2bfd206cc68f11d3c807c335bfb7
srcfiles size=156
RELOC/source/latex/siunitx/siunitx-abbreviation.dtx
RELOC/source/latex/siunitx/siunitx-angle.dtx
@@ -273865,7 +273981,7 @@ srcfiles size=156
RELOC/source/latex/siunitx/siunitx.dtx
RELOC/source/latex/siunitx/siunitx.ins
RELOC/source/latex/siunitx/siunitx.tex
-runfiles size=142
+runfiles size=141
RELOC/tex/latex/siunitx/siunitx-abbreviations.cfg
RELOC/tex/latex/siunitx/siunitx-binary.cfg
RELOC/tex/latex/siunitx/siunitx-v2.sty
@@ -299498,7 +299614,7 @@ docfiles size=376
name texlive-scripts
category TLCore
-revision 59290
+revision 59302
shortdesc TeX Live infrastructure programs
longdesc Includes install-tl, tl-portable, rungs, etc.; not needed for
longdesc tlmgr to run but still ours. Not included in tlcritical.
@@ -299506,10 +299622,10 @@ depend texlive-scripts.ARCH
depend texlive.infra
execute addMap mathpple.map
postaction shortcut type=menu name="TeX Live command-line" cmd=TEXDIR/tlpkg/installer/tl-cmd.bat
-containersize 107996
-containerchecksum f942700528aa2e76109bc4013bf4601e16cfd7bef28a87da10b3d5b45b980eb84903aedb4ae0e11312fc55e1ee5a62ac9f638a790fb52d37af2944d9716a48ac
-doccontainersize 397364
-doccontainerchecksum 7267e0d85fb10722e89e29dabbf03cbd7226af05f1a6ede16cc592e6c0310a610220edb5fc8845f5c01b283daa5b14876b41dd37d66f559f8cf5701aab2af210
+containersize 107976
+containerchecksum 490b93daa75212e3fd9a68cc4c0bdfad7a22a092499209846e5dad96b22fa5e96ec7e652452667305a8d0f45405fef1a74b84d439ff811221348e44fb76183d6
+doccontainersize 397412
+doccontainerchecksum b287dc9253bb56a0dac70daa11c89c291f7fdc3da35ad16924f964f3cf8e909364d9863edd0f36c91a47982dc4ed86b88628ba94c6cc52c491b75c7e6824c7ce
docfiles size=490
doc.html
texmf-dist/doc/man/man1/fmtutil-sys.1
@@ -309829,17 +309945,17 @@ catalogue-topics chinese-doc
name tlmgrbasics
category Package
-revision 59134
+revision 59305
shortdesc A simplified documentation for tlmgr
relocated 1
longdesc This package provides simplified documentation for tlmgr, the
longdesc TeX Live Manager. It describes the most commonly-used actions
longdesc and options in a convenient format.
containersize 424
-containerchecksum f30ba9672ff64961fb0f8d68fbaf9a74d88693d48f566e5a758de748b7ffbaf4bac2e27a5e0d808f620abb1861524080b5d384d543cbc115dc64be9d5d34014c
-doccontainersize 151392
-doccontainerchecksum d08a0a6bde8956e68eaed86a8a18be9dac1c14d97854142135d322923b0278a3eaabfa089db10d69fdfaa5703885b738c8571fdb11f17a17aaa9c1dddb47049a
-docfiles size=43
+containerchecksum 931d1fbd0de8a137566916e8b54846f06e5678285bf8deac99578af0ecb8c1085db35270489de63f44d0ef23602be673d1c3e16cc21e1ecf85351fc424baf4e8
+doccontainersize 164280
+doccontainerchecksum 02a881bf7cecad793174a5772c10b566fb0dbd1ce295f03d09be965289e43e5fc35febdd3dad6abf793b135c2fd2cb9145a29f74fa4d451c54fcef85e0172695
+docfiles size=46
RELOC/doc/support/tlmgrbasics/README details="Readme"
RELOC/doc/support/tlmgrbasics/tlmgr.pdf details="The document itself"
RELOC/doc/support/tlmgrbasics/tlmgr.tex
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
index cfca8b4187..2d41ecb0ef 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
@@ -1 +1 @@
-4f14ea40c927008d266413297aa7259d texlive.tlpdb
+d3935e95b66f953e93ac6a4e32a90a6f texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
index fb62fe17d8..9e005c2c33 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
@@ -1 +1 @@
-ddc85dabaafc413e8667e773efcec8bf755b7c4e5e66c4d4c9640c5d3b1ceb25e4339414a60ce9141d30354bb1f233a39be8149936b98c16ae552581f08c240c texlive.tlpdb
+3be17532338821190ef4f6b596e8fd12c4a42c84aef9d2b126a981bd38e05190e97e7a692708ca29a7b36a78a74452115f10b1ed1d638eaa6b55a4f7a9c8703e texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
index da067d1e83..fab603243b 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
@@ -1,10 +1,10 @@
-----BEGIN PGP SIGNATURE-----
-iQEcBAEBCgAGBQJgqEfYAAoJEEzhh34ZQ4xwLRMH/io2XENRSOisvczt0GeAy0KS
-E7bh0W4dUY/91pOkfl5ZBZh8BFtPalimuSsRfBMLi3nKDRzbJZQbomMWn9rPlthI
-XN4l3qClSx0J81aMWGFXQeBKxyI5eTtaK6boJumjsxe8s7gfQ4Qe45o6cy16Yx5u
-hgaiZ8JCztSEvEO1oQavbrp7waGBLMihJxyfTOLyYcLzsjMgdJAkgWnu7yPS3dWj
-x3p5/OQYw2nowiHWX2zvzH1B9C8+Z16WcBx3MVgteJy8bXk0frwbGeBz9AI7Zasp
-AjCqVv8iT6zTE+CFG57t4BO5GBx7ea/CfNPZm5tSy40bkmTOZFX35YHn1yNYJFU=
-=HgxW
+iQEcBAEBCgAGBQJgqZmNAAoJEEzhh34ZQ4xwNK8H/1POUifwmKsgxshhKUyeadct
+PaH6pKQycS8bqHTXdsT7UsxHpGfKiUoeYKmVR7UjUR5evZOHcEv2WuEXswa77tbX
+Na8xz3ZA8f8ST47qBE8pwOCmQvcLhGiVyC63hBjhf7dGxG+3TaNoP5Tpy/qB78oN
+Z21XmAetKQvRfmyH+plXIZ36SESiFKfvgnWQ4cyuAESuR8YFv+c4uazf14TUvP8J
+FYt3xCVTT+WaLHrHhudSTpyMHbihraoHxpK72iymQQE90TZMmNw4uJ3tYkNTSOVR
+scJP4KIt28oDp7gNMOi4c69477J8UTXEG2HSVacA3X9QAL1IEDedefoon42haV0=
+=MeQb
-----END PGP SIGNATURE-----
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
index fe8108e19a..62336b09e8 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
Binary files differ
diff --git a/systems/win32/miktex/tm/packages/next/pr.ini b/systems/win32/miktex/tm/packages/next/pr.ini
index d3c827c85b..1a633ffbe3 100644
--- a/systems/win32/miktex/tm/packages/next/pr.ini
+++ b/systems/win32/miktex/tm/packages/next/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1621628055
+date=1621714491
lastupd=miktex-arctrl-bin-2.9 miktex-arctrl-bin-x64-2.9 miktex-asymptote-bin-2.9 miktex-asymptote-bin-x64-2.9 miktex-autosp-bin-2.9 miktex-autosp-bin-x64-2.9 miktex-axohelp-bin-2.9 miktex-axohelp-bin-x64-2.9 miktex-bibarts-bin-2.9 miktex-bibarts-bin-x64-2.9 miktex-bibtex-bin-2.9 miktex-bibtex-bin-x64-2.9 miktex-bibtex8bit-bin-2.9 miktex-bibtex8bit-bin-x64-2.9 miktex-bzip2-bin-2.9 miktex-bzip2-bin-x64-2.9 miktex-cairo-bin-2.9 miktex-cairo-bin-x64-2.9 miktex-chktex-bin-2.9 miktex-chktex-bin-x64-2.9
-lstdigest=d3dd4f05f4dee3d65a8f25afaa6d908b
+lstdigest=9bf5df1d7f78f5a5c9765908724f0119
numpkg=4101
relstate=next
-version=7811
+version=7812
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: uvtbgG3lzm5+Pi3rCfqR3MH6hQCl0E1l8loLrV5Ko4RNHSBRr6CGhpNbrnXB8/9npxdKEQa33Z2cCxGnCODrHMc221KB9W+3LA2C4RMaRe2JEyFi3pYgkpsPYmjLY7A8tazJJr8mm5AkcXktG9dUgBchyBSrZ+ClLDAnuwccxJZfwyRxLGqBaTbUvJiz1Ul9YEP8T1G/Eolok5LaElkepuPsZBxfvJRzSfS0xJEccafEYGwb9XKeFR5nfFUDmw9wTlWAzvEJDgmrkGQ5NCyq+a7tDiK4qngEfzA4Qf2/oeM+wZQGuA/hCousgD3Xj71BjITj/J1Y4OrWcwRRu7mUyg==
+;;;; signature/miktex: awLZjsz2jz7H6lOJFaPWrJ6gEbpIbTWv2YjBHj6rsXHigc4XycjSbVQMjwoZzEfoMOvj7EsEk07EH6hANscAu8y9eA0P3gVyrJ3XOgzMrzvOStvAF6wQEkINFGfpMR8y3SDgLzA7DuiCz1WX3YL/ltrIj9gKT/1dqhJx4ZGAT6edx1MRBNz3Cfmc0V2uqXRs+AgDQMi/nbnRCbEWG7SlWKUKQWRnTlOQsysTEY1KeZjhoFcKC2x2db7qQKqxkbLmNDK5whMBLG37W1oykYFpl6EIj5uH8FC8gU7vcFXdbcCHAgYg6koq+5Rm8qKttUn9RE4L95Y0T9qIrrY6JOXX/g==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/systems/win32/miktex/tm/packages/pr.ini b/systems/win32/miktex/tm/packages/pr.ini
index be3dd490ef..956ee820bf 100644
--- a/systems/win32/miktex/tm/packages/pr.ini
+++ b/systems/win32/miktex/tm/packages/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1621627865
+date=1621714316
lastupd=alterqcm apa7 bxjscls covington easybook hvfloat hvqrurl pgfmath-xfp pm-isomath powerdot projlib siunitx tuda-ci acrotex babel biblatex-gost bnumexpr changes circuitikz codehigh
-lstdigest=7d88ec2353465e120463b644a0d46cec
+lstdigest=e90e3f1b3fde03c2ff23c85fa3ef31bf
numpkg=4101
relstate=stable
-version=7811
+version=7812
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: Tv48cIw9o0wzPE6fFhMirwjo4xBqcXwcizJ6lQQx1awIw3D4QCbK35I43kuuSD/lYsSACj+Easmskbgv/KozwsXe8KFm6LmMYofHQ9/K055jfJlpcBZj7XNUpwT6MjPT+atSH+cTH6VDTtC09NxzWZGTie2gYZlKoI6J8aQOkH2USGvcvbL0FJYedIAjkhrVeizo342yENeEQaD/LryMAQbAPAmPSVoTljpHZrC1+6DOp2OIWt+dGel8+XjAZvn8nlVW07IbNJIZkmXu16qtA2UgkyRI+swTBTpA0819DWKa9a7FmmVeMBeMbuRjWi64F8fgzMPm1i2XrK2+T7NePg==
+;;;; signature/miktex: devopsk4QJ9Cl4rkKwArGrWkAzyhTU4JIzl+bs6kl+iQvcgVtqVixu/WfMhMl8DrXVKXUfohUKh3hrrOgZgh22t+TeZgUtkqidBzxm+egslRgIaylmI8YWwfKAVVHtnQUmO5IhbwifNldBdBTkboazt+7gUZBawzo3cbgz6gpn6Qvp3BcO6Bqu4kZbfb4p3JktWIHoOHl2fb/TNAwZMwl/cF8Z7yCYGdbhqWA7b2DqE550q+bSiB2dHraxVu1karS73tFcNAbmuxt5vJBAb5UzEd7lZcXls1HdNU6edTdJXurvULNvzbyFen11Nk9jpqo3n7/18hKXiEPo/4uTKg7Q==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/timestamp b/timestamp
index 2f5e473c01..954df4b537 100644
--- a/timestamp
+++ b/timestamp
@@ -2,4 +2,4 @@
# The source CTAN of this site's material:
dante.ctan.org
# The year-month-day-hour-minute of this site's material:
-2021-05-22-02-02
+2021-05-23-02-02