manimpango 0.2.4__tar.gz → 0.2.5__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.
- ManimPango-0.2.5/.coveragerc +26 -0
- ManimPango-0.2.5/CODE_OF_CONDUCT.md +5 -0
- ManimPango-0.2.5/MANIFEST.in +7 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5/ManimPango.egg-info}/PKG-INFO +2 -2
- {ManimPango-0.2.4 → ManimPango-0.2.5}/ManimPango.egg-info/SOURCES.txt +21 -1
- {ManimPango-0.2.4/ManimPango.egg-info → ManimPango-0.2.5}/PKG-INFO +2 -2
- {ManimPango-0.2.4 → ManimPango-0.2.5}/README.md +1 -1
- ManimPango-0.2.5/docs/RELEASE.rst +52 -0
- ManimPango-0.2.5/docs/_static/favicon.ico +0 -0
- ManimPango-0.2.5/docs/_templates/autosummary/class.rst +19 -0
- ManimPango-0.2.5/docs/_templates/autosummary/module.rst +50 -0
- ManimPango-0.2.5/docs/conf.py +85 -0
- ManimPango-0.2.5/docs/index.rst +16 -0
- ManimPango-0.2.5/docs/make.bat +35 -0
- ManimPango-0.2.5/docs/reference.rst +22 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/__init__.py +2 -2
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/_version.py +1 -1
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/cmanimpango.pyx +34 -2
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/enums.pyx +18 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/pango.pxd +35 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/utils.py +0 -2
- ManimPango-0.2.5/requirements-dev.txt +5 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/setup.cfg +5 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/setup.py +10 -2
- {ManimPango-0.2.4 → ManimPango-0.2.5}/tests/__init__.py +10 -0
- ManimPango-0.2.5/tests/_manim.py +81 -0
- ManimPango-0.2.5/tests/conftest.py +10 -0
- ManimPango-0.2.5/tests/fonts/AdobeVFPrototype.ttf +0 -0
- ManimPango-0.2.5/tests/fonts/BungeeColor-Regular_colr_Windows.ttf +0 -0
- ManimPango-0.2.5/tests/fonts/BungeeOutline-Regular.ttf +0 -0
- ManimPango-0.2.5/tests/fonts/LICENSE.txt +6 -0
- ManimPango-0.2.5/tests/fonts/NotoNastaliqUrdu-Regular.ttf +0 -0
- ManimPango-0.2.5/tests/svg_tester.py +134 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/tests/test_fonts.py +20 -2
- ManimPango-0.2.5/tests/test_markup.py +99 -0
- ManimPango-0.2.5/tests/test_utils.py +40 -0
- ManimPango-0.2.4/MANIFEST.in +0 -4
- ManimPango-0.2.4/tests/test_markup.py +0 -24
- {ManimPango-0.2.4 → ManimPango-0.2.5}/LICENSE +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/ManimPango.egg-info/dependency_links.txt +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/ManimPango.egg-info/not-zip-safe +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/ManimPango.egg-info/top_level.txt +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/cairo.pxd +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/cmanimpango.pxd +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/glib.pxd +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/register_font.pxd +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/manimpango/register_font.pyx +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/pyproject.toml +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/tests/test_import.py +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/tests/test_list_fonts.py +0 -0
- {ManimPango-0.2.4 → ManimPango-0.2.5}/tests/test_version.py +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[run]
|
|
2
|
+
plugins = Cython.Coverage
|
|
3
|
+
omit =
|
|
4
|
+
packing
|
|
5
|
+
data_file = .coverage/data
|
|
6
|
+
source = manimpango
|
|
7
|
+
|
|
8
|
+
[report]
|
|
9
|
+
skip_empty = true
|
|
10
|
+
ignore_errors = true
|
|
11
|
+
exclude_lines =
|
|
12
|
+
pragma: no cover
|
|
13
|
+
def __repr__
|
|
14
|
+
if self.debug:
|
|
15
|
+
raise AssertionError
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
except Exception as e:
|
|
18
|
+
|
|
19
|
+
[html]
|
|
20
|
+
directory = .coverage/html
|
|
21
|
+
|
|
22
|
+
[xml]
|
|
23
|
+
output = .coverage/coverage.xml
|
|
24
|
+
|
|
25
|
+
[json]
|
|
26
|
+
output = .coverage/coverage.json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ManimPango
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Bindings for Pango for using with Manim.
|
|
5
5
|
Home-page: https://manimpango.manim.community/
|
|
6
6
|
Author: Naveen M K
|
|
@@ -16,7 +16,7 @@ Description: # ManimPango
|
|
|
16
16
|
<a href="https://pypi.org/project/manimpango/"><img src="https://img.shields.io/pypi/v/manimpango.svg?style=flat&logo=pypi" alt="PyPI Latest Release"></a>
|
|
17
17
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Wheel" src="https://img.shields.io/pypi/wheel/manimpango"></a>
|
|
18
18
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/manimpango"></a>
|
|
19
|
-
<a href="
|
|
19
|
+
<a href="https://choosealicense.com/licenses/gpl-3.0/"><img alt="PyPI - License" src="https://img.shields.io/pypi/l/manimpango"></a>
|
|
20
20
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/pangocffi.svg?style=flat"></a>
|
|
21
21
|
<a href='https://manimpango.readthedocs.io/en/latest/?badge=latest'><img src='https://readthedocs.org/projects/manimpango/badge/?version=latest' alt='Documentation Status' /></a>
|
|
22
22
|
<br>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
.coveragerc
|
|
2
|
+
CODE_OF_CONDUCT.md
|
|
1
3
|
LICENSE
|
|
2
4
|
MANIFEST.in
|
|
3
5
|
README.md
|
|
4
6
|
pyproject.toml
|
|
7
|
+
requirements-dev.txt
|
|
5
8
|
setup.cfg
|
|
6
9
|
setup.py
|
|
7
10
|
ManimPango.egg-info/PKG-INFO
|
|
@@ -9,6 +12,14 @@ ManimPango.egg-info/SOURCES.txt
|
|
|
9
12
|
ManimPango.egg-info/dependency_links.txt
|
|
10
13
|
ManimPango.egg-info/not-zip-safe
|
|
11
14
|
ManimPango.egg-info/top_level.txt
|
|
15
|
+
docs/RELEASE.rst
|
|
16
|
+
docs/conf.py
|
|
17
|
+
docs/index.rst
|
|
18
|
+
docs/make.bat
|
|
19
|
+
docs/reference.rst
|
|
20
|
+
docs/_static/favicon.ico
|
|
21
|
+
docs/_templates/autosummary/class.rst
|
|
22
|
+
docs/_templates/autosummary/module.rst
|
|
12
23
|
manimpango/__init__.py
|
|
13
24
|
manimpango/_version.py
|
|
14
25
|
manimpango/cairo.pxd
|
|
@@ -21,8 +32,17 @@ manimpango/register_font.pxd
|
|
|
21
32
|
manimpango/register_font.pyx
|
|
22
33
|
manimpango/utils.py
|
|
23
34
|
tests/__init__.py
|
|
35
|
+
tests/_manim.py
|
|
36
|
+
tests/conftest.py
|
|
37
|
+
tests/svg_tester.py
|
|
24
38
|
tests/test_fonts.py
|
|
25
39
|
tests/test_import.py
|
|
26
40
|
tests/test_list_fonts.py
|
|
27
41
|
tests/test_markup.py
|
|
28
|
-
tests/
|
|
42
|
+
tests/test_utils.py
|
|
43
|
+
tests/test_version.py
|
|
44
|
+
tests/fonts/AdobeVFPrototype.ttf
|
|
45
|
+
tests/fonts/BungeeColor-Regular_colr_Windows.ttf
|
|
46
|
+
tests/fonts/BungeeOutline-Regular.ttf
|
|
47
|
+
tests/fonts/LICENSE.txt
|
|
48
|
+
tests/fonts/NotoNastaliqUrdu-Regular.ttf
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ManimPango
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Bindings for Pango for using with Manim.
|
|
5
5
|
Home-page: https://manimpango.manim.community/
|
|
6
6
|
Author: Naveen M K
|
|
@@ -16,7 +16,7 @@ Description: # ManimPango
|
|
|
16
16
|
<a href="https://pypi.org/project/manimpango/"><img src="https://img.shields.io/pypi/v/manimpango.svg?style=flat&logo=pypi" alt="PyPI Latest Release"></a>
|
|
17
17
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Wheel" src="https://img.shields.io/pypi/wheel/manimpango"></a>
|
|
18
18
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/manimpango"></a>
|
|
19
|
-
<a href="
|
|
19
|
+
<a href="https://choosealicense.com/licenses/gpl-3.0/"><img alt="PyPI - License" src="https://img.shields.io/pypi/l/manimpango"></a>
|
|
20
20
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/pangocffi.svg?style=flat"></a>
|
|
21
21
|
<a href='https://manimpango.readthedocs.io/en/latest/?badge=latest'><img src='https://readthedocs.org/projects/manimpango/badge/?version=latest' alt='Documentation Status' /></a>
|
|
22
22
|
<br>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<a href="https://pypi.org/project/manimpango/"><img src="https://img.shields.io/pypi/v/manimpango.svg?style=flat&logo=pypi" alt="PyPI Latest Release"></a>
|
|
5
5
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Wheel" src="https://img.shields.io/pypi/wheel/manimpango"></a>
|
|
6
6
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/manimpango"></a>
|
|
7
|
-
<a href="
|
|
7
|
+
<a href="https://choosealicense.com/licenses/gpl-3.0/"><img alt="PyPI - License" src="https://img.shields.io/pypi/l/manimpango"></a>
|
|
8
8
|
<a href="https://pypi.org/project/manimpango/"><img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/pangocffi.svg?style=flat"></a>
|
|
9
9
|
<a href='https://manimpango.readthedocs.io/en/latest/?badge=latest'><img src='https://readthedocs.org/projects/manimpango/badge/?version=latest' alt='Documentation Status' /></a>
|
|
10
10
|
<br>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Release Procedure
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
This is the **maintainer** note on how to Release.
|
|
5
|
+
All versioning is in accordance to
|
|
6
|
+
`Semantic Versioning 2.0.0 <https://semver.org/>`_.
|
|
7
|
+
This means older version would have a backport of bugs fixes.
|
|
8
|
+
|
|
9
|
+
1. Check whether the test suite passes on the main branch.
|
|
10
|
+
|
|
11
|
+
2. Revert any changes which seems to be not working, and check
|
|
12
|
+
for the milestone if PR are merged accordingly.
|
|
13
|
+
|
|
14
|
+
3. Check whether the `Wheels Build`_,
|
|
15
|
+
against the main branch works as expected.
|
|
16
|
+
|
|
17
|
+
4. Clone the repository locally.
|
|
18
|
+
|
|
19
|
+
5. Bump the version in `manimpango/_version`_ accordingly.
|
|
20
|
+
|
|
21
|
+
6. Make a commit with the changes done, as ``Release v<version here>``
|
|
22
|
+
|
|
23
|
+
7. Create a tag, locally with
|
|
24
|
+
|
|
25
|
+
.. code-block:: sh
|
|
26
|
+
|
|
27
|
+
git tag -s v<version-number>
|
|
28
|
+
|
|
29
|
+
.. note::
|
|
30
|
+
|
|
31
|
+
Here, ``-s`` is used to sign the tag with gpg so that users
|
|
32
|
+
can later verify it, and a tag shouldn't be created with
|
|
33
|
+
signing because Github shows it unverified.
|
|
34
|
+
.. important::
|
|
35
|
+
|
|
36
|
+
The message should include the changelog of the release.
|
|
37
|
+
|
|
38
|
+
8. Push the tag to remote.
|
|
39
|
+
|
|
40
|
+
9. Go to `Github`_, and `draft a new release`_ with the same tag pushed.
|
|
41
|
+
|
|
42
|
+
10. Check whether the CI uploads the wheels and the ``.tar.gz`` file to
|
|
43
|
+
PyPi.
|
|
44
|
+
|
|
45
|
+
11. Finally, test the ``.tar.gz`` which was uploaded to `PyPi`_, and install
|
|
46
|
+
it in a new virtual environment.
|
|
47
|
+
|
|
48
|
+
.. _Wheels Build: https://github.com/ManimCommunity/ManimPango/actions?query=workflow%3A%22Build+Wheels%22
|
|
49
|
+
.. _manimpango/_version: https://github.com/ManimCommunity/ManimPango/blob/main/manimpango/_version.py
|
|
50
|
+
.. _Github: https://github.com
|
|
51
|
+
.. _draft a new release: https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/managing-releases-in-a-repository#creating-a-release
|
|
52
|
+
.. _PyPi: https://pypi.org/project/manimpango/
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{{ fullname | escape | underline}}
|
|
2
|
+
|
|
3
|
+
.. currentmodule:: {{ module }}
|
|
4
|
+
|
|
5
|
+
.. autoclass:: {{ objname }}
|
|
6
|
+
:show-inheritance:
|
|
7
|
+
:members:
|
|
8
|
+
|
|
9
|
+
{% block methods %}
|
|
10
|
+
{%- if methods %}
|
|
11
|
+
.. rubric:: {{ _('Methods') }}
|
|
12
|
+
|
|
13
|
+
.. autosummary::
|
|
14
|
+
:nosignatures:
|
|
15
|
+
{% for item in methods if item != '__init__' and item not in inherited_members %}
|
|
16
|
+
~{{ name }}.{{ item }}
|
|
17
|
+
{%- endfor %}
|
|
18
|
+
{%- endif %}
|
|
19
|
+
{%- endblock %}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{{ fullname | escape | underline }}
|
|
2
|
+
|
|
3
|
+
.. currentmodule:: {{ fullname }}
|
|
4
|
+
|
|
5
|
+
.. automodule:: {{ fullname }}
|
|
6
|
+
|
|
7
|
+
{% block attributes %}
|
|
8
|
+
{% if attributes %}
|
|
9
|
+
.. rubric:: Module Attributes
|
|
10
|
+
|
|
11
|
+
.. autosummary::
|
|
12
|
+
{% for item in attributes %}
|
|
13
|
+
{{ item }}
|
|
14
|
+
{%- endfor %}
|
|
15
|
+
{% endif %}
|
|
16
|
+
{% endblock %}
|
|
17
|
+
|
|
18
|
+
{% block classes %}
|
|
19
|
+
{% if classes %}
|
|
20
|
+
.. rubric:: Classes
|
|
21
|
+
|
|
22
|
+
.. autosummary::
|
|
23
|
+
:toctree: .
|
|
24
|
+
:nosignatures:
|
|
25
|
+
{% for class in classes %}
|
|
26
|
+
{{ class }}
|
|
27
|
+
{% endfor %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
{% endblock %}
|
|
30
|
+
|
|
31
|
+
{% block functions %}
|
|
32
|
+
{% if functions %}
|
|
33
|
+
.. rubric:: {{ _('Functions') }}
|
|
34
|
+
|
|
35
|
+
{% for item in functions %}
|
|
36
|
+
.. autofunction:: {{ item }}
|
|
37
|
+
{%- endfor %}
|
|
38
|
+
{% endif %}
|
|
39
|
+
{% endblock %}
|
|
40
|
+
|
|
41
|
+
{% block exceptions %}
|
|
42
|
+
{% if exceptions %}
|
|
43
|
+
.. rubric:: {{ _('Exceptions') }}
|
|
44
|
+
|
|
45
|
+
.. autosummary::
|
|
46
|
+
{% for item in exceptions %}
|
|
47
|
+
{{ item }}
|
|
48
|
+
{%- endfor %}
|
|
49
|
+
{% endif %}
|
|
50
|
+
{% endblock %}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Configuration file for the Sphinx documentation builder.
|
|
3
|
+
#
|
|
4
|
+
# This file only contains a selection of the most common options. For a full
|
|
5
|
+
# list see the documentation:
|
|
6
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
7
|
+
|
|
8
|
+
# -- Path setup --------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
# If extensions (or modules to document with autodoc) are in another directory,
|
|
11
|
+
# add these directories to sys.path here. If the directory is relative to the
|
|
12
|
+
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
13
|
+
#
|
|
14
|
+
# import os
|
|
15
|
+
# import sys
|
|
16
|
+
# sys.path.insert(0, os.path.abspath(".."))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
# -- Project information -----------------------------------------------------
|
|
22
|
+
from pkg_resources import get_distribution
|
|
23
|
+
|
|
24
|
+
project = "ManimPango"
|
|
25
|
+
copyright = "2021, The Manim Community Dev Team"
|
|
26
|
+
author = "The Manim Community Dev Team"
|
|
27
|
+
|
|
28
|
+
release = get_distribution("ManimPango").version
|
|
29
|
+
version = ".".join(release.split(".")[:2])
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# -- General configuration ---------------------------------------------------
|
|
33
|
+
|
|
34
|
+
# Add any Sphinx extension module names here, as strings. They can be
|
|
35
|
+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
36
|
+
# ones.
|
|
37
|
+
extensions = [
|
|
38
|
+
"sphinx.ext.autodoc",
|
|
39
|
+
"sphinx.ext.napoleon",
|
|
40
|
+
"sphinx.ext.autosummary",
|
|
41
|
+
"sphinx.ext.doctest",
|
|
42
|
+
"sphinx.ext.extlinks",
|
|
43
|
+
"sphinx.ext.intersphinx",
|
|
44
|
+
"sphinxext.opengraph",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
# Add any paths that contain templates here, relative to this directory.
|
|
48
|
+
templates_path = ["_templates"]
|
|
49
|
+
|
|
50
|
+
# List of patterns, relative to source directory, that match files and
|
|
51
|
+
# directories to ignore when looking for source files.
|
|
52
|
+
# This pattern also affects html_static_path and html_extra_path.
|
|
53
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# -- Options for HTML output -------------------------------------------------
|
|
57
|
+
|
|
58
|
+
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
59
|
+
# a list of builtin themes.
|
|
60
|
+
#
|
|
61
|
+
html_theme = "furo"
|
|
62
|
+
|
|
63
|
+
# Add any paths that contain custom static files (such as style sheets) here,
|
|
64
|
+
# relative to this directory. They are copied after the builtin static files,
|
|
65
|
+
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
66
|
+
html_static_path = ["_static"]
|
|
67
|
+
html_favicon = str(Path("_static/favicon.ico"))
|
|
68
|
+
autosummary_generate = True
|
|
69
|
+
|
|
70
|
+
# generate documentation from type hints
|
|
71
|
+
autodoc_typehints = "description"
|
|
72
|
+
autoclass_content = "both"
|
|
73
|
+
|
|
74
|
+
# controls whether functions documented by the autofunction directive
|
|
75
|
+
# appear with their full module names
|
|
76
|
+
add_module_names = False
|
|
77
|
+
|
|
78
|
+
intersphinx_mapping = {
|
|
79
|
+
"manim": ("https://docs.manim.community/en/v0.2.0", None),
|
|
80
|
+
"python": ("https://docs.python.org/3", None),
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
ogp_image = "https://www.manim.community/logo.png"
|
|
84
|
+
ogp_site_name = "Manim Pango | Documentation"
|
|
85
|
+
ogp_site_url = "https://manimpango.manim.community/"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@ECHO OFF
|
|
2
|
+
|
|
3
|
+
pushd %~dp0
|
|
4
|
+
|
|
5
|
+
REM Command file for Sphinx documentation
|
|
6
|
+
|
|
7
|
+
if "%SPHINXBUILD%" == "" (
|
|
8
|
+
set SPHINXBUILD=sphinx-build
|
|
9
|
+
)
|
|
10
|
+
set SOURCEDIR=.
|
|
11
|
+
set BUILDDIR=_build
|
|
12
|
+
|
|
13
|
+
if "%1" == "" goto help
|
|
14
|
+
|
|
15
|
+
%SPHINXBUILD% >NUL 2>NUL
|
|
16
|
+
if errorlevel 9009 (
|
|
17
|
+
echo.
|
|
18
|
+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
|
19
|
+
echo.installed, then set the SPHINXBUILD environment variable to point
|
|
20
|
+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
|
21
|
+
echo.may add the Sphinx directory to PATH.
|
|
22
|
+
echo.
|
|
23
|
+
echo.If you don't have Sphinx installed, grab it from
|
|
24
|
+
echo.http://sphinx-doc.org/
|
|
25
|
+
exit /b 1
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
29
|
+
goto end
|
|
30
|
+
|
|
31
|
+
:help
|
|
32
|
+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
33
|
+
|
|
34
|
+
:end
|
|
35
|
+
popd
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Manimpango Reference
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
.. autosummary::
|
|
5
|
+
:toctree: reference
|
|
6
|
+
|
|
7
|
+
manimpango.TextSetting
|
|
8
|
+
manimpango.PangoUtils
|
|
9
|
+
manimpango.text2svg
|
|
10
|
+
manimpango.MarkupUtils
|
|
11
|
+
manimpango.register_font
|
|
12
|
+
manimpango.unregister_font
|
|
13
|
+
manimpango.list_fonts
|
|
14
|
+
|
|
15
|
+
Enums
|
|
16
|
+
=====
|
|
17
|
+
.. autosummary::
|
|
18
|
+
:toctree: reference
|
|
19
|
+
|
|
20
|
+
manimpango.Style
|
|
21
|
+
manimpango.Weight
|
|
22
|
+
manimpango.Variant
|
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
|
|
4
4
|
from ._version import __version__ # noqa: F403,F401
|
|
5
5
|
|
|
6
|
-
if os.name == "nt":
|
|
6
|
+
if os.name == "nt": # pragma: no cover
|
|
7
7
|
os.environ["PATH"] = (
|
|
8
8
|
f"{os.path.abspath(os.path.dirname(__file__))}"
|
|
9
9
|
f"{os.pathsep}"
|
|
@@ -13,5 +13,5 @@ try:
|
|
|
13
13
|
from .cmanimpango import * # noqa: F403,F401
|
|
14
14
|
from .enums import * # noqa: F403,F401
|
|
15
15
|
from .register_font import * # noqa: F403,F401
|
|
16
|
-
except ImportError:
|
|
16
|
+
except ImportError: # pragma: no cover
|
|
17
17
|
raise ImportError("Couldn't load the necessary Shared Libraries.")
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
__version__ = "0.2.
|
|
2
|
+
__version__ = "0.2.5"
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from xml.sax.saxutils import escape
|
|
2
2
|
from .utils import *
|
|
3
|
+
from .enums import Alignment
|
|
4
|
+
import warnings
|
|
3
5
|
|
|
4
6
|
class TextSetting:
|
|
5
7
|
"""Formatting for slices of a :class:`manim.mobject.svg.text_mobject.Text` object."""
|
|
@@ -138,13 +140,18 @@ class MarkupUtils:
|
|
|
138
140
|
slant: str,
|
|
139
141
|
weight: str,
|
|
140
142
|
size: int,
|
|
141
|
-
|
|
143
|
+
_: int, # for some there was a keyword here.
|
|
142
144
|
disable_liga: bool,
|
|
143
145
|
file_name: str,
|
|
144
146
|
START_X: int,
|
|
145
147
|
START_Y: int,
|
|
146
148
|
width: int,
|
|
147
149
|
height: int,
|
|
150
|
+
*, # keyword only arguments below
|
|
151
|
+
justify: bool = None,
|
|
152
|
+
indent: float = None,
|
|
153
|
+
line_spacing: float = None,
|
|
154
|
+
alignment: Alignment = None
|
|
148
155
|
) -> int:
|
|
149
156
|
"""Render an SVG file from a :class:`manim.mobject.svg.text_mobject.MarkupText` object."""
|
|
150
157
|
cdef cairo_surface_t* surface
|
|
@@ -152,8 +159,9 @@ class MarkupUtils:
|
|
|
152
159
|
cdef PangoFontDescription* font_desc
|
|
153
160
|
cdef PangoLayout* layout
|
|
154
161
|
cdef cairo_status_t status
|
|
155
|
-
cdef double width_layout = width
|
|
162
|
+
cdef double width_layout = width - 50
|
|
156
163
|
cdef double font_size = size
|
|
164
|
+
cdef int temp_int # a temporary C integer for conversion
|
|
157
165
|
|
|
158
166
|
file_name_bytes = file_name.encode("utf-8")
|
|
159
167
|
|
|
@@ -182,8 +190,32 @@ class MarkupUtils:
|
|
|
182
190
|
cairo_destroy(context)
|
|
183
191
|
cairo_surface_destroy(surface)
|
|
184
192
|
raise MemoryError("Pango.Layout can't be created from Cairo Context.")
|
|
193
|
+
|
|
185
194
|
pango_layout_set_width(layout, pango_units_from_double(width_layout))
|
|
186
195
|
|
|
196
|
+
if justify:
|
|
197
|
+
pango_layout_set_justify(layout, justify)
|
|
198
|
+
|
|
199
|
+
if indent:
|
|
200
|
+
temp_int = pango_units_from_double(indent)
|
|
201
|
+
pango_layout_set_indent(layout, temp_int)
|
|
202
|
+
|
|
203
|
+
if line_spacing:
|
|
204
|
+
# Typical values are: 0, 1, 1.5, 2.
|
|
205
|
+
ret = set_line_width(layout, line_spacing)
|
|
206
|
+
if not ret:
|
|
207
|
+
# warn that line spacing don't work
|
|
208
|
+
# because of old Pango version they
|
|
209
|
+
# have
|
|
210
|
+
warnings.warn(
|
|
211
|
+
"Pango Version<1.44 found."
|
|
212
|
+
"Impossible to set line_spacing."
|
|
213
|
+
"Expect Ugly Output."
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
if alignment:
|
|
217
|
+
pango_layout_set_alignment(layout, alignment.value)
|
|
218
|
+
|
|
187
219
|
font_desc = pango_font_description_new()
|
|
188
220
|
if font_desc==NULL:
|
|
189
221
|
cairo_destroy(context)
|
|
@@ -90,3 +90,21 @@ class Variant(Enum):
|
|
|
90
90
|
"""
|
|
91
91
|
NORMAL = PANGO_VARIANT_NORMAL
|
|
92
92
|
SMALL_CAPS = PANGO_VARIANT_SMALL_CAPS
|
|
93
|
+
|
|
94
|
+
class Alignment(Enum):
|
|
95
|
+
"""
|
|
96
|
+
An enumeration specifying alignment.
|
|
97
|
+
|
|
98
|
+
Attributes
|
|
99
|
+
----------
|
|
100
|
+
|
|
101
|
+
NORMAL :
|
|
102
|
+
A normal font.
|
|
103
|
+
|
|
104
|
+
SMALL_CAPS :
|
|
105
|
+
A font with the lower case characters replaced by smaller variants
|
|
106
|
+
of the capital characters.
|
|
107
|
+
"""
|
|
108
|
+
LEFT = PANGO_ALIGN_LEFT
|
|
109
|
+
CENTER = PANGO_ALIGN_CENTER
|
|
110
|
+
RIGHT = PANGO_ALIGN_RIGHT
|
|
@@ -37,6 +37,10 @@ cdef extern from "pango/pangocairo.h":
|
|
|
37
37
|
PANGO_WRAP_WORD
|
|
38
38
|
PANGO_WRAP_CHAR
|
|
39
39
|
PANGO_WRAP_WORD_CHAR
|
|
40
|
+
ctypedef enum PangoAlignment:
|
|
41
|
+
PANGO_ALIGN_LEFT
|
|
42
|
+
PANGO_ALIGN_CENTER
|
|
43
|
+
PANGO_ALIGN_RIGHT
|
|
40
44
|
PangoLayout* pango_cairo_create_layout(cairo_t* cr)
|
|
41
45
|
void pango_cairo_show_layout(
|
|
42
46
|
cairo_t* cr,
|
|
@@ -121,3 +125,34 @@ cdef extern from "pango/pangocairo.h":
|
|
|
121
125
|
const char* pango_font_family_get_name(
|
|
122
126
|
PangoFontFamily *family
|
|
123
127
|
)
|
|
128
|
+
void pango_layout_set_justify(
|
|
129
|
+
PangoLayout *layout,
|
|
130
|
+
gboolean justify
|
|
131
|
+
)
|
|
132
|
+
void pango_layout_set_indent(
|
|
133
|
+
PangoLayout *layout,
|
|
134
|
+
int indent
|
|
135
|
+
)
|
|
136
|
+
void pango_layout_set_alignment(
|
|
137
|
+
PangoLayout *layout,
|
|
138
|
+
PangoAlignment alignment
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
cdef extern from *:
|
|
142
|
+
"""
|
|
143
|
+
#if PANGO_VERSION_CHECK(1,44,0)
|
|
144
|
+
int set_line_width(PangoLayout *layout,float spacing)
|
|
145
|
+
{
|
|
146
|
+
pango_layout_set_line_spacing(layout, spacing);
|
|
147
|
+
return 1;
|
|
148
|
+
}
|
|
149
|
+
#else
|
|
150
|
+
int set_line_width(PangoLayout *layout,float spacing){return 0;}
|
|
151
|
+
#endif
|
|
152
|
+
"""
|
|
153
|
+
# The above docs string is C which is used to
|
|
154
|
+
# check for the Pango Version there at run time.
|
|
155
|
+
# pango_layout_set_line_spacing is only avaiable only for
|
|
156
|
+
# pango>=1.44.0 but we support pango>=1.30.0 that why this
|
|
157
|
+
# conditionals.
|
|
158
|
+
bint set_line_width(PangoLayout *layout,float spacing)
|
|
@@ -19,6 +19,11 @@ try:
|
|
|
19
19
|
except ImportError:
|
|
20
20
|
USE_CYTHON = False
|
|
21
21
|
|
|
22
|
+
coverage = False
|
|
23
|
+
if sys.argv[-1] == "--coverage":
|
|
24
|
+
coverage = True
|
|
25
|
+
sys.argv.pop()
|
|
26
|
+
|
|
22
27
|
|
|
23
28
|
def get_version():
|
|
24
29
|
version_file = "manimpango/_version.py"
|
|
@@ -166,7 +171,6 @@ class PKG_CONFIG:
|
|
|
166
171
|
known_cflags, unknown_cflags = self.parse_cflags(raw_cflags.decode("utf8"))
|
|
167
172
|
if unknown_cflags:
|
|
168
173
|
known_cflags["extra_compile_args"] = unknown_cflags.split()
|
|
169
|
-
# return update_dict(known_cflags, known_libs)
|
|
170
174
|
return known_cflags
|
|
171
175
|
return dict()
|
|
172
176
|
|
|
@@ -197,6 +201,9 @@ if sys.platform == "win32":
|
|
|
197
201
|
returns["define_macros"] += [("UNICODE", 1)]
|
|
198
202
|
else:
|
|
199
203
|
returns["define_macros"] = [("UNICODE", 1)]
|
|
204
|
+
if coverage:
|
|
205
|
+
returns["define_macros"] += [("CYTHON_TRACE", 1)]
|
|
206
|
+
returns["define_macros"] += [("CYTHON_TRACE_NOGIL", 1)]
|
|
200
207
|
|
|
201
208
|
ext_modules = [
|
|
202
209
|
Extension(
|
|
@@ -221,6 +228,7 @@ if USE_CYTHON:
|
|
|
221
228
|
language_level=3,
|
|
222
229
|
include_path=["manimpango"],
|
|
223
230
|
gdb_debug=DEBUG,
|
|
231
|
+
compiler_directives={"linetrace": coverage},
|
|
224
232
|
)
|
|
225
233
|
with open("README.md") as fh:
|
|
226
234
|
long_description = fh.read()
|
|
@@ -259,6 +267,6 @@ setup(
|
|
|
259
267
|
},
|
|
260
268
|
ext_modules=ext_modules,
|
|
261
269
|
package_data={
|
|
262
|
-
"manimpango": ["*.pxd"],
|
|
270
|
+
"manimpango": ["*.pxd", "*.pyx"],
|
|
263
271
|
},
|
|
264
272
|
)
|
|
@@ -29,3 +29,13 @@ def delete_media_dir():
|
|
|
29
29
|
|
|
30
30
|
set_dll_search_path()
|
|
31
31
|
delete_media_dir()
|
|
32
|
+
CASES_DIR = Path(Path(__file__).parent, "cases").absolute()
|
|
33
|
+
FONT_DIR = Path(__file__).parent / "fonts"
|
|
34
|
+
|
|
35
|
+
import manimpango # noqa: E402
|
|
36
|
+
|
|
37
|
+
font = str((FONT_DIR / "BungeeOutline-Regular.ttf").absolute())
|
|
38
|
+
orig = manimpango.list_fonts()
|
|
39
|
+
assert manimpango.register_font(font)
|
|
40
|
+
final = manimpango.list_fonts()
|
|
41
|
+
main_font = list(set(final) - set(orig))[0]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""This file contains helpers for the tests copied and modified
|
|
3
|
+
from Manim.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from manimpango import Alignment, MarkupUtils
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MarkupText:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
text: str,
|
|
16
|
+
*,
|
|
17
|
+
size: int = 1,
|
|
18
|
+
line_spacing: int = None,
|
|
19
|
+
font: str = None,
|
|
20
|
+
slant: str = "NORMAL",
|
|
21
|
+
weight: str = "NORMAL",
|
|
22
|
+
tab_width: int = 4,
|
|
23
|
+
disable_ligatures: bool = False,
|
|
24
|
+
justify: bool = None,
|
|
25
|
+
indent: float = None,
|
|
26
|
+
alignment: Alignment = None,
|
|
27
|
+
# for the tests
|
|
28
|
+
filename: str = "test.svg",
|
|
29
|
+
**kwargs,
|
|
30
|
+
):
|
|
31
|
+
self.text = text
|
|
32
|
+
self.size = size
|
|
33
|
+
self.line_spacing = line_spacing
|
|
34
|
+
self.font = font
|
|
35
|
+
self.slant = slant
|
|
36
|
+
self.weight = weight
|
|
37
|
+
self.tab_width = tab_width
|
|
38
|
+
self.filename = filename
|
|
39
|
+
self.original_text = text
|
|
40
|
+
self.disable_ligatures = disable_ligatures
|
|
41
|
+
|
|
42
|
+
self.justify = justify
|
|
43
|
+
self.indent = indent
|
|
44
|
+
self.alignment = alignment
|
|
45
|
+
if not MarkupUtils.validate(self.text):
|
|
46
|
+
raise ValueError(
|
|
47
|
+
f"Pango cannot parse your markup in {self.text}. "
|
|
48
|
+
"Please check for typos, unmatched tags or unescaped "
|
|
49
|
+
"special chars like < and &."
|
|
50
|
+
)
|
|
51
|
+
self.text2svg()
|
|
52
|
+
|
|
53
|
+
def text2svg(self):
|
|
54
|
+
"""Convert the text to SVG using Pango."""
|
|
55
|
+
size = self.size * 10
|
|
56
|
+
dir_name = Path(self.filename).parent
|
|
57
|
+
disable_liga = self.disable_ligatures
|
|
58
|
+
if not os.path.exists(dir_name):
|
|
59
|
+
os.makedirs(dir_name)
|
|
60
|
+
file_name = self.filename
|
|
61
|
+
return MarkupUtils.text2svg(
|
|
62
|
+
f"{self.text}",
|
|
63
|
+
self.font,
|
|
64
|
+
self.slant,
|
|
65
|
+
self.weight,
|
|
66
|
+
size,
|
|
67
|
+
True, # stray positional argument
|
|
68
|
+
disable_liga,
|
|
69
|
+
file_name,
|
|
70
|
+
20,
|
|
71
|
+
20,
|
|
72
|
+
600, # width
|
|
73
|
+
400, # height
|
|
74
|
+
justify=self.justify,
|
|
75
|
+
indent=self.indent,
|
|
76
|
+
line_spacing=self.line_spacing,
|
|
77
|
+
alignment=self.alignment,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
def __repr__(self):
|
|
81
|
+
return f"MarkupText({repr(self.original_text)})"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
NotoNastaliqUrdu-Regular.ttf from https://github.com/googlei18n/noto-fonts
|
|
2
|
+
BungeeColor-Regular_colr_Windows.ttf, from https://github.com/djrrb/bungee
|
|
3
|
+
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
|
4
|
+
BungeeOutline-Regular.ttf, from https://fonts.google.com/specimen/Bungee+Outline
|
|
5
|
+
|
|
6
|
+
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
|
|
Binary file
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Dict
|
|
4
|
+
from xml.parsers.expat import ParserCreate
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SVGUtils:
|
|
8
|
+
SVG_DEFAULT_ATTRIBUTES: Dict[str, str] = {
|
|
9
|
+
"fill": "black",
|
|
10
|
+
"fill-opacity": "1",
|
|
11
|
+
"stroke": "none",
|
|
12
|
+
"stroke-opacity": "1",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
def __init__(self) -> None:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
def parse_color_string(self, color_spec: str) -> str:
|
|
19
|
+
# copied from Manim's SVG parser.
|
|
20
|
+
if color_spec[0:3] == "rgb":
|
|
21
|
+
# these are only in integer form,
|
|
22
|
+
# but the Colour module wants them in floats.
|
|
23
|
+
splits = color_spec[4:-1].split(",")
|
|
24
|
+
if splits[0][-1] == "%":
|
|
25
|
+
# if the last character of the first number is a percentage,
|
|
26
|
+
# then interpret the number as a percentage
|
|
27
|
+
parsed_rgbs = [float(i[:-1]) / 100.0 for i in splits]
|
|
28
|
+
else:
|
|
29
|
+
parsed_rgbs = [int(i) / 255.0 for i in splits]
|
|
30
|
+
|
|
31
|
+
# hex_color = rgb_to_hex(parsed_rgbs)
|
|
32
|
+
|
|
33
|
+
else:
|
|
34
|
+
# not necessary for web2hex case and hex
|
|
35
|
+
raise NotImplementedError
|
|
36
|
+
|
|
37
|
+
return parsed_rgbs
|
|
38
|
+
|
|
39
|
+
def str2styledict(self, style_specs: str) -> Dict[str, str]:
|
|
40
|
+
# helper for parse style
|
|
41
|
+
# copied from manim's svg parser.
|
|
42
|
+
style = {}
|
|
43
|
+
|
|
44
|
+
# the style attribute should be handled separately in order to
|
|
45
|
+
# break it up nicely. furthermore, style takes priority over other
|
|
46
|
+
# attributes in the same element.
|
|
47
|
+
if style_specs:
|
|
48
|
+
for style_spec in style_specs.split(";"):
|
|
49
|
+
try:
|
|
50
|
+
key, value = style_spec.split(":")
|
|
51
|
+
except ValueError as e:
|
|
52
|
+
if not style_spec:
|
|
53
|
+
# there was just a stray semicolon
|
|
54
|
+
# at the end, producing an
|
|
55
|
+
# emptystring
|
|
56
|
+
pass
|
|
57
|
+
else:
|
|
58
|
+
raise e
|
|
59
|
+
else:
|
|
60
|
+
style[key] = value
|
|
61
|
+
|
|
62
|
+
return style
|
|
63
|
+
|
|
64
|
+
def parse_style(self, stylestr: str) -> Dict:
|
|
65
|
+
# Originally written by @MrMallIronmaker
|
|
66
|
+
# Copied from Manim.
|
|
67
|
+
# https://github.com/ManimCommunity/manim/
|
|
68
|
+
# blob/aa873e0f8e5c4f35c864568213b04b88af5b4769/manim/mobject/svg/style_utils.py#L143
|
|
69
|
+
SVG_DEFAULT_ATTRIBUTES = self.SVG_DEFAULT_ATTRIBUTES
|
|
70
|
+
manim_style = {}
|
|
71
|
+
svg_style = self.str2styledict(stylestr)
|
|
72
|
+
for key in SVG_DEFAULT_ATTRIBUTES:
|
|
73
|
+
if key not in svg_style:
|
|
74
|
+
svg_style[key] = SVG_DEFAULT_ATTRIBUTES[key]
|
|
75
|
+
|
|
76
|
+
if "fill-opacity" in svg_style:
|
|
77
|
+
manim_style["fill_opacity"] = float(svg_style["fill-opacity"])
|
|
78
|
+
|
|
79
|
+
if "stroke-opacity" in svg_style:
|
|
80
|
+
manim_style["stroke_opacity"] = float(svg_style["stroke-opacity"])
|
|
81
|
+
|
|
82
|
+
# nones need to be handled specially
|
|
83
|
+
if "fill" in svg_style:
|
|
84
|
+
if svg_style["fill"] == "none":
|
|
85
|
+
manim_style["fill_opacity"] = 0
|
|
86
|
+
else:
|
|
87
|
+
manim_style["fill_color"] = self.parse_color_string(svg_style["fill"])
|
|
88
|
+
|
|
89
|
+
if "stroke" in svg_style:
|
|
90
|
+
if svg_style["stroke"] == "none":
|
|
91
|
+
# In order to not break animations.creation.Write,
|
|
92
|
+
# we interpret no stroke as stroke-width of zero and
|
|
93
|
+
# color the same as the fill color, if it exists.
|
|
94
|
+
manim_style["stroke_width"] = 0
|
|
95
|
+
if "fill_color" in manim_style:
|
|
96
|
+
manim_style["stroke_color"] = manim_style["fill_color"]
|
|
97
|
+
else:
|
|
98
|
+
manim_style["stroke_color"] = self.parse_color_string(
|
|
99
|
+
svg_style["stroke"]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return manim_style
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class SVGStyleTester(SVGUtils):
|
|
106
|
+
def __init__(self, gotSVG: Path, expectedSVG: Path) -> None:
|
|
107
|
+
self.expected_file = expectedSVG
|
|
108
|
+
self.got_file = gotSVG
|
|
109
|
+
self.prepare()
|
|
110
|
+
|
|
111
|
+
def get_handler(self, final_setter):
|
|
112
|
+
def func(name, attrs):
|
|
113
|
+
styles = []
|
|
114
|
+
if name == "g":
|
|
115
|
+
if "style" in attrs:
|
|
116
|
+
styles.append(self.parse_style(attrs["style"]))
|
|
117
|
+
if styles:
|
|
118
|
+
# need to think of better way than this.
|
|
119
|
+
exec(f"self.{final_setter} += [styles]")
|
|
120
|
+
|
|
121
|
+
return func
|
|
122
|
+
|
|
123
|
+
def prepare(self):
|
|
124
|
+
self.got_svg_style = []
|
|
125
|
+
self.expected_svg_style = []
|
|
126
|
+
got_parser = ParserCreate()
|
|
127
|
+
got_parser.StartElementHandler = self.get_handler("got_svg_style")
|
|
128
|
+
with open(self.got_file, "rb") as f:
|
|
129
|
+
got_parser.ParseFile(f)
|
|
130
|
+
|
|
131
|
+
expected_parser = ParserCreate()
|
|
132
|
+
expected_parser.StartElementHandler = self.get_handler("expected_svg_style")
|
|
133
|
+
with open(self.expected_file, "rb") as f:
|
|
134
|
+
expected_parser.ParseFile(f)
|
|
@@ -8,7 +8,9 @@ import pytest
|
|
|
8
8
|
|
|
9
9
|
import manimpango
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
from . import FONT_DIR, main_font
|
|
12
|
+
from ._manim import MarkupText
|
|
13
|
+
|
|
12
14
|
font_lists = {
|
|
13
15
|
(FONT_DIR / "AdobeVFPrototype.ttf").absolute(): "Adobe Variable Font Prototype",
|
|
14
16
|
(
|
|
@@ -76,4 +78,20 @@ def test_fail_just_unregister():
|
|
|
76
78
|
)
|
|
77
79
|
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="unsupported api for mac")
|
|
78
80
|
def test_unregister_linux():
|
|
79
|
-
manimpango.unregister_font("random")
|
|
81
|
+
assert manimpango.unregister_font("random")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@pytest.mark.skipif(
|
|
85
|
+
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
86
|
+
)
|
|
87
|
+
def test_adding_dummy_font(tmpdir):
|
|
88
|
+
dummy = tmpdir / "font.ttf"
|
|
89
|
+
with open(dummy, "wb") as f:
|
|
90
|
+
f.write(b"dummy")
|
|
91
|
+
assert not manimpango.register_font(str(dummy)), "Registered a dummy font?"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_fonts_render(tmpdir):
|
|
95
|
+
filename = str(Path(tmpdir) / "hello.svg")
|
|
96
|
+
MarkupText("Hello World", font=main_font, filename=filename)
|
|
97
|
+
assert Path(filename).exists()
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import manimpango
|
|
5
|
+
|
|
6
|
+
from . import CASES_DIR
|
|
7
|
+
from ._manim import MarkupText
|
|
8
|
+
from .svg_tester import SVGStyleTester
|
|
9
|
+
|
|
10
|
+
ipsum_text = (
|
|
11
|
+
"<b>Lorem ipsum dolor</b> sit amet, <i>consectetur</i> adipiscing elit,"
|
|
12
|
+
"sed do eiusmod tempor incididunt ut labore et dolore"
|
|
13
|
+
"magna aliqua. Ut enim <b>ad</b> minim veniam, quis nostrud"
|
|
14
|
+
"exercitation ullamco laboris nisi ut aliquip"
|
|
15
|
+
"ex ea commodo consequat. Duis aute irure dolor"
|
|
16
|
+
"in reprehenderit in voluptate velit esse cillum"
|
|
17
|
+
"dolore eu fugiat nulla pariatur. Excepteur sint"
|
|
18
|
+
"occaecat cupidatat non proident, sunt in culpa qui"
|
|
19
|
+
"officia deserunt mollit anim id est laborum."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_good_markup():
|
|
24
|
+
|
|
25
|
+
assert manimpango.MarkupUtils.validate(
|
|
26
|
+
"foo",
|
|
27
|
+
), '"foo" should not fail validation'
|
|
28
|
+
assert manimpango.MarkupUtils.validate(
|
|
29
|
+
"<b>bar</b>"
|
|
30
|
+
), '"<b>bar</b>" should not fail validation'
|
|
31
|
+
assert manimpango.MarkupUtils.validate(
|
|
32
|
+
"வணக்கம்",
|
|
33
|
+
), '"வணக்கம்" should not fail'
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_bad_markup():
|
|
37
|
+
|
|
38
|
+
assert not manimpango.MarkupUtils.validate(
|
|
39
|
+
"<b>foo"
|
|
40
|
+
), '"<b>foo" should fail validation (unbalanced tags)'
|
|
41
|
+
assert not manimpango.MarkupUtils.validate(
|
|
42
|
+
"<xyz>foo</xyz>"
|
|
43
|
+
), '"<xyz>foo</xyz>" should fail validation (invalid tag)'
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_markup_text(tmpdir):
|
|
47
|
+
loc = Path(tmpdir, "test.svg")
|
|
48
|
+
assert not loc.exists()
|
|
49
|
+
MarkupText(
|
|
50
|
+
'<span underline="error"><b><i>Hello Manim</i></b></span>', filename=str(loc)
|
|
51
|
+
)
|
|
52
|
+
assert loc.exists()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_markup_justify(tmpdir):
|
|
56
|
+
# don't know how to verify this correctly
|
|
57
|
+
# it varies upon diffent system so, we are
|
|
58
|
+
# just check whether it runs
|
|
59
|
+
loc = Path(tmpdir, "test.svg")
|
|
60
|
+
assert not loc.exists()
|
|
61
|
+
MarkupText(ipsum_text, justify=True, filename=str(loc))
|
|
62
|
+
assert loc.exists()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_markup_indent(tmpdir):
|
|
66
|
+
# don't know how to verify this correctly
|
|
67
|
+
# it varies upon diffent system so, we are
|
|
68
|
+
# just check whether it runs
|
|
69
|
+
loc = Path(tmpdir, "test.svg")
|
|
70
|
+
assert not loc.exists()
|
|
71
|
+
MarkupText(ipsum_text, indent=10, filename=str(loc))
|
|
72
|
+
assert loc.exists()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_markup_alignment(tmpdir):
|
|
76
|
+
# don't know how to verify this correctly
|
|
77
|
+
# it varies upon diffent system so, we are
|
|
78
|
+
# just check whether it runs
|
|
79
|
+
loc = Path(tmpdir, "test.svg")
|
|
80
|
+
assert not loc.exists()
|
|
81
|
+
MarkupText(
|
|
82
|
+
ipsum_text,
|
|
83
|
+
alignment=manimpango.Alignment.CENTER,
|
|
84
|
+
filename=str(loc),
|
|
85
|
+
)
|
|
86
|
+
assert loc.exists()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_markup_style(tmpdir):
|
|
90
|
+
test_case = CASES_DIR / "hello_blue_world_green.svg"
|
|
91
|
+
expected = tmpdir / "expected.svg"
|
|
92
|
+
text = "<span foreground='BLUE'>Hello</span>\n<span foreground='GREEN'>World</span>"
|
|
93
|
+
MarkupText(
|
|
94
|
+
text,
|
|
95
|
+
filename=str(expected),
|
|
96
|
+
)
|
|
97
|
+
s = SVGStyleTester(gotSVG=expected, expectedSVG=test_case)
|
|
98
|
+
assert len(s.got_svg_style) == len(s.expected_svg_style)
|
|
99
|
+
assert s.got_svg_style == s.expected_svg_style
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from manimpango.enums import Style, Weight
|
|
5
|
+
from manimpango.utils import PangoUtils
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_str2style():
|
|
9
|
+
p = PangoUtils()
|
|
10
|
+
|
|
11
|
+
assert p.str2style("NORMAL") == Style.NORMAL
|
|
12
|
+
assert p.str2style("ITALIC") == Style.ITALIC
|
|
13
|
+
assert p.str2style("OBLIQUE") == Style.OBLIQUE
|
|
14
|
+
|
|
15
|
+
with pytest.raises(AttributeError) as exc_info:
|
|
16
|
+
p.str2style("DNE")
|
|
17
|
+
exception_raised = exc_info.value
|
|
18
|
+
assert "There is no Style Called DNE" == str(exception_raised)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_str2weight():
|
|
22
|
+
p = PangoUtils()
|
|
23
|
+
|
|
24
|
+
assert p.str2weight("NORMAL") == Weight.NORMAL
|
|
25
|
+
assert p.str2weight("BOLD") == Weight.BOLD
|
|
26
|
+
assert p.str2weight("THIN") == Weight.THIN
|
|
27
|
+
assert p.str2weight("THIN") == Weight.THIN
|
|
28
|
+
assert p.str2weight("ULTRALIGHT") == Weight.ULTRALIGHT
|
|
29
|
+
assert p.str2weight("LIGHT") == Weight.LIGHT
|
|
30
|
+
assert p.str2weight("BOOK") == Weight.BOOK
|
|
31
|
+
assert p.str2weight("MEDIUM") == Weight.MEDIUM
|
|
32
|
+
assert p.str2weight("SEMIBOLD") == Weight.SEMIBOLD
|
|
33
|
+
assert p.str2weight("ULTRABOLD") == Weight.ULTRABOLD
|
|
34
|
+
assert p.str2weight("HEAVY") == Weight.HEAVY
|
|
35
|
+
assert p.str2weight("ULTRAHEAVY") == Weight.ULTRAHEAVY
|
|
36
|
+
|
|
37
|
+
with pytest.raises(AttributeError) as exc_info:
|
|
38
|
+
p.str2weight("DNE")
|
|
39
|
+
exception_raised = exc_info.value
|
|
40
|
+
assert "There is no Font Weight Called DNE" == str(exception_raised)
|
ManimPango-0.2.4/MANIFEST.in
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
def test_good_markup():
|
|
3
|
-
import manimpango # noqa: F401
|
|
4
|
-
|
|
5
|
-
assert manimpango.MarkupUtils.validate(
|
|
6
|
-
"foo",
|
|
7
|
-
), '"foo" should not fail validation'
|
|
8
|
-
assert manimpango.MarkupUtils.validate(
|
|
9
|
-
"<b>bar</b>"
|
|
10
|
-
), '"<b>bar</b>" should not fail validation'
|
|
11
|
-
assert manimpango.MarkupUtils.validate(
|
|
12
|
-
"வணக்கம்",
|
|
13
|
-
), '"வணக்கம்" should not fail'
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def test_bad_markup():
|
|
17
|
-
import manimpango # noqa: F401
|
|
18
|
-
|
|
19
|
-
assert not manimpango.MarkupUtils.validate(
|
|
20
|
-
"<b>foo"
|
|
21
|
-
), '"<b>foo" should fail validation (unbalanced tags)'
|
|
22
|
-
assert not manimpango.MarkupUtils.validate(
|
|
23
|
-
"<xyz>foo</xyz>"
|
|
24
|
-
), '"<xyz>foo</xyz>" should fail validation (invalid tag)'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|