From 8ea3dc020f1d3592ec606a9ad0b494679d866ee3 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 12:45:19 +0200 Subject: [PATCH 01/10] hyphenate text --- vpype/text.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/vpype/text.py b/vpype/text.py index f8fe7c29..dc4c55f9 100644 --- a/vpype/text.py +++ b/vpype/text.py @@ -23,6 +23,7 @@ import itertools import pickle +import pyphen from dataclasses import dataclass from pathlib import Path from typing import Callable @@ -145,8 +146,9 @@ def text_line( return lc -def _word_wrap(paragraph: str, width: float, measure_func: Callable[[str], float]): +def _word_wrap(paragraph: str, width: float, lang: str, measure_func: Callable[[str], float]): """Break text in multiple line.""" + dic = pyphen.Pyphen(lang=lang) result = [] for line in paragraph.split("\n"): # handle empty lines @@ -162,13 +164,23 @@ def _word_wrap(paragraph: str, width: float, measure_func: Callable[[str], float for a, b in zip(fields[::2], fields[1::2]): w = measure_func(x + a) if w > width: - if x == "": - result.append(a) - continue - else: - result.append(x) - x = "" - x += a + b + for (aa, ab) in dic.iterate(a): # try hyphenating + xa = x+aa+"\u002D" # our fonts don't have a true hyphen + w = measure_func(xa) + if w <= width: + result.append(xa) + x = ab+b + break + else: # no fitting hyphenation + if x == "": # single word exceeds width + result.append(a) + continue + else: + result.append(x) + x = "" + x += a + b + else: + x += a + b if x != "": result.append(x + "\n") return result @@ -195,6 +207,7 @@ def text_block( align: str = "left", line_spacing: float = 1, justify=False, + hyphenate="en", ) -> LineCollection: """Create a wrapped block of text using the provided width. @@ -221,7 +234,7 @@ def measure(txt): bounds = _text_line(txt, font).bounds() return bounds[2] if bounds else 0.0 - lines = _word_wrap(paragraph, width, measure) + lines = _word_wrap(paragraph, width, hyphenate, measure) lc_arr = [ _justify_text(line, font, width) From daa273442682436591300781602e1c54bcb52a32 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:27:40 +0200 Subject: [PATCH 02/10] add --hyphenate parameter --- vpype/text.py | 8 +++++--- vpype_cli/text.py | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/vpype/text.py b/vpype/text.py index dc4c55f9..6ebdb2ac 100644 --- a/vpype/text.py +++ b/vpype/text.py @@ -146,9 +146,10 @@ def text_line( return lc -def _word_wrap(paragraph: str, width: float, lang: str, measure_func: Callable[[str], float]): +def _word_wrap(paragraph: str, width: float, lang: str | None, measure_func: Callable[[str], float]): """Break text in multiple line.""" - dic = pyphen.Pyphen(lang=lang) + dic = pyphen.Pyphen(lang=lang) if lang else None + print(lang, dic) result = [] for line in paragraph.split("\n"): # handle empty lines @@ -164,7 +165,8 @@ def _word_wrap(paragraph: str, width: float, lang: str, measure_func: Callable[[ for a, b in zip(fields[::2], fields[1::2]): w = measure_func(x + a) if w > width: - for (aa, ab) in dic.iterate(a): # try hyphenating + + for (aa, ab) in (dic.iterate(a) if dic else ()): # try hyphenating xa = x+aa+"\u002D" # our fonts don't have a true hyphen w = measure_func(xa) if w <= width: diff --git a/vpype_cli/text.py b/vpype_cli/text.py index 81ce03d7..976c0ee1 100644 --- a/vpype_cli/text.py +++ b/vpype_cli/text.py @@ -16,6 +16,7 @@ ) @click.option("-s", "--size", type=LengthType(), default=18, help="Text size (default: 18).") @click.option("-w", "--wrap", type=LengthType(), help="Wrap to provided width.") +@click.option("-h", "--hyphenate", type=TextType(), help="Wrap to provided width.") @click.option("-j", "--justify", is_flag=True, help="Justify text block (wrap-mode only).") @click.option( "-p", @@ -38,6 +39,7 @@ def text( font: str, size: float, wrap: float | None, + hyphenate: str | None, justify: float, position: tuple[float, float], align: str, @@ -64,7 +66,7 @@ def text( if wrap: lc = vp.text_block( - string, font_name=font, width=wrap, size=size, align=align, justify=justify + string, font_name=font, width=wrap, size=size, align=align, justify=justify, hyphenate=hyphenate ) else: lc = vp.text_line(string, font_name=font, size=size, align=align) From 8b617b7e27b20ee31e17b5564444049b4423080e Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:29:33 +0200 Subject: [PATCH 03/10] forgot docstring --- vpype_cli/text.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpype_cli/text.py b/vpype_cli/text.py index 976c0ee1..11683bd9 100644 --- a/vpype_cli/text.py +++ b/vpype_cli/text.py @@ -16,7 +16,7 @@ ) @click.option("-s", "--size", type=LengthType(), default=18, help="Text size (default: 18).") @click.option("-w", "--wrap", type=LengthType(), help="Wrap to provided width.") -@click.option("-h", "--hyphenate", type=TextType(), help="Wrap to provided width.") +@click.option("-h", "--hyphenate", type=TextType(), help="Hyphenate wrapped words using the provided language.") @click.option("-j", "--justify", is_flag=True, help="Justify text block (wrap-mode only).") @click.option( "-p", From 8cbfa15a7323531267d5764bcce9d7d3f66c346e Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:31:26 +0200 Subject: [PATCH 04/10] update text docs --- vpype_cli/text.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vpype_cli/text.py b/vpype_cli/text.py index 11683bd9..0264e499 100644 --- a/vpype_cli/text.py +++ b/vpype_cli/text.py @@ -55,7 +55,8 @@ def text( In wrap mode, the text start at (0, 0) and expends left until it reach the specified width. The `--align` option controls how the text is laid out within the column and behaves as - typically expected. + typically expected. The `--hyphenate` options enables hyphenation using the provided + language code. To start the text at the different location than (0, 0), use the `--position` option. """ From ac07354d764b3adf9f60d37f083f6775e9108bf1 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:34:29 +0200 Subject: [PATCH 05/10] add pyphen to project --- poetry.lock | 43 +++++++++++++++++++++++++++++++++++++++++-- pyproject.toml | 1 + 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5c522de9..8fc46040 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "alabaster" @@ -259,6 +259,7 @@ files = [ {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"}, {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"}, {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"}, + {file = "contourpy-1.1.0-cp310-cp310-win32.whl", hash = "sha256:9b2dd2ca3ac561aceef4c7c13ba654aaa404cf885b187427760d7f7d4c57cff8"}, {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"}, {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"}, {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"}, @@ -267,6 +268,7 @@ files = [ {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"}, {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"}, {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"}, + {file = "contourpy-1.1.0-cp311-cp311-win32.whl", hash = "sha256:edb989d31065b1acef3828a3688f88b2abb799a7db891c9e282df5ec7e46221b"}, {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"}, {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"}, {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"}, @@ -275,6 +277,7 @@ files = [ {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"}, {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"}, {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"}, + {file = "contourpy-1.1.0-cp38-cp38-win32.whl", hash = "sha256:108dfb5b3e731046a96c60bdc46a1a0ebee0760418951abecbe0fc07b5b93b27"}, {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"}, {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"}, {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"}, @@ -283,6 +286,7 @@ files = [ {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"}, {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"}, {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"}, + {file = "contourpy-1.1.0-cp39-cp39-win32.whl", hash = "sha256:71551f9520f008b2950bef5f16b0e3587506ef4f23c734b71ffb7b89f8721999"}, {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"}, {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"}, {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"}, @@ -814,6 +818,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -1374,6 +1388,21 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] +[[package]] +name = "pyphen" +version = "0.14.0" +description = "Pure Python module to hyphenate text" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyphen-0.14.0-py3-none-any.whl", hash = "sha256:414c9355958ca3c6a3ff233f65678c245b8ecb56418fb291e2b93499d61cd510"}, + {file = "pyphen-0.14.0.tar.gz", hash = "sha256:596c8b3be1c1a70411ba5f6517d9ccfe3083c758ae2b94a45f2707346d8e66fa"}, +] + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + [[package]] name = "pyside6" version = "6.5.2" @@ -1549,6 +1578,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1556,8 +1586,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1574,6 +1611,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1581,6 +1619,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2150,4 +2189,4 @@ all = ["Pillow", "PySide6", "glcontext", "matplotlib", "moderngl"] [metadata] lock-version = "2.0" python-versions = ">=3.9, <3.12" -content-hash = "c9fc73348b159d48dab6a3f81f7951375ab91ef45db03726d205d9cee915eaaa" +content-hash = "243713c9958bccaada6645b8ddb6cd2aa25c96912b0f9efe73abf4a3408ea8ff" diff --git a/pyproject.toml b/pyproject.toml index e0226d04..af60a42e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ glcontext = { version = ">=2.3.2", optional = true } # 2.3.2 needed to fix #200 moderngl = { version = ">=5.6.2,!=5.7.1,!=5.7.2", optional = true } # see moderngl/moderngl#525 Pillow = { version = ">=9.0.1", optional = true } PySide6 = { version = ">=6.4.0.1", optional = true } +pyphen = "^0.14.0" [tool.poetry.group.dev.dependencies] From 5a3c360473915ac1fee86ae8b91dfae11471d684 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:35:52 +0200 Subject: [PATCH 06/10] reformat --- vpype/text.py | 15 ++++++++------- vpype_cli/text.py | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/vpype/text.py b/vpype/text.py index 6ebdb2ac..c86212ed 100644 --- a/vpype/text.py +++ b/vpype/text.py @@ -146,7 +146,9 @@ def text_line( return lc -def _word_wrap(paragraph: str, width: float, lang: str | None, measure_func: Callable[[str], float]): +def _word_wrap( + paragraph: str, width: float, lang: str | None, measure_func: Callable[[str], float] +): """Break text in multiple line.""" dic = pyphen.Pyphen(lang=lang) if lang else None print(lang, dic) @@ -165,16 +167,15 @@ def _word_wrap(paragraph: str, width: float, lang: str | None, measure_func: Cal for a, b in zip(fields[::2], fields[1::2]): w = measure_func(x + a) if w > width: - - for (aa, ab) in (dic.iterate(a) if dic else ()): # try hyphenating - xa = x+aa+"\u002D" # our fonts don't have a true hyphen + for aa, ab in dic.iterate(a) if dic else (): # try hyphenating + xa = x + aa + "\u002D" # our fonts don't have a true hyphen w = measure_func(xa) if w <= width: result.append(xa) - x = ab+b + x = ab + b break - else: # no fitting hyphenation - if x == "": # single word exceeds width + else: # no fitting hyphenation + if x == "": # single word exceeds width result.append(a) continue else: diff --git a/vpype_cli/text.py b/vpype_cli/text.py index 0264e499..bfee36a9 100644 --- a/vpype_cli/text.py +++ b/vpype_cli/text.py @@ -16,7 +16,12 @@ ) @click.option("-s", "--size", type=LengthType(), default=18, help="Text size (default: 18).") @click.option("-w", "--wrap", type=LengthType(), help="Wrap to provided width.") -@click.option("-h", "--hyphenate", type=TextType(), help="Hyphenate wrapped words using the provided language.") +@click.option( + "-h", + "--hyphenate", + type=TextType(), + help="Hyphenate wrapped words using the provided language.", +) @click.option("-j", "--justify", is_flag=True, help="Justify text block (wrap-mode only).") @click.option( "-p", @@ -67,7 +72,13 @@ def text( if wrap: lc = vp.text_block( - string, font_name=font, width=wrap, size=size, align=align, justify=justify, hyphenate=hyphenate + string, + font_name=font, + width=wrap, + size=size, + align=align, + justify=justify, + hyphenate=hyphenate, ) else: lc = vp.text_line(string, font_name=font, size=size, align=align) From 72cdc66535a534eba4329412f018c59cc7818efc Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:40:02 +0200 Subject: [PATCH 07/10] ruff checks --- vpype/text.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vpype/text.py b/vpype/text.py index c86212ed..dc8bb5e4 100644 --- a/vpype/text.py +++ b/vpype/text.py @@ -23,11 +23,12 @@ import itertools import pickle -import pyphen from dataclasses import dataclass from pathlib import Path from typing import Callable +import pyphen + from .model import LineCollection __all__ = ["FONT_NAMES", "text_line", "text_block"] @@ -210,7 +211,7 @@ def text_block( align: str = "left", line_spacing: float = 1, justify=False, - hyphenate="en", + hyphenate=None, ) -> LineCollection: """Create a wrapped block of text using the provided width. @@ -226,6 +227,7 @@ def text_block( left alignment) line_spacing: line spacing (default: 1.0) justify: should the text be justified (default: False) + hyphenate: wrapped text is hyphenated with the given language (default: None) """ font = _Font.get(font_name) From 14dd56a3054179bd229185103ab00c68d6c523df Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sun, 8 Oct 2023 21:48:28 +0200 Subject: [PATCH 08/10] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index caacae54..da75ec66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Release date: UNRELEASED ### New features and improvements * Added an option to the `reverse` command to also flip the line direction (#654) +* Added a `--hyphenate LANG` option to the `text` command (#668) ### Bug fixes From 620f16c66def52eb54ef4c7ede028ea22b8529e8 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Fri, 13 Oct 2023 20:32:00 +0200 Subject: [PATCH 09/10] add example language codes --- vpype/text.py | 3 +-- vpype_cli/text.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/vpype/text.py b/vpype/text.py index dc8bb5e4..b3842849 100644 --- a/vpype/text.py +++ b/vpype/text.py @@ -152,7 +152,6 @@ def _word_wrap( ): """Break text in multiple line.""" dic = pyphen.Pyphen(lang=lang) if lang else None - print(lang, dic) result = [] for line in paragraph.split("\n"): # handle empty lines @@ -227,7 +226,7 @@ def text_block( left alignment) line_spacing: line spacing (default: 1.0) justify: should the text be justified (default: False) - hyphenate: wrapped text is hyphenated with the given language (default: None) + hyphenate: wrapped text is hyphenated with the given language (en, nl, etc, default: None) """ font = _Font.get(font_name) diff --git a/vpype_cli/text.py b/vpype_cli/text.py index bfee36a9..6c712161 100644 --- a/vpype_cli/text.py +++ b/vpype_cli/text.py @@ -20,7 +20,7 @@ "-h", "--hyphenate", type=TextType(), - help="Hyphenate wrapped words using the provided language.", + help="Hyphenate wrapped words using the provided language code (en, nl, etc.)", ) @click.option("-j", "--justify", is_flag=True, help="Justify text block (wrap-mode only).") @click.option( @@ -61,7 +61,7 @@ def text( In wrap mode, the text start at (0, 0) and expends left until it reach the specified width. The `--align` option controls how the text is laid out within the column and behaves as typically expected. The `--hyphenate` options enables hyphenation using the provided - language code. + language code (en, nl, etc.) To start the text at the different location than (0, 0), use the `--position` option. """ From e90071bc3c3508523b4b798a6ba0dae34e17232a Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Fri, 13 Oct 2023 22:12:37 +0200 Subject: [PATCH 10/10] fix ruff check again --- vpype/text.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpype/text.py b/vpype/text.py index b3842849..e7fbc939 100644 --- a/vpype/text.py +++ b/vpype/text.py @@ -226,7 +226,7 @@ def text_block( left alignment) line_spacing: line spacing (default: 1.0) justify: should the text be justified (default: False) - hyphenate: wrapped text is hyphenated with the given language (en, nl, etc, default: None) + hyphenate: wrapped text is hyphenated with the given language (en, etc., default: None) """ font = _Font.get(font_name)