unidash 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- unidash-0.2.0/.gitattributes +1 -0
- unidash-0.2.0/.github/FUNDING.yml +1 -0
- unidash-0.2.0/.gitignore +16 -0
- unidash-0.2.0/CHANGELOG.md +42 -0
- unidash-0.2.0/CONTRIBUTING.md +19 -0
- unidash-0.2.0/IMPROVEMENTS-round.md +125 -0
- unidash-0.2.0/LICENSE +21 -0
- unidash-0.2.0/PKG-INFO +223 -0
- unidash-0.2.0/README.md +188 -0
- unidash-0.2.0/pyproject.toml +65 -0
- unidash-0.2.0/requirements-dev.txt +3 -0
- unidash-0.2.0/scripts/check.ps1 +16 -0
- unidash-0.2.0/scripts/fetch_vectors.py +33 -0
- unidash-0.2.0/scripts/release.ps1 +28 -0
- unidash-0.2.0/src/unidash/__init__.py +21 -0
- unidash-0.2.0/src/unidash/__main__.py +7 -0
- unidash-0.2.0/src/unidash/_classes.py +89 -0
- unidash-0.2.0/src/unidash/_cli.py +94 -0
- unidash-0.2.0/src/unidash/_dashes.py +108 -0
- unidash-0.2.0/src/unidash/_fold.py +16 -0
- unidash-0.2.0/src/unidash/_mapping.py +43 -0
- unidash-0.2.0/src/unidash/_tables.py +57 -0
- unidash-0.2.0/src/unidash/py.typed +0 -0
- unidash-0.2.0/tests/test_cli.py +174 -0
- unidash-0.2.0/tests/test_contract.py +40 -0
- unidash-0.2.0/tests/test_dashes.py +132 -0
- unidash-0.2.0/tests/test_docs.py +122 -0
- unidash-0.2.0/tests/test_e2e_wheel.py +96 -0
- unidash-0.2.0/tests/test_fold.py +130 -0
- unidash-0.2.0/tests/test_tools.py +175 -0
- unidash-0.2.0/tests/test_typing.py +75 -0
- unidash-0.2.0/tests/test_unicode_data.py +122 -0
- unidash-0.2.0/tests/vectors/unicode/MANIFEST.txt +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
buy_me_a_coffee: jlianesglrs
|
unidash-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
.venv/
|
|
4
|
+
venv/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.mypy_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.coverage
|
|
12
|
+
htmlcov/
|
|
13
|
+
|
|
14
|
+
# Third-party data, fetched by scripts/fetch_vectors.py (see its MANIFEST.txt)
|
|
15
|
+
tests/vectors/unicode/*
|
|
16
|
+
!tests/vectors/unicode/MANIFEST.txt
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.0]
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `fold_dashes(text, form="ascii")` with three forms: `ascii` (every dash to one `-`, wavy
|
|
14
|
+
dashes to `~`), `tex` (en dash `--`, em dash `---`) and `typographic` (real dashes kept,
|
|
15
|
+
small, vertical and fullwidth forms replaced by their standard counterparts).
|
|
16
|
+
- Every code point with the Unicode 18.0 Dash property is classified: general dashes fold by
|
|
17
|
+
default, script hyphens only with `script_hyphens=True`, and the superscript and subscript
|
|
18
|
+
minus are never folded.
|
|
19
|
+
- Soft hyphens are removed unless `keep_soft_hyphens=True`.
|
|
20
|
+
- `find_dashes` and `DashHit` report line, column and name of each character a fold would
|
|
21
|
+
change; `is_dash`, `DASHES`, `dash_table` and the streaming `iter_fold_dashes`.
|
|
22
|
+
- Command line tool `unidash` (also `python -m unidash`) with `--check` for pre-commit use.
|
|
23
|
+
- Tests against the Unicode data files and the UTS #39 confusables, fetched by
|
|
24
|
+
`scripts/fetch_vectors.py` and pinned by size and SHA-256, plus an installed-wheel test.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- `to_ascii_punct` now folds every general dash (fullwidth, small, vertical, two-em and
|
|
29
|
+
three-em dashes, wave dashes to `~`) and removes soft hyphens.
|
|
30
|
+
- Type errors name the type that was passed.
|
|
31
|
+
- `to_ascii_punct` folds fullwidth punctuation (U+FF01 to U+FF5E, not letters or digits) to
|
|
32
|
+
ASCII, so the Japanese wave dash from CP932 text (U+FF5E) becomes `~`.
|
|
33
|
+
|
|
34
|
+
## [0.1.0]
|
|
35
|
+
|
|
36
|
+
- First release.
|
|
37
|
+
- `to_ascii_punct(text)` folds Unicode punctuation to ASCII: curly quotes to `'` and `"`,
|
|
38
|
+
en and em dashes and the minus sign to `-`, the ellipsis to `...`, non-breaking and
|
|
39
|
+
other spaces to a normal space, and bullets to `*`.
|
|
40
|
+
- Letters, including accented ones, pass through untouched, unlike `unidecode` and
|
|
41
|
+
`anyascii`, which transliterate every character.
|
|
42
|
+
- Zero runtime dependencies, with the mapping vendored in.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for taking the time. This project keeps a small, predictable shape.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pip install -r requirements-dev.txt
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Before you open a pull request
|
|
12
|
+
|
|
13
|
+
- Keep public API in `src/unidash/__init__.py`; internals live in `_`-prefixed modules.
|
|
14
|
+
- Add a test for the behaviour you change. Tests inject time, disk and network; they
|
|
15
|
+
never touch the real thing.
|
|
16
|
+
- Run `scripts/check.ps1` (format, lint, types, tests) and make sure it passes.
|
|
17
|
+
- One logical change per commit, imperative subject line.
|
|
18
|
+
|
|
19
|
+
Open an issue first if the change is large or shifts the public API.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# unidash improvement round
|
|
2
|
+
|
|
3
|
+
Progress:
|
|
4
|
+
- [x] Brainstorm ranked improvements (this file)
|
|
5
|
+
- [x] Dash classification from the Unicode data: general dashes, script hyphens, kept marks
|
|
6
|
+
- [x] `fold_dashes` with the `ascii`, `tex` and `typographic` forms and soft hyphen control
|
|
7
|
+
- [x] `to_ascii_punct` covers every general dash and drops soft hyphens
|
|
8
|
+
- [x] `find_dashes`, `is_dash`, `DASHES`, `dash_table`, streaming `iter_fold_dashes`
|
|
9
|
+
- [x] Command line tool (`unidash`, `python -m unidash`) with `--check`
|
|
10
|
+
- [x] Contracts: UCD and UTS #39 data, interpreter scan, typing, README, wheel e2e
|
|
11
|
+
- [x] Mutation run (guards removed one at a time, each must fail the suite)
|
|
12
|
+
- [x] Docs: README, CHANGELOG, docstrings, packaging metadata
|
|
13
|
+
- [x] Gates: ruff format, ruff check, mypy --strict, pytest
|
|
14
|
+
- [x] Independent review findings fixed with regression tests
|
|
15
|
+
- [x] Pull request opened (#2), guard clean
|
|
16
|
+
|
|
17
|
+
## Starting point
|
|
18
|
+
|
|
19
|
+
`0.1.0` (not on PyPI) ships one function, `to_ascii_punct`, which folds a hand-picked set of
|
|
20
|
+
quotes, seven dashes, bullets, spaces and the ellipsis. Read as a user who cleans text pasted
|
|
21
|
+
from word processors, PDFs, CJK input methods and web pages:
|
|
22
|
+
|
|
23
|
+
- Only U+2010..U+2015 and U+2212 fold. The fullwidth hyphen-minus from a Japanese keyboard,
|
|
24
|
+
the small and vertical presentation forms, the two-em and three-em dashes and the wave dash
|
|
25
|
+
pass through, so "ASCII punctuation" output still holds non-ASCII dashes.
|
|
26
|
+
- The soft hyphen (U+00AD) is kept. It is invisible, breaks search and diffing, and is the most
|
|
27
|
+
common stray character in text copied from PDFs and hyphenating renderers.
|
|
28
|
+
- There is no choice of target. Everything becomes one `-`, which loses the en and em dash
|
|
29
|
+
distinction that Markdown and TeX users keep as `--` and `---`, and there is no way to only
|
|
30
|
+
tidy lookalike forms while keeping real typographic dashes.
|
|
31
|
+
- Nothing says which characters were chosen or why; nothing is checked against the Unicode
|
|
32
|
+
data, so the next Unicode version silently adds dashes the table never heard of.
|
|
33
|
+
- No way to find dashes (a lint or a pre-commit check), no streaming, no command line tool.
|
|
34
|
+
- Packaging: README example is not executed, no Python classifiers, no wheel test.
|
|
35
|
+
|
|
36
|
+
## Sources (fetched 2026-10-13)
|
|
37
|
+
|
|
38
|
+
- UnicodeData.txt 18.0.0, https://www.unicode.org/Public/18.0.0/ucd/UnicodeData.txt: 27 code
|
|
39
|
+
points have General_Category=Pd (U+002D, U+058A, U+05BE, U+1400, U+1806, U+2010..U+2015,
|
|
40
|
+
U+2E17, U+2E1A, U+2E3A, U+2E3B, U+2E40, U+2E5D, U+301C, U+3030, U+30A0, U+FE31, U+FE32,
|
|
41
|
+
U+FE58, U+FE63, U+FF0D, U+10D6E, U+10EAD).
|
|
42
|
+
- PropList.txt 18.0.0, https://www.unicode.org/Public/18.0.0/ucd/PropList.txt: the Dash
|
|
43
|
+
property is every Pd code point plus U+2053 SWUNG DASH (Po) and three math signs, U+207B,
|
|
44
|
+
U+208B and U+2212 (Sm).
|
|
45
|
+
- confusables.txt 18.0.0 (UTS #39), https://www.unicode.org/Public/18.0.0/security/confusables.txt:
|
|
46
|
+
maps to U+002D the hyphen, non-breaking hyphen, figure dash, en dash, minus sign, small em
|
|
47
|
+
dash and small hyphen-minus, and also non-dashes (letters in Coptic, Buhid and Myanmar, a
|
|
48
|
+
modifier letter, the Arabic full stop, the hyphen bullet, an emoji, a Roman weight sign).
|
|
49
|
+
The em dash, horizontal bar and fullwidth hyphen-minus map to U+30FC instead; the wave dash
|
|
50
|
+
and swung dash to `~`; the double hyphens to `=`.
|
|
51
|
+
- The three files are third-party and not committed: `scripts/fetch_vectors.py` fetches them
|
|
52
|
+
into a gitignored folder checked against a tracked MANIFEST; the tests that read them skip
|
|
53
|
+
when the folder is absent. The running interpreter's `unicodedata` gives a second, always-on
|
|
54
|
+
check for General_Category and NFKC.
|
|
55
|
+
|
|
56
|
+
## Ranked improvements
|
|
57
|
+
|
|
58
|
+
1. **Every dash is classified, on purpose.** Three tables built from code points, each with a
|
|
59
|
+
reason: general dashes (fold by default), script hyphens (Armenian, Hebrew maqaf, Canadian
|
|
60
|
+
syllabics, Mongolian, katakana double hyphen, Garay, Yezidi: they belong to a script, like
|
|
61
|
+
letters, so they fold only on request) and kept marks (superscript and subscript minus,
|
|
62
|
+
which sit next to superscript digits that stay). A contract checks that every Pd and Dash
|
|
63
|
+
code point in the fetched data lands in exactly one table, and every UTS #39 confusable of
|
|
64
|
+
`-` is either folded or excluded for a stated reason (letter, emoji, bullet, sentence stop).
|
|
65
|
+
2. **`fold_dashes(text, form=...)`.** `ascii` (default): every general dash becomes `-`, the
|
|
66
|
+
wave and swung dashes become `~`. `tex`: en dash `--`, em dash and horizontal bar `---`,
|
|
67
|
+
two-em and three-em dashes six and nine hyphens, the rest as `ascii`. `typographic`: real
|
|
68
|
+
dashes stay; only compatibility forms (small, vertical, fullwidth) become their NFKC
|
|
69
|
+
counterparts. `script_hyphens=True` folds the script hyphens too.
|
|
70
|
+
3. **Soft and non-breaking hyphens.** The soft hyphen is dropped by default (it is a line
|
|
71
|
+
break hint, not a character), `keep_soft_hyphens=True` keeps it. The non-breaking hyphen
|
|
72
|
+
folds to `-` in the ASCII forms and stays in `typographic`, where it carries meaning.
|
|
73
|
+
4. **Numbers and ranges preserved.** A minus sign is always a single `-` in the ASCII forms, so
|
|
74
|
+
`-5` stays a negative number; the TeX form never touches characters that are already ASCII,
|
|
75
|
+
so `1-2` and `--` written by hand come out unchanged.
|
|
76
|
+
5. **`to_ascii_punct` follows suit.** It folds every general dash and drops soft hyphens, so
|
|
77
|
+
its output is ASCII for every dash the Unicode data knows.
|
|
78
|
+
6. **Find, test and build.** `find_dashes(text)` yields position, character and Unicode name
|
|
79
|
+
for each non-ASCII dash (for linting); `is_dash(char)`; `DASHES` is the Dash property as a
|
|
80
|
+
frozenset; `dash_table(...)` returns the `str.translate` table for callers with their own
|
|
81
|
+
pipeline.
|
|
82
|
+
7. **Streaming.** `iter_fold_dashes(chunks, ...)` folds an iterable of strings lazily. The fold
|
|
83
|
+
is per code point, so a chunked result equals the whole-text result (property test).
|
|
84
|
+
8. **Command line tool.** `unidash [FILE...]` writes folded text to stdout (`-` is stdin),
|
|
85
|
+
`--form`, `--script-hyphens`, `--keep-soft-hyphens`, `--punct` for the full punctuation fold,
|
|
86
|
+
and `--check` lists `file:line:col: U+2014 EM DASH` and exits 1 (pre-commit style). Exit 2
|
|
87
|
+
on unreadable or non UTF-8 input.
|
|
88
|
+
9. **Contracts that bite.** UCD and UTS #39 data checks, an interpreter scan, chunking
|
|
89
|
+
properties, a mypy snippet over the typed API, executed README examples, an installed-wheel
|
|
90
|
+
e2e and a mutation run.
|
|
91
|
+
10. **Docs and packaging.** README with runnable examples and the full classification, CHANGELOG
|
|
92
|
+
0.2.0, classifiers and keywords.
|
|
93
|
+
|
|
94
|
+
Left out on purpose: turning ASCII hyphens into typographic dashes (the opposite direction,
|
|
95
|
+
`smartypants` owns it), context rules such as "en dash between digits" (guesswork that breaks
|
|
96
|
+
code and identifiers), in-place file rewriting (shell redirection and editors already do this
|
|
97
|
+
safely), and folding letters that look like hyphens (the library never touches letters).
|
|
98
|
+
|
|
99
|
+
## Verification
|
|
100
|
+
|
|
101
|
+
- Gates: `ruff format --check .`, `ruff check .`, `mypy --strict src` (also `src tests`) and
|
|
102
|
+
`pytest` exit 0 on Windows with Python 3.13 (126 passed, 2 skipped: the wheel e2e and the
|
|
103
|
+
POSIX file name test). On the second machine with Python 3.14 and `UNIDASH_E2E=1` the suite
|
|
104
|
+
passes (127 passed, 1 skipped: the POSIX test): it builds the wheel and the sdist, checks
|
|
105
|
+
that no third-party data or tests ship in them, installs the wheel in a fresh venv,
|
|
106
|
+
drives the API from an empty folder, and runs the installed `unidash` script and
|
|
107
|
+
`python -m unidash`.
|
|
108
|
+
- Unicode data: the classes equal the Dash property of PropList.txt 18.0.0 exactly, cover all
|
|
109
|
+
27 Pd code points of UnicodeData.txt 18.0.0, and the stored names match it. Every UTS #39
|
|
110
|
+
confusable of `-` either folds to `-` or is a letter or one of five listed non-dashes. The
|
|
111
|
+
running interpreter's Pd set and NFKC mappings are checked on every run, data or not.
|
|
112
|
+
- Mutations: 53 mutants (classes, tables, option checks, TeX widths, compatibility targets,
|
|
113
|
+
soft and script hyphen switches, table copying, position counting, name lookup, streaming
|
|
114
|
+
type checks, the punctuation and fullwidth tables, LF, CR and CRLF line counting, the byte
|
|
115
|
+
order mark column, the broken pipe exit, and every command line flag, label, encoding and
|
|
116
|
+
exit code rule), applied one at a time with the bytecode cache disabled and purged before each
|
|
117
|
+
run: all killed. One first draft of an output-encoding mutant was equivalent and was
|
|
118
|
+
replaced. The baseline was green before and after.
|
|
119
|
+
- Independent review: 9 findings, all addressed with regression tests: lone CR now ends a
|
|
120
|
+
line for positions; a leading byte order mark takes no column; a closed output pipe stops
|
|
121
|
+
quietly; undecodable POSIX file names are printed as given; the typographic minus claim and
|
|
122
|
+
the scope of minus-like characters are stated exactly in the README, with the reason double
|
|
123
|
+
hyphens become `-`; `to_ascii_punct` folds fullwidth punctuation, including the CP932 wave
|
|
124
|
+
dash; every README table cell is checked against the fold; the sdist is checked for data
|
|
125
|
+
files; `is_dash` raises `ValueError` for a string of the wrong length.
|
unidash-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Javier Lianes
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
unidash-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: unidash
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Fold Unicode dashes and punctuation to plain ASCII while leaving letters untouched
|
|
5
|
+
Project-URL: Homepage, https://lianes8studio.com
|
|
6
|
+
Project-URL: Repository, https://github.com/JaviLianes8/unidash
|
|
7
|
+
Project-URL: Issues, https://github.com/JaviLianes8/unidash/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/JaviLianes8/unidash/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: LinkedIn, https://www.linkedin.com/in/jlianes/
|
|
10
|
+
Project-URL: Funding, https://buymeacoffee.com/jlianesglrs
|
|
11
|
+
Author-email: Javier Lianes <javier@lianes8studio.com>
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: ascii,dash,em-dash,en-dash,hyphen,minus,normalize,punctuation,quotes,soft-hyphen,text,unicode
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Text Processing :: Filters
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build; extra == 'dev'
|
|
30
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
33
|
+
Requires-Dist: twine; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# unidash
|
|
37
|
+
|
|
38
|
+
Fold Unicode dashes and punctuation to plain ASCII while leaving letters untouched.
|
|
39
|
+
|
|
40
|
+
Text pasted from word processors, PDFs, CJK input methods and web pages is full of
|
|
41
|
+
characters that look like `-` but are not: en and em dashes, the minus sign, the
|
|
42
|
+
non-breaking hyphen, fullwidth and small forms, and the invisible soft hyphen. They break
|
|
43
|
+
search, diffs, command lines and parsers. `unidash` knows every character with the Unicode
|
|
44
|
+
Dash property, plus the soft hyphen, and folds them the way you choose.
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
pip install unidash
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Python 3.10 or newer, no dependencies.
|
|
53
|
+
|
|
54
|
+
## Dashes
|
|
55
|
+
|
|
56
|
+
`fold_dashes(text, form="ascii")` has three forms. `ascii` turns every dash into one `-`
|
|
57
|
+
(wavy dashes into `~`). `tex` keeps the en and em dash apart the way TeX and Markdown do, as
|
|
58
|
+
`--` and `---`. `typographic` keeps the real dashes and only replaces the small, vertical and
|
|
59
|
+
fullwidth compatibility forms with their standard counterparts.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from unidash import fold_dashes
|
|
63
|
+
|
|
64
|
+
text = "Pages 10\u201320 \u2014 see \u22125\uff0d6"
|
|
65
|
+
print(fold_dashes(text))
|
|
66
|
+
print(fold_dashes(text, "tex"))
|
|
67
|
+
print(ascii(fold_dashes("a\ufe58b\uff0dc", "typographic")))
|
|
68
|
+
# Pages 10-20 - see -5-6
|
|
69
|
+
# Pages 10--20 --- see -5-6
|
|
70
|
+
# 'a\u2014b-c'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
A minus sign is always a single `-` in the `ascii` and `tex` forms (`typographic` keeps
|
|
74
|
+
U+2212), so negative numbers stay negative, and characters that are already ASCII are never
|
|
75
|
+
touched: `1-2` and a hand-written `--` come out as they went in.
|
|
76
|
+
|
|
77
|
+
## Soft hyphens, non-breaking hyphens and script hyphens
|
|
78
|
+
|
|
79
|
+
The soft hyphen (U+00AD) is a hint for where a word may break, not a character, so it is
|
|
80
|
+
removed unless you pass `keep_soft_hyphens=True`. The non-breaking hyphen (U+2011) becomes
|
|
81
|
+
`-` in the ASCII forms and stays in `typographic`, where its promise matters.
|
|
82
|
+
|
|
83
|
+
Hyphens that belong to one script (Armenian, the Hebrew maqaf, Canadian syllabics,
|
|
84
|
+
Mongolian, the katakana double hyphen, Garay and Yezidi) are left alone, like that script's
|
|
85
|
+
letters, unless you pass `script_hyphens=True`.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from unidash import fold_dashes
|
|
89
|
+
|
|
90
|
+
print(fold_dashes("co\u00adop\u00aderate"))
|
|
91
|
+
print(ascii(fold_dashes("co\u00adop", keep_soft_hyphens=True)))
|
|
92
|
+
print(ascii(fold_dashes("\u05e2\u05be\u05d1")))
|
|
93
|
+
print(ascii(fold_dashes("\u05e2\u05be\u05d1", script_hyphens=True)))
|
|
94
|
+
# cooperate
|
|
95
|
+
# 'co\xadop'
|
|
96
|
+
# '\u05e2\u05be\u05d1'
|
|
97
|
+
# '\u05e2-\u05d1'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Finding dashes
|
|
101
|
+
|
|
102
|
+
`find_dashes` yields a `DashHit` (offset, line, column, character and Unicode name) for
|
|
103
|
+
every character `fold_dashes` would change with the same options, which makes a lint or a
|
|
104
|
+
pre-commit check a one-liner. Lines end at LF, CR or CRLF, columns count code points from 1,
|
|
105
|
+
and a byte order mark at the start of the text takes no column. `is_dash(char)` tells whether a character has the Unicode Dash
|
|
106
|
+
property and `DASHES` is that set. `dash_table(...)` returns the `str.translate` table, and
|
|
107
|
+
`iter_fold_dashes(chunks, ...)` folds an iterable of strings lazily, for large inputs.
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from unidash import find_dashes, is_dash, iter_fold_dashes
|
|
111
|
+
|
|
112
|
+
for hit in find_dashes("first line\nsecond\u2014line\u00ad"):
|
|
113
|
+
print(hit.line, hit.column, hit.codepoint, hit.name)
|
|
114
|
+
print(is_dash("\u2212"), is_dash("\u00ad"))
|
|
115
|
+
print("".join(iter_fold_dashes(["a\u2013", "b"])))
|
|
116
|
+
# 2 7 U+2014 EM DASH
|
|
117
|
+
# 2 12 U+00AD SOFT HYPHEN
|
|
118
|
+
# True False
|
|
119
|
+
# a-b
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## All punctuation
|
|
123
|
+
|
|
124
|
+
`to_ascii_punct(text)` folds the rest of the typographic punctuation too: curly quotes become
|
|
125
|
+
`'` and `"`, the ellipsis becomes `...`, non-breaking and other Unicode spaces become a normal
|
|
126
|
+
space, bullets become `*`, fullwidth punctuation from CJK input (U+FF01 to U+FF5E, letters and
|
|
127
|
+
digits excepted) becomes its ASCII character, and dashes follow the `ascii` form. Accented
|
|
128
|
+
letters pass through.
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from unidash import to_ascii_punct
|
|
132
|
+
|
|
133
|
+
print(to_ascii_punct("\u201cCaf\u00e9\u201d\u2014it\u2019s 100\u00a0%\u2026"))
|
|
134
|
+
# "Café"-it's 100 %...
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Command line
|
|
138
|
+
|
|
139
|
+
`unidash FILE...` writes the folded text to stdout (`-` or no file reads stdin). It takes
|
|
140
|
+
`--form`, `--script-hyphens`, `--keep-soft-hyphens`, and `--punct` for the full punctuation
|
|
141
|
+
fold. `--check` lists what would change and exits 1, for pre-commit hooks. Input must be
|
|
142
|
+
UTF-8; unreadable files exit 2.
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
$ unidash --check notes.md
|
|
146
|
+
notes.md:2:6: U+2014 EM DASH
|
|
147
|
+
notes.md:3:3: U+00AD SOFT HYPHEN
|
|
148
|
+
$ unidash --form tex notes.md
|
|
149
|
+
Draft
|
|
150
|
+
Done --- ship it
|
|
151
|
+
coop
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## What counts as a dash
|
|
155
|
+
|
|
156
|
+
The classes follow the Unicode 18.0 Dash property and General_Category=Pd, and the tests
|
|
157
|
+
check them against the Unicode data files and the UTS #39 confusables list.
|
|
158
|
+
|
|
159
|
+
| Code point | Name | `ascii` | `tex` | `typographic` |
|
|
160
|
+
| --- | --- | --- | --- | --- |
|
|
161
|
+
| U+2010 | HYPHEN | `-` | `-` | kept |
|
|
162
|
+
| U+2011 | NON-BREAKING HYPHEN | `-` | `-` | kept |
|
|
163
|
+
| U+2012 | FIGURE DASH | `-` | `-` | kept |
|
|
164
|
+
| U+2013 | EN DASH | `-` | `--` | kept |
|
|
165
|
+
| U+2014 | EM DASH | `-` | `---` | kept |
|
|
166
|
+
| U+2015 | HORIZONTAL BAR | `-` | `---` | kept |
|
|
167
|
+
| U+2212 | MINUS SIGN | `-` | `-` | kept |
|
|
168
|
+
| U+2E17 | DOUBLE OBLIQUE HYPHEN | `-` | `-` | kept |
|
|
169
|
+
| U+2E1A | HYPHEN WITH DIAERESIS | `-` | `-` | kept |
|
|
170
|
+
| U+2E3A | TWO-EM DASH | `-` | `------` | kept |
|
|
171
|
+
| U+2E3B | THREE-EM DASH | `-` | `---------` | kept |
|
|
172
|
+
| U+2E40 | DOUBLE HYPHEN | `-` | `-` | kept |
|
|
173
|
+
| U+2E5D | OBLIQUE HYPHEN | `-` | `-` | kept |
|
|
174
|
+
| U+FE31 | PRESENTATION FORM FOR VERTICAL EM DASH | `-` | `---` | U+2014 |
|
|
175
|
+
| U+FE32 | PRESENTATION FORM FOR VERTICAL EN DASH | `-` | `--` | U+2013 |
|
|
176
|
+
| U+FE58 | SMALL EM DASH | `-` | `---` | U+2014 |
|
|
177
|
+
| U+FE63 | SMALL HYPHEN-MINUS | `-` | `-` | `-` |
|
|
178
|
+
| U+FF0D | FULLWIDTH HYPHEN-MINUS | `-` | `-` | `-` |
|
|
179
|
+
| U+2053 | SWUNG DASH | `~` | `~` | kept |
|
|
180
|
+
| U+301C | WAVE DASH | `~` | `~` | kept |
|
|
181
|
+
| U+3030 | WAVY DASH | `~` | `~` | kept |
|
|
182
|
+
| U+00AD | SOFT HYPHEN | removed | removed | removed |
|
|
183
|
+
|
|
184
|
+
Script hyphens, folded only with `script_hyphens=True` (to `-`, or to U+2010 in
|
|
185
|
+
`typographic`): U+058A ARMENIAN HYPHEN, U+05BE HEBREW PUNCTUATION MAQAF, U+1400 CANADIAN
|
|
186
|
+
SYLLABICS HYPHEN, U+1806 MONGOLIAN TODO SOFT HYPHEN, U+30A0 KATAKANA-HIRAGANA DOUBLE HYPHEN,
|
|
187
|
+
U+10D6E GARAY HYPHEN and U+10EAD YEZIDI HYPHENATION MARK.
|
|
188
|
+
|
|
189
|
+
The double hyphens (U+2E40, and U+1400 and U+30A0 among the script hyphens) become `-`
|
|
190
|
+
although UTS #39 lists them as confusable with `=`: they are hyphens in use, and `=` would
|
|
191
|
+
change the meaning of the text.
|
|
192
|
+
|
|
193
|
+
Never folded: U+002D HYPHEN-MINUS, and U+207B SUPERSCRIPT MINUS and U+208B SUBSCRIPT MINUS,
|
|
194
|
+
which sit next to superscript and subscript digits that stay as they are. Characters that
|
|
195
|
+
only look like a hyphen are not dashes and are left alone: letters in other scripts, the Arabic
|
|
196
|
+
full stop, the hyphen bullet, U+02D7 MODIFIER LETTER MINUS SIGN (a tone mark), and minus-like
|
|
197
|
+
symbols without the Dash property such as U+2052 COMMERCIAL MINUS SIGN, U+2796 HEAVY MINUS
|
|
198
|
+
SIGN (an emoji), U+2E43 DASH WITH LEFT UPTURN and U+10D8F GARAY MINUS SIGN.
|
|
199
|
+
|
|
200
|
+
## Why
|
|
201
|
+
|
|
202
|
+
Tools like `unidecode` and `anyascii` transliterate every character, so `café` turns into
|
|
203
|
+
`cafe`. That is the wrong tool when you only want to tidy punctuation and keep the words.
|
|
204
|
+
`smartypants` goes the opposite way, turning ASCII into typographic dashes. `unidash` folds
|
|
205
|
+
punctuation to ASCII, knows the whole Unicode dash family rather than the three most common
|
|
206
|
+
members, and leaves letters alone. It is zero dependency and typed.
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
The Unicode data files are not part of the repository. `python scripts/fetch_vectors.py`
|
|
211
|
+
downloads them into `tests/vectors/unicode/` and checks each against the size and SHA-256 in
|
|
212
|
+
`MANIFEST.txt`; without them the data tests skip. The installed-wheel test runs with
|
|
213
|
+
`UNIDASH_E2E=1`.
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT. See [LICENSE](LICENSE).
|
|
218
|
+
|
|
219
|
+
## Links
|
|
220
|
+
|
|
221
|
+
- Website: https://lianes8studio.com
|
|
222
|
+
- GitHub: https://github.com/JaviLianes8
|
|
223
|
+
- LinkedIn: https://www.linkedin.com/in/jlianes/
|
unidash-0.2.0/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# unidash
|
|
2
|
+
|
|
3
|
+
Fold Unicode dashes and punctuation to plain ASCII while leaving letters untouched.
|
|
4
|
+
|
|
5
|
+
Text pasted from word processors, PDFs, CJK input methods and web pages is full of
|
|
6
|
+
characters that look like `-` but are not: en and em dashes, the minus sign, the
|
|
7
|
+
non-breaking hyphen, fullwidth and small forms, and the invisible soft hyphen. They break
|
|
8
|
+
search, diffs, command lines and parsers. `unidash` knows every character with the Unicode
|
|
9
|
+
Dash property, plus the soft hyphen, and folds them the way you choose.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
pip install unidash
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Python 3.10 or newer, no dependencies.
|
|
18
|
+
|
|
19
|
+
## Dashes
|
|
20
|
+
|
|
21
|
+
`fold_dashes(text, form="ascii")` has three forms. `ascii` turns every dash into one `-`
|
|
22
|
+
(wavy dashes into `~`). `tex` keeps the en and em dash apart the way TeX and Markdown do, as
|
|
23
|
+
`--` and `---`. `typographic` keeps the real dashes and only replaces the small, vertical and
|
|
24
|
+
fullwidth compatibility forms with their standard counterparts.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from unidash import fold_dashes
|
|
28
|
+
|
|
29
|
+
text = "Pages 10\u201320 \u2014 see \u22125\uff0d6"
|
|
30
|
+
print(fold_dashes(text))
|
|
31
|
+
print(fold_dashes(text, "tex"))
|
|
32
|
+
print(ascii(fold_dashes("a\ufe58b\uff0dc", "typographic")))
|
|
33
|
+
# Pages 10-20 - see -5-6
|
|
34
|
+
# Pages 10--20 --- see -5-6
|
|
35
|
+
# 'a\u2014b-c'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
A minus sign is always a single `-` in the `ascii` and `tex` forms (`typographic` keeps
|
|
39
|
+
U+2212), so negative numbers stay negative, and characters that are already ASCII are never
|
|
40
|
+
touched: `1-2` and a hand-written `--` come out as they went in.
|
|
41
|
+
|
|
42
|
+
## Soft hyphens, non-breaking hyphens and script hyphens
|
|
43
|
+
|
|
44
|
+
The soft hyphen (U+00AD) is a hint for where a word may break, not a character, so it is
|
|
45
|
+
removed unless you pass `keep_soft_hyphens=True`. The non-breaking hyphen (U+2011) becomes
|
|
46
|
+
`-` in the ASCII forms and stays in `typographic`, where its promise matters.
|
|
47
|
+
|
|
48
|
+
Hyphens that belong to one script (Armenian, the Hebrew maqaf, Canadian syllabics,
|
|
49
|
+
Mongolian, the katakana double hyphen, Garay and Yezidi) are left alone, like that script's
|
|
50
|
+
letters, unless you pass `script_hyphens=True`.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from unidash import fold_dashes
|
|
54
|
+
|
|
55
|
+
print(fold_dashes("co\u00adop\u00aderate"))
|
|
56
|
+
print(ascii(fold_dashes("co\u00adop", keep_soft_hyphens=True)))
|
|
57
|
+
print(ascii(fold_dashes("\u05e2\u05be\u05d1")))
|
|
58
|
+
print(ascii(fold_dashes("\u05e2\u05be\u05d1", script_hyphens=True)))
|
|
59
|
+
# cooperate
|
|
60
|
+
# 'co\xadop'
|
|
61
|
+
# '\u05e2\u05be\u05d1'
|
|
62
|
+
# '\u05e2-\u05d1'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Finding dashes
|
|
66
|
+
|
|
67
|
+
`find_dashes` yields a `DashHit` (offset, line, column, character and Unicode name) for
|
|
68
|
+
every character `fold_dashes` would change with the same options, which makes a lint or a
|
|
69
|
+
pre-commit check a one-liner. Lines end at LF, CR or CRLF, columns count code points from 1,
|
|
70
|
+
and a byte order mark at the start of the text takes no column. `is_dash(char)` tells whether a character has the Unicode Dash
|
|
71
|
+
property and `DASHES` is that set. `dash_table(...)` returns the `str.translate` table, and
|
|
72
|
+
`iter_fold_dashes(chunks, ...)` folds an iterable of strings lazily, for large inputs.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from unidash import find_dashes, is_dash, iter_fold_dashes
|
|
76
|
+
|
|
77
|
+
for hit in find_dashes("first line\nsecond\u2014line\u00ad"):
|
|
78
|
+
print(hit.line, hit.column, hit.codepoint, hit.name)
|
|
79
|
+
print(is_dash("\u2212"), is_dash("\u00ad"))
|
|
80
|
+
print("".join(iter_fold_dashes(["a\u2013", "b"])))
|
|
81
|
+
# 2 7 U+2014 EM DASH
|
|
82
|
+
# 2 12 U+00AD SOFT HYPHEN
|
|
83
|
+
# True False
|
|
84
|
+
# a-b
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## All punctuation
|
|
88
|
+
|
|
89
|
+
`to_ascii_punct(text)` folds the rest of the typographic punctuation too: curly quotes become
|
|
90
|
+
`'` and `"`, the ellipsis becomes `...`, non-breaking and other Unicode spaces become a normal
|
|
91
|
+
space, bullets become `*`, fullwidth punctuation from CJK input (U+FF01 to U+FF5E, letters and
|
|
92
|
+
digits excepted) becomes its ASCII character, and dashes follow the `ascii` form. Accented
|
|
93
|
+
letters pass through.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from unidash import to_ascii_punct
|
|
97
|
+
|
|
98
|
+
print(to_ascii_punct("\u201cCaf\u00e9\u201d\u2014it\u2019s 100\u00a0%\u2026"))
|
|
99
|
+
# "Café"-it's 100 %...
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Command line
|
|
103
|
+
|
|
104
|
+
`unidash FILE...` writes the folded text to stdout (`-` or no file reads stdin). It takes
|
|
105
|
+
`--form`, `--script-hyphens`, `--keep-soft-hyphens`, and `--punct` for the full punctuation
|
|
106
|
+
fold. `--check` lists what would change and exits 1, for pre-commit hooks. Input must be
|
|
107
|
+
UTF-8; unreadable files exit 2.
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
$ unidash --check notes.md
|
|
111
|
+
notes.md:2:6: U+2014 EM DASH
|
|
112
|
+
notes.md:3:3: U+00AD SOFT HYPHEN
|
|
113
|
+
$ unidash --form tex notes.md
|
|
114
|
+
Draft
|
|
115
|
+
Done --- ship it
|
|
116
|
+
coop
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## What counts as a dash
|
|
120
|
+
|
|
121
|
+
The classes follow the Unicode 18.0 Dash property and General_Category=Pd, and the tests
|
|
122
|
+
check them against the Unicode data files and the UTS #39 confusables list.
|
|
123
|
+
|
|
124
|
+
| Code point | Name | `ascii` | `tex` | `typographic` |
|
|
125
|
+
| --- | --- | --- | --- | --- |
|
|
126
|
+
| U+2010 | HYPHEN | `-` | `-` | kept |
|
|
127
|
+
| U+2011 | NON-BREAKING HYPHEN | `-` | `-` | kept |
|
|
128
|
+
| U+2012 | FIGURE DASH | `-` | `-` | kept |
|
|
129
|
+
| U+2013 | EN DASH | `-` | `--` | kept |
|
|
130
|
+
| U+2014 | EM DASH | `-` | `---` | kept |
|
|
131
|
+
| U+2015 | HORIZONTAL BAR | `-` | `---` | kept |
|
|
132
|
+
| U+2212 | MINUS SIGN | `-` | `-` | kept |
|
|
133
|
+
| U+2E17 | DOUBLE OBLIQUE HYPHEN | `-` | `-` | kept |
|
|
134
|
+
| U+2E1A | HYPHEN WITH DIAERESIS | `-` | `-` | kept |
|
|
135
|
+
| U+2E3A | TWO-EM DASH | `-` | `------` | kept |
|
|
136
|
+
| U+2E3B | THREE-EM DASH | `-` | `---------` | kept |
|
|
137
|
+
| U+2E40 | DOUBLE HYPHEN | `-` | `-` | kept |
|
|
138
|
+
| U+2E5D | OBLIQUE HYPHEN | `-` | `-` | kept |
|
|
139
|
+
| U+FE31 | PRESENTATION FORM FOR VERTICAL EM DASH | `-` | `---` | U+2014 |
|
|
140
|
+
| U+FE32 | PRESENTATION FORM FOR VERTICAL EN DASH | `-` | `--` | U+2013 |
|
|
141
|
+
| U+FE58 | SMALL EM DASH | `-` | `---` | U+2014 |
|
|
142
|
+
| U+FE63 | SMALL HYPHEN-MINUS | `-` | `-` | `-` |
|
|
143
|
+
| U+FF0D | FULLWIDTH HYPHEN-MINUS | `-` | `-` | `-` |
|
|
144
|
+
| U+2053 | SWUNG DASH | `~` | `~` | kept |
|
|
145
|
+
| U+301C | WAVE DASH | `~` | `~` | kept |
|
|
146
|
+
| U+3030 | WAVY DASH | `~` | `~` | kept |
|
|
147
|
+
| U+00AD | SOFT HYPHEN | removed | removed | removed |
|
|
148
|
+
|
|
149
|
+
Script hyphens, folded only with `script_hyphens=True` (to `-`, or to U+2010 in
|
|
150
|
+
`typographic`): U+058A ARMENIAN HYPHEN, U+05BE HEBREW PUNCTUATION MAQAF, U+1400 CANADIAN
|
|
151
|
+
SYLLABICS HYPHEN, U+1806 MONGOLIAN TODO SOFT HYPHEN, U+30A0 KATAKANA-HIRAGANA DOUBLE HYPHEN,
|
|
152
|
+
U+10D6E GARAY HYPHEN and U+10EAD YEZIDI HYPHENATION MARK.
|
|
153
|
+
|
|
154
|
+
The double hyphens (U+2E40, and U+1400 and U+30A0 among the script hyphens) become `-`
|
|
155
|
+
although UTS #39 lists them as confusable with `=`: they are hyphens in use, and `=` would
|
|
156
|
+
change the meaning of the text.
|
|
157
|
+
|
|
158
|
+
Never folded: U+002D HYPHEN-MINUS, and U+207B SUPERSCRIPT MINUS and U+208B SUBSCRIPT MINUS,
|
|
159
|
+
which sit next to superscript and subscript digits that stay as they are. Characters that
|
|
160
|
+
only look like a hyphen are not dashes and are left alone: letters in other scripts, the Arabic
|
|
161
|
+
full stop, the hyphen bullet, U+02D7 MODIFIER LETTER MINUS SIGN (a tone mark), and minus-like
|
|
162
|
+
symbols without the Dash property such as U+2052 COMMERCIAL MINUS SIGN, U+2796 HEAVY MINUS
|
|
163
|
+
SIGN (an emoji), U+2E43 DASH WITH LEFT UPTURN and U+10D8F GARAY MINUS SIGN.
|
|
164
|
+
|
|
165
|
+
## Why
|
|
166
|
+
|
|
167
|
+
Tools like `unidecode` and `anyascii` transliterate every character, so `café` turns into
|
|
168
|
+
`cafe`. That is the wrong tool when you only want to tidy punctuation and keep the words.
|
|
169
|
+
`smartypants` goes the opposite way, turning ASCII into typographic dashes. `unidash` folds
|
|
170
|
+
punctuation to ASCII, knows the whole Unicode dash family rather than the three most common
|
|
171
|
+
members, and leaves letters alone. It is zero dependency and typed.
|
|
172
|
+
|
|
173
|
+
## Development
|
|
174
|
+
|
|
175
|
+
The Unicode data files are not part of the repository. `python scripts/fetch_vectors.py`
|
|
176
|
+
downloads them into `tests/vectors/unicode/` and checks each against the size and SHA-256 in
|
|
177
|
+
`MANIFEST.txt`; without them the data tests skip. The installed-wheel test runs with
|
|
178
|
+
`UNIDASH_E2E=1`.
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT. See [LICENSE](LICENSE).
|
|
183
|
+
|
|
184
|
+
## Links
|
|
185
|
+
|
|
186
|
+
- Website: https://lianes8studio.com
|
|
187
|
+
- GitHub: https://github.com/JaviLianes8
|
|
188
|
+
- LinkedIn: https://www.linkedin.com/in/jlianes/
|