diff --git a/docker/Dockerfile b/docker/Dockerfile index d7ce166776..0d9d81c1fb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -26,9 +26,6 @@ COPY . /opt/manim WORKDIR /opt/manim RUN pip install --no-cache . -# ensure that ffi bindings are generated -RUN python -c "import pangocairocffi" - # create working directory for user to mount local directory into WORKDIR /manim RUN chmod 666 /manim diff --git a/docs/source/installation/mac.rst b/docs/source/installation/mac.rst index d39e633066..25064a4c19 100644 --- a/docs/source/installation/mac.rst +++ b/docs/source/installation/mac.rst @@ -15,16 +15,6 @@ To install cairo: brew install cairo -To install Pango and it dependencies: - -.. code-block:: bash - - brew install pkg-config - brew install libffi - brew install pango - brew install glib - - To install ffmpeg: .. code-block:: bash diff --git a/docs/source/installation/troubleshooting.rst b/docs/source/installation/troubleshooting.rst index 21917fa23f..f679909dd6 100644 --- a/docs/source/installation/troubleshooting.rst +++ b/docs/source/installation/troubleshooting.rst @@ -3,30 +3,28 @@ Troubleshooting List of known installation problems. -(Windows) OSError: dlopen() failed to load a library: pango? ------------------------------------------------------------- - -If your manual installation of Manim (or even the installation using -Chocolatey) fails with the error +``pip install manim`` fails when installing manimpango? +------------------------------------------------------- +Most likely this means that pip was not able to use our pre-built wheels +of ``manimpango``. Let us know (via our `Discord `_ +or by opening a +`new issue on GitHub `_) +which architecture you would like to see supported, and we'll see what we +can do about it. + +To fix errors when installing ``manimpango``, you need to make sure you +have all the necessary build requirements. Check out the detailed +instructions given in +`the BUILDING section `_ +of the corresponding `GitHub repository `_. -.. code-block:: - OSError: dlopen() failed to load a library: pango / pango-1 / pango-1.0 / pango-1.0-0 - -possibly combined with alerts warning about procedure entry points -``"deflateSetHeader"`` and ``"inflateReset2"`` that could not be -located, you might run into an issue with a patched version of ``zlib1.dll`` -shipped by Intel, `as described here `_. +(Windows) OSError: dlopen() failed to load a library: pango? +------------------------------------------------------------ -To resolve this issue, you can copy ``zlib1.dll`` from the directory -provided for the Pango binaries to the directory Manim is installed to. +This should be fixed in Manim's latest version, update +using ``pip install --upgrade manim``. -For a more global solution (try at your own risk!), try renaming the -file ``zlib1.dll`` located at ``C:\Program Files\Intel\Wifi\bin`` to -something like ``zlib1.dll.bak`` -- and then try installing Manim again -(either using ``pip install manim`` or with Chocolatey). Ensure that -you are able to revert this name change in case you run into troubles -with your WiFi (we did not get any reports about such a problem, however). Some letters are missing from TextMobject/TexMobject output? diff --git a/docs/source/installation/win.rst b/docs/source/installation/win.rst index f9d301d13b..30b8824d2f 100644 --- a/docs/source/installation/win.rst +++ b/docs/source/installation/win.rst @@ -18,32 +18,6 @@ You can install manim very easily using chocolatey, by typing the following comm And then you can skip all the other steps and move to installing :ref:`latex-installation`. Please see :doc:`troubleshooting` section for details about OSError. -Pango Installation -****************** - -These steps would get you `libpango-1.0-0.dll` to your ``PATH`` along -with other dependencies. You may probably have them before itself if -you have installed `GTK `_ or any ``GTK`` -based app like emacs. If you have it you can just add it to your -path and skip these steps. - -1. Go to `Release Page - `_ - and download the one according to your PC architechture. - - .. important:: Please download the ``zip`` file for architechture of python installed. - It is possible to have installed ``x86`` python installed on ``x64`` PC. - -2. Extract the zip file using File Explorer or 7z to the loaction you want to install. - - .. code-block:: bash - - 7z x pango-windows-binaires-x64.zip -oC:\Pango - -3. Finally, add it `PATH variable - `_. - - FFmpeg installation ******************* diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index bf1b1d2ff6..ed2e024dde 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -53,18 +53,15 @@ def construct(self): from xml.sax.saxutils import escape import cairo -import cairocffi -import pangocairocffi -import pangocffi +import manimpango +from manimpango import PangoUtils, TextSetting, MarkupUtils from ... import config, logger from ...constants import * from ...mobject.geometry import Dot from ...mobject.svg.svg_mobject import SVGMobject from ...mobject.types.vectorized_mobject import VGroup -from ...utils.color import WHITE -from ...utils.color import Colors - +from ...utils.color import WHITE, Colors TEXT_MOB_SCALE_FACTOR = 0.05 @@ -103,68 +100,6 @@ def remove_invisible_chars(mobject): return mobject_without_dots -class PangoUtils: - @staticmethod - def str2style(string: str) -> pangocffi.Style: - """Internally used function. Converts text to Pango Understandable Styles.""" - if string == NORMAL: - return pangocffi.Style.NORMAL - elif string == ITALIC: - return pangocffi.Style.ITALIC - elif string == OBLIQUE: - return pangocffi.Style.OBLIQUE - else: - raise AttributeError("There is no Style Called %s" % string) - - @staticmethod - def str2weight(string: str) -> pangocffi.Weight: - """Internally used function. Convert text to Pango Understandable Weight""" - if string == NORMAL: - return pangocffi.Weight.NORMAL - elif string == BOLD: - return pangocffi.Weight.BOLD - elif string == THIN: - return pangocffi.Weight.THIN - elif string == ULTRALIGHT: - return pangocffi.Weight.ULTRALIGHT - elif string == LIGHT: - return pangocffi.Weight.LIGHT - elif string == SEMILIGHT: - return pangocffi.Weight.SEMILIGHT - elif string == BOOK: - return pangocffi.Weight.BOOK - elif string == MEDIUM: - return pangocffi.Weight.MEDIUM - elif string == SEMIBOLD: - return pangocffi.Weight.SEMIBOLD - elif string == ULTRABOLD: - return pangocffi.Weight.ULTRABOLD - elif string == HEAVY: - return pangocffi.Weight.HEAVY - elif string == ULTRAHEAVY: - return pangocffi.Weight.ULTRAHEAVY - else: - raise AttributeError("There is no Font Weight Called %s" % string) - - @staticmethod - def remove_last_M(file_name: str) -> None: - with open(file_name, "r") as fpr: - content = fpr.read() - content = re.sub(r'Z M [^A-Za-z]*? "\/>', 'Z "/>', content) - with open(file_name, "w") as fpw: - fpw.write(content) - - -class TextSetting(object): - def __init__(self, start, end, font, slant, weight, line_num=-1): - self.start = start - self.end = end - self.font = font - self.slant = slant - self.weight = weight - self.line_num = line_num - - class CairoText(SVGMobject): """Display (non-LaTeX) text. @@ -448,7 +383,7 @@ def text2svg(self): offset_x = 0 last_line_num = 0 for setting in settings: - font = setting.font + font = setting.font.decode("utf-8") slant = self.str2slant(setting.slant) weight = self.str2weight(setting.weight) text = self.text[setting.start : setting.end].replace("\n", " ") @@ -1012,45 +947,22 @@ def text2svg(self): file_name = os.path.join(dir_name, hash_name) + ".svg" if os.path.exists(file_name): return file_name - surface = cairocffi.SVGSurface(file_name, 600, 400) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) settings = self.text2settings() - offset_x = 0 - last_line_num = 0 - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(600)) - for setting in settings: - family = setting.font - style = PangoUtils.str2style(setting.slant) - weight = PangoUtils.str2weight(setting.weight) - text = self.text[setting.start : setting.end].replace("\n", " ") - fontdesc = pangocffi.FontDescription() - fontdesc.set_size(pangocffi.units_from_double(size)) - if family: - fontdesc.set_family(family) - fontdesc.set_style(style) - fontdesc.set_weight(weight) - layout.set_font_description(fontdesc) - if setting.line_num != last_line_num: - offset_x = 0 - last_line_num = setting.line_num - context.move_to( - START_X + offset_x, START_Y + line_spacing * setting.line_num - ) - pangocairocffi.update_layout(context, layout) - if disable_liga: - text = escape(text) - layout.set_markup( - f"{text}" - ) - else: - layout.set_text(text) - logger.debug(f"Setting Text {text}") - pangocairocffi.show_layout(context, layout) - offset_x += pangocffi.units_to_double(layout.get_size()[0]) - surface.finish() - return file_name + width = 600 + height = 400 + + return manimpango.text2svg( + settings, + size, + line_spacing, + disable_liga, + file_name, + START_X, + START_Y, + width, + height, + self.text, + ) class MarkupText(SVGMobject): @@ -1360,32 +1272,22 @@ def text2svg(self): file_name = os.path.join(dir_name, hash_name) + ".svg" if os.path.exists(file_name): return file_name - surface = cairocffi.SVGSurface(file_name, 600, 400) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(600)) - - fontdesc = pangocffi.FontDescription() - fontdesc.set_size(pangocffi.units_from_double(size)) - if self.font: - fontdesc.set_family(self.font) - fontdesc.set_style(PangoUtils.str2style(self.slant)) - fontdesc.set_weight(PangoUtils.str2weight(self.weight)) - layout.set_font_description(fontdesc) - context.move_to(START_X, START_Y) - pangocairocffi.update_layout(context, layout) - if disable_liga: - layout.set_markup( - f"{self.text}" - ) - else: - layout.set_markup(self.text) logger.debug(f"Setting Text {self.text}") - pangocairocffi.show_layout(context, layout) - surface.finish() - return file_name + return MarkupUtils.text2svg( + self.text, + self.font, + self.slant, + self.weight, + size, + line_spacing, + disable_liga, + file_name, + START_X, + START_Y, + 600, # width + 400, # height + ) def _count_real_chars(self, s): """Counts characters that will be displayed. diff --git a/poetry.lock b/poetry.lock index fe77424bb4..c6342e9231 100644 --- a/poetry.lock +++ b/poetry.lock @@ -84,48 +84,21 @@ typing-extensions = ">=3.7.4" colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] -[[package]] -name = "cairocffi" -version = "1.2.0" -description = "cffi-based cairo bindings for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cffi = ">=1.1.0" - -[package.extras] -doc = ["sphinx", "sphinx-rtd-theme"] -test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"] -xcb = ["xcffib (>=0.3.2)"] - [[package]] name = "certifi" -version = "2020.11.8" +version = "2020.12.5" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false python-versions = "*" -[[package]] -name = "cffi" -version = "1.14.4" -description = "Foreign Function Interface for Python calling C code." -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -pycparser = "*" - [[package]] name = "chardet" -version = "3.0.4" +version = "4.0.0" description = "Universal encoding detector for Python 2 and 3" category = "dev" optional = false -python-versions = "*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "click" @@ -163,7 +136,7 @@ optional = false python-versions = "*" [package.extras] -test = ["flake8 (3.7.8)", "hypothesis (3.55.3)"] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "cycler" @@ -247,18 +220,19 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "3.1.0" +version = "3.3.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "rst.linker"] -testing = ["packaging", "pep517", "unittest2", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -311,6 +285,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "manimpango" +version = "0.1.4" +description = "Bindings for Pango for using with Manim." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "markupsafe" version = "1.1.1" @@ -361,7 +343,7 @@ python-versions = ">=3.6" [[package]] name = "packaging" -version = "20.7" +version = "20.8" description = "Core utilities for Python packages" category = "dev" optional = false @@ -370,30 +352,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pyparsing = ">=2.0.2" -[[package]] -name = "pangocairocffi" -version = "0.4.0" -description = "CFFI-based pango-cairo bindings for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cairocffi = ">=1.0.2" -cffi = ">=1.1.0" -pangocffi = ">=0.8.0" - -[[package]] -name = "pangocffi" -version = "0.8.0" -description = "CFFI-based pango bindings for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cffi = ">=1.1.0" - [[package]] name = "pathspec" version = "0.8.1" @@ -402,14 +360,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[[package]] -name = "pathtools" -version = "0.1.2" -description = "File system general utilities" -category = "main" -optional = true -python-versions = "*" - [[package]] name = "pillow" version = "8.0.1" @@ -453,7 +403,7 @@ six = ">=1.9" [[package]] name = "py" -version = "1.9.0" +version = "1.10.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false @@ -467,14 +417,6 @@ category = "main" optional = false python-versions = ">=3.6, <4" -[[package]] -name = "pycparser" -version = "2.20" -description = "C parser in Python" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "pydub" version = "0.24.1" @@ -485,7 +427,7 @@ python-versions = "*" [[package]] name = "pygments" -version = "2.7.2" +version = "2.7.3" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false @@ -516,25 +458,24 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.1.2" +version = "6.2.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=17.4.0" +attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0" +pluggy = ">=0.12,<1.0.0a1" py = ">=1.8.2" toml = "*" [package.extras] -checkqa_mypy = ["mypy (0.780)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [[package]] @@ -550,7 +491,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2020.4" +version = "2020.5" description = "World timezone definitions, modern and historical" category = "dev" optional = false @@ -558,7 +499,7 @@ python-versions = "*" [[package]] name = "recommonmark" -version = "0.6.0" +version = "0.7.1" description = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects." category = "dev" optional = false @@ -579,7 +520,7 @@ python-versions = "*" [[package]] name = "requests" -version = "2.25.0" +version = "2.25.1" description = "Python HTTP for Humans." category = "dev" optional = false @@ -587,13 +528,13 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] certifi = ">=2017.4.17" -chardet = ">=3.0.2,<4" +chardet = ">=3.0.2,<5" idna = ">=2.5,<3" urllib3 = ">=1.21.1,<1.27" [package.extras] security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] [[package]] name = "rich" @@ -642,7 +583,7 @@ python-versions = "*" [[package]] name = "sphinx" -version = "3.3.1" +version = "3.4.1" description = "Python documentation generator" category = "dev" optional = false @@ -668,8 +609,8 @@ sphinxcontrib-serializinghtml = "*" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.790)", "docutils-stubs"] -test = ["pytest", "pytest-cov", "html5lib", "typed-ast", "cython"] +lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.790)", "docutils-stubs"] +test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] [[package]] name = "sphinxcontrib-applehelp" @@ -752,14 +693,15 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tqdm" -version = "4.54.0" +version = "4.55.0" description = "Fast, Extensible Progress Meter" category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.extras] -dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +telegram = ["requests"] [[package]] name = "typed-ast" @@ -788,18 +730,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "watchdog" -version = "0.10.4" +version = "1.0.2" description = "Filesystem events monitoring" category = "main" optional = true -python-versions = "*" - -[package.dependencies] -pathtools = ">=0.1.1" +python-versions = ">=3.6" [package.extras] watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] @@ -822,7 +761,7 @@ python-versions = ">=3.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [extras] js_renderer = ["grpcio", "grpcio-tools", "watchdog"] @@ -830,7 +769,7 @@ js_renderer = ["grpcio", "grpcio-tools", "watchdog"] [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "f66610f54761f5f832bba54c4b8fb33ca584624493965927935763b24df6e08f" +content-hash = "c2d54eafca0b27220ef8fd1432501a461399480e4bc81e61adce393b17d98f30" [metadata.files] alabaster = [ @@ -860,52 +799,13 @@ babel = [ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] -cairocffi = [ - {file = "cairocffi-1.2.0.tar.gz", hash = "sha256:9a979b500c64c8179fec286f337e8fe644eca2f2cd05860ce0b62d25f22ea140"}, -] certifi = [ - {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"}, - {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"}, -] -cffi = [ - {file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"}, - {file = "cffi-1.14.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06"}, - {file = "cffi-1.14.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26"}, - {file = "cffi-1.14.4-cp27-cp27m-win32.whl", hash = "sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c"}, - {file = "cffi-1.14.4-cp27-cp27m-win_amd64.whl", hash = "sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b"}, - {file = "cffi-1.14.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d"}, - {file = "cffi-1.14.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca"}, - {file = "cffi-1.14.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698"}, - {file = "cffi-1.14.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b"}, - {file = "cffi-1.14.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293"}, - {file = "cffi-1.14.4-cp35-cp35m-win32.whl", hash = "sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2"}, - {file = "cffi-1.14.4-cp35-cp35m-win_amd64.whl", hash = "sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7"}, - {file = "cffi-1.14.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f"}, - {file = "cffi-1.14.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362"}, - {file = "cffi-1.14.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec"}, - {file = "cffi-1.14.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b"}, - {file = "cffi-1.14.4-cp36-cp36m-win32.whl", hash = "sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668"}, - {file = "cffi-1.14.4-cp36-cp36m-win_amd64.whl", hash = "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009"}, - {file = "cffi-1.14.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb"}, - {file = "cffi-1.14.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d"}, - {file = "cffi-1.14.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03"}, - {file = "cffi-1.14.4-cp37-cp37m-win32.whl", hash = "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e"}, - {file = "cffi-1.14.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35"}, - {file = "cffi-1.14.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d"}, - {file = "cffi-1.14.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b"}, - {file = "cffi-1.14.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53"}, - {file = "cffi-1.14.4-cp38-cp38-win32.whl", hash = "sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d"}, - {file = "cffi-1.14.4-cp38-cp38-win_amd64.whl", hash = "sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375"}, - {file = "cffi-1.14.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909"}, - {file = "cffi-1.14.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd"}, - {file = "cffi-1.14.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a"}, - {file = "cffi-1.14.4-cp39-cp39-win32.whl", hash = "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3"}, - {file = "cffi-1.14.4-cp39-cp39-win_amd64.whl", hash = "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b"}, - {file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"}, + {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, + {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, ] chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, + {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, + {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -1043,8 +943,8 @@ imagesize = [ {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, ] importlib-metadata = [ - {file = "importlib_metadata-3.1.0-py2.py3-none-any.whl", hash = "sha256:590690d61efdd716ff82c39ca9a9d4209252adfe288a4b5721181050acbd4175"}, - {file = "importlib_metadata-3.1.0.tar.gz", hash = "sha256:d9b8a46a0885337627a6430db287176970fff18ad421becec1d64cfc763c2099"}, + {file = "importlib_metadata-3.3.0-py3-none-any.whl", hash = "sha256:bf792d480abbd5eda85794e4afb09dd538393f7d6e6ffef6e9f03d2014cf9450"}, + {file = "importlib_metadata-3.3.0.tar.gz", hash = "sha256:5c5a2720817414a6c41f0a49993908068243ae02c1635a228126519b509c8aed"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1115,6 +1015,30 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.4.3-cp38-cp38-win32.whl", hash = "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd"}, {file = "lazy_object_proxy-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239"}, ] +manimpango = [ + {file = "manimpango-0.1.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b4d61797b36b9938c226bd38a32fd15eea580bf052044143749326921bf0a6cd"}, + {file = "manimpango-0.1.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:fcbe104da7b63d8781d1e9952cba6bf4358a9c341c4e98f158bc91b913384f91"}, + {file = "manimpango-0.1.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:6e02472fbb05176ba5d0b70866221152507fe6daa4bdf1eb1cf30dffb6f606bd"}, + {file = "manimpango-0.1.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:05a055c41db3b731cbd3fcb3cfe7b1765d4bb1c3b6201db392a3ee9e57772976"}, + {file = "manimpango-0.1.4-cp36-cp36m-win32.whl", hash = "sha256:3cb3622f4defdcbb0c90bbd86aa20ec2ae9b548a967d31a49f5a06a848b5b923"}, + {file = "manimpango-0.1.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4059eac98f93296da9431a2dd3c2e863819a311cc945d3c8e6112a48e4657005"}, + {file = "manimpango-0.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f489bc3f5fe0c908894a480ed14e5ac0cc87a959aeb073cf5a82a48eecd07bcb"}, + {file = "manimpango-0.1.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c3b493dd5cf53f0243c3d7d861415869bac7e04ec86a816536d23aab2aa88230"}, + {file = "manimpango-0.1.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:205e7ded2e74f174be4d1e96b27a2fc3bf9b0bdfedccc095b79d627d659d4238"}, + {file = "manimpango-0.1.4-cp37-cp37m-win32.whl", hash = "sha256:4d5eb4a98684dfd91809c0c910637a952c14c35e0029776e4f907aaf61c206fa"}, + {file = "manimpango-0.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:306a8e67782178f968e5f1414f4b86711c487ea74f886280aae93225afa103b9"}, + {file = "manimpango-0.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:75044532210a11c00cfd5a6adc5381fd9b848b4a4f444b5d872488d571c6ca2a"}, + {file = "manimpango-0.1.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:34867ab61eb691dae7291596eb09c12616ee054f9812e884a0391c83cf6b5f92"}, + {file = "manimpango-0.1.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:7ca4adcebe45b37e52edb7d5bdc50e0b53fc73eada17e6dfc83e237386df4e36"}, + {file = "manimpango-0.1.4-cp38-cp38-win32.whl", hash = "sha256:8543495da7b7fb5c35a33af710130b2c6950a1b931b5baf03c058573657b1197"}, + {file = "manimpango-0.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:a840b41243d30d8d19a4847c2213aa05158d3009dbc4289b914eac92719b4f24"}, + {file = "manimpango-0.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c17cb10e74f191df7a7848423c298e5a4004a13641088a6a31b4ae5296f00d82"}, + {file = "manimpango-0.1.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:5295d3a27d291ca0879b51cf1e398d129aa91db8c6b89c14417fa61cb1fa80e7"}, + {file = "manimpango-0.1.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:6e0ed860825c4e57f16f06f1b14d9599217add991136edfb390f446c85fc4830"}, + {file = "manimpango-0.1.4-cp39-cp39-win32.whl", hash = "sha256:ec4497af4a23d6969dd045cc66695ae59d63157119908ce76bb5585450183b63"}, + {file = "manimpango-0.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:e165fd017864b7435da59f4a192f3f55354602e399e763ded20fbbd7fc5f9e42"}, + {file = "manimpango-0.1.4.tar.gz", hash = "sha256:693fbc52ea60c75acb9c98f23fc8e98a429b5ce02ab761ef9db24e9d61d62a49"}, +] markupsafe = [ {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, @@ -1222,22 +1146,13 @@ numpy = [ {file = "numpy-1.19.4.zip", hash = "sha256:141ec3a3300ab89c7f2b0775289954d193cc8edb621ea05f99db9cb181530512"}, ] packaging = [ - {file = "packaging-20.7-py2.py3-none-any.whl", hash = "sha256:eb41423378682dadb7166144a4926e443093863024de508ca5c9737d6bc08376"}, - {file = "packaging-20.7.tar.gz", hash = "sha256:05af3bb85d320377db281cf254ab050e1a7ebcbf5410685a9a407e18a1f81236"}, -] -pangocairocffi = [ - {file = "pangocairocffi-0.4.0.tar.gz", hash = "sha256:ebebffb16861aca36823d39dfbcabe963eb4af03035ed9e0a701bd97a0e16af0"}, -] -pangocffi = [ - {file = "pangocffi-0.8.0.tar.gz", hash = "sha256:f8b03bc7dcc85e70f8cc58ca2b56b2077511a44c3d5c20bb0abdcbc66132288d"}, + {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, + {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, ] pathspec = [ {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, ] -pathtools = [ - {file = "pathtools-0.1.2.tar.gz", hash = "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0"}, -] pillow = [ {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"}, {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"}, @@ -1296,8 +1211,8 @@ protobuf = [ {file = "protobuf-3.14.0.tar.gz", hash = "sha256:1d63eb389347293d8915fb47bee0951c7b5dab522a4a60118b9a18f33e21f8ce"}, ] py = [ - {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, - {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] pycairo = [ {file = "pycairo-1.20.0-cp36-cp36m-win32.whl", hash = "sha256:e5a3433690c473e073a9917dc8f1fc7dc8b9af7b201bf372894b8ad70d960c6d"}, @@ -1310,17 +1225,13 @@ pycairo = [ {file = "pycairo-1.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:57166119e424d71eccdba6b318bd731bdabd17188e2ba10d4f315f7bf16ace3f"}, {file = "pycairo-1.20.0.tar.gz", hash = "sha256:5695a10cb7f9ae0d01f665b56602a845b0a8cb17e2123bfece10c2e58552468c"}, ] -pycparser = [ - {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, - {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, -] pydub = [ {file = "pydub-0.24.1-py2.py3-none-any.whl", hash = "sha256:25fdfbbfd4c69363006a27c7bd2346c4b886a0dd3da264c14d858b71a9593284"}, {file = "pydub-0.24.1.tar.gz", hash = "sha256:630c68bfff9bb27cbc5e1f02923f717c3bc5f4d73fd685fda08b6ce90f76dc69"}, ] pygments = [ - {file = "Pygments-2.7.2-py3-none-any.whl", hash = "sha256:88a0bbcd659fcb9573703957c6b9cff9fab7295e6e76db54c9d00ae42df32773"}, - {file = "Pygments-2.7.2.tar.gz", hash = "sha256:381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0"}, + {file = "Pygments-2.7.3-py3-none-any.whl", hash = "sha256:f275b6c0909e5dafd2d6269a656aa90fa58ebf4a74f8fcf9053195d226b24a08"}, + {file = "Pygments-2.7.3.tar.gz", hash = "sha256:ccf3acacf3782cbed4a989426012f1c535c9a90d3a7fc3f16d231b9372d2b716"}, ] pylint = [ {file = "pylint-2.6.0-py3-none-any.whl", hash = "sha256:bfe68f020f8a0fece830a22dd4d5dddb4ecc6137db04face4c3420a46a52239f"}, @@ -1331,20 +1242,20 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, - {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, + {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, + {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] pytz = [ - {file = "pytz-2020.4-py2.py3-none-any.whl", hash = "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd"}, - {file = "pytz-2020.4.tar.gz", hash = "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268"}, + {file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"}, + {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, ] recommonmark = [ - {file = "recommonmark-0.6.0-py2.py3-none-any.whl", hash = "sha256:2ec4207a574289355d5b6ae4ae4abb29043346ca12cdd5f07d374dc5987d2852"}, - {file = "recommonmark-0.6.0.tar.gz", hash = "sha256:29cd4faeb6c5268c633634f2d69aef9431e0f4d347f90659fd0aab20e541efeb"}, + {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"}, + {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"}, ] regex = [ {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, @@ -1390,8 +1301,8 @@ regex = [ {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, ] requests = [ - {file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"}, - {file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"}, + {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, + {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] rich = [ {file = "rich-6.2.0-py3-none-any.whl", hash = "sha256:fa55d5d6ba9a0df1f1c95518891b57b13f1d45548a9a198a87b093fceee513ec"}, @@ -1433,8 +1344,8 @@ snowballstemmer = [ {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, ] sphinx = [ - {file = "Sphinx-3.3.1-py3-none-any.whl", hash = "sha256:d4e59ad4ea55efbb3c05cde3bfc83bfc14f0c95aa95c3d75346fcce186a47960"}, - {file = "Sphinx-3.3.1.tar.gz", hash = "sha256:1e8d592225447104d1172be415bc2972bd1357e3e12fdc76edf2261105db4300"}, + {file = "Sphinx-3.4.1-py3-none-any.whl", hash = "sha256:aeef652b14629431c82d3fe994ce39ead65b3fe87cf41b9a3714168ff8b83376"}, + {file = "Sphinx-3.4.1.tar.gz", hash = "sha256:e450cb205ff8924611085183bf1353da26802ae73d9251a8fcdf220a8f8712ef"}, ] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, @@ -1465,8 +1376,8 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tqdm = [ - {file = "tqdm-4.54.0-py2.py3-none-any.whl", hash = "sha256:9e7b8ab0ecbdbf0595adadd5f0ebbb9e69010e0bd48bbb0c15e550bf2a5292df"}, - {file = "tqdm-4.54.0.tar.gz", hash = "sha256:5c0d04e06ccc0da1bd3fa5ae4550effcce42fcad947b4a6cafa77bdc9b09ff22"}, + {file = "tqdm-4.55.0-py2.py3-none-any.whl", hash = "sha256:0cd81710de29754bf17b6fee07bdb86f956b4fa20d3078f02040f83e64309416"}, + {file = "tqdm-4.55.0.tar.gz", hash = "sha256:f4f80b96e2ceafea69add7bf971b8403b9cba8fb4451c1220f91c79be4ebd208"}, ] typed-ast = [ {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, @@ -1510,7 +1421,23 @@ urllib3 = [ {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, ] watchdog = [ - {file = "watchdog-0.10.4.tar.gz", hash = "sha256:e38bffc89b15bafe2a131f0e1c74924cf07dcec020c2e0a26cccd208831fcd43"}, + {file = "watchdog-1.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e2a531e71be7b5cc3499ae2d1494d51b6a26684bcc7c3146f63c810c00e8a3cc"}, + {file = "watchdog-1.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e7c73edef48f4ceeebb987317a67e0080e5c9228601ff67b3c4062fa020403c7"}, + {file = "watchdog-1.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85e6574395aa6c1e14e0f030d9d7f35c2340a6cf95d5671354ce876ac3ffdd4d"}, + {file = "watchdog-1.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:27d9b4666938d5d40afdcdf2c751781e9ce36320788b70208d0f87f7401caf93"}, + {file = "watchdog-1.0.2-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2f1ade0d0802503fda4340374d333408831cff23da66d7e711e279ba50fe6c4a"}, + {file = "watchdog-1.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f1d0e878fd69129d0d68b87cee5d9543f20d8018e82998efb79f7e412d42154a"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d948ad9ab9aba705f9836625b32e965b9ae607284811cd98334423f659ea537a"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:101532b8db506559e52a9b5d75a308729b3f68264d930670e6155c976d0e52a0"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:b1d723852ce90a14abf0ec0ca9e80689d9509ee4c9ee27163118d87b564a12ac"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:68744de2003a5ea2dfbb104f9a74192cf381334a9e2c0ed2bbe1581828d50b61"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:602dbd9498592eacc42e0632c19781c3df1728ef9cbab555fab6778effc29eeb"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:016b01495b9c55b5d4126ed8ae75d93ea0d99377084107c33162df52887cee18"}, + {file = "watchdog-1.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:5f1f3b65142175366ba94c64d8d4c8f4015825e0beaacee1c301823266b47b9b"}, + {file = "watchdog-1.0.2-py3-none-win32.whl", hash = "sha256:57f05e55aa603c3b053eed7e679f0a83873c540255b88d58c6223c7493833bac"}, + {file = "watchdog-1.0.2-py3-none-win_amd64.whl", hash = "sha256:f84146f7864339c8addf2c2b9903271df21d18d2c721e9a77f779493234a82b5"}, + {file = "watchdog-1.0.2-py3-none-win_ia64.whl", hash = "sha256:ee21aeebe6b3e51e4ba64564c94cee8dbe7438b9cb60f0bb350c4fa70d1b52c2"}, + {file = "watchdog-1.0.2.tar.gz", hash = "sha256:376cbc2a35c0392b0fe7ff16fbc1b303fd99d4dd9911ab5581ee9d69adc88982"}, ] wrapt = [ {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, diff --git a/pyproject.toml b/pyproject.toml index 8e98758011..cff99152d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,11 +35,9 @@ pydub = "*" pygments = "*" rich = "^6.0" pycairo = "^1.19" -pangocffi = "^0.8.0" -pangocairocffi = "^0.4.0" -cairocffi = "^1.1.0" -grpcio = { version = "*", optional = true } -grpcio-tools = { version = "*", optional = true } +manimpango = "^0.1.4" +grpcio = { version = "1.33.*", optional = true } +grpcio-tools = { version = "1.33.*", optional = true } watchdog = { version = "*", optional = true } [tool.poetry.extras] diff --git a/tests/test_pango.py b/tests/test_pango.py deleted file mode 100644 index 3c393673c5..0000000000 --- a/tests/test_pango.py +++ /dev/null @@ -1,156 +0,0 @@ -"""Tests :class:`Text` by comparing SVG files created. -""" -import os -import re - -import cairocffi -import pangocairocffi -import pangocffi -from manim import START_X, START_Y, Text, SVGMobject, ITALIC - -RTL_TEXT: str = """صباح الخير -مرحبا جميعا""" - -WIDTH: int = 600 -HEIGTH: int = 400 -folder: str = os.path.abspath(os.path.join("media", "texts")) -filename: str = os.path.join(folder, "hello.svg") - - -def remove_last_M(file_path: str) -> None: # pylint: disable=invalid-name - """Format SVG file so that it can be compared""" - with open(file_path, "r") as fpr: - content = fpr.read() - content = re.sub(r'Z M [^A-Za-z]*? "\/>', 'Z "/>', content) - with open(file_path, "w") as fpw: - fpw.write(content) - - -def compare_SVGObject_with_PangoText( # pylint: disable=invalid-name - text: Text, svg_path: str -) -> bool: - """Checks for the path_string formed by Text and Formed SVG file. - Uses SVGMobject as it parses the SVG and returns the path_string - """ - remove_last_M(svg_path) # to prevent issue displaying - svg = SVGMobject(svg_path) - assert len(text.submobjects) == len(svg.submobjects) - assert (text.points == svg.points).all() - for i in range(len(text.submobjects)): - assert text.submobjects[i].path_string == svg.submobjects[i].path_string - assert ( - text.submobjects[i].sheen_direction == svg.submobjects[i].sheen_direction - ).all() - assert ( - text.submobjects[i].stroke_rgbas == svg.submobjects[i].stroke_rgbas - ).all() - return True - - -def test_general_text_svgobject() -> None: - """Checks number of submobjects generated when directly - called using ``SVGMobject`` - """ - text = "hello" - size = 1 - temp_pango_text = Text(text, size=size) - surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(WIDTH)) - fontdesc = pangocffi.FontDescription() - fontdesc.set_size(pangocffi.units_from_double(size * 10)) - layout.set_font_description(fontdesc) - layout.set_text(text) - pangocairocffi.show_layout(context, layout) - surface.finish() - assert compare_SVGObject_with_PangoText(temp_pango_text, filename) - - -def test_rtl_text_to_svgobject() -> None: - """Checks number of submobjects generated when directly - called using ``SVGMobject``""" - size = 1 - text = RTL_TEXT.replace("\n", "") - temp_pango_text = Text(text, size=1) - surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(WIDTH)) - fontdesc = pangocffi.FontDescription() - fontdesc.set_size(pangocffi.units_from_double(size * 10)) - layout.set_font_description(fontdesc) - layout.set_text(text) - pangocairocffi.show_layout(context, layout) - surface.finish() - assert compare_SVGObject_with_PangoText(temp_pango_text, filename) - - -def test_font_face() -> None: - """Checks font face using submobject len""" - size = 1 - text = RTL_TEXT.replace("\n", "") - font_face = "sans" - temp_pango_text = Text(text, size=1, font=font_face) - surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(WIDTH)) - fontdesc = pangocffi.FontDescription() - fontdesc.set_family(font_face) - fontdesc.set_size(pangocffi.units_from_double(size * 10)) - layout.set_font_description(fontdesc) - layout.set_text(text) - pangocairocffi.show_layout(context, layout) - surface.finish() - assert compare_SVGObject_with_PangoText(temp_pango_text, filename) - - -def test_whether_svg_file_created() -> None: - """Checks Whether SVG file is created in desired location""" - temp_pango_text = Text("hello", size=1) - theo_path = os.path.abspath( - os.path.join(folder, temp_pango_text.text2hash() + ".svg") - ) - actual_path = os.path.abspath(temp_pango_text.text2svg()) - assert theo_path == actual_path - - -def test_tabs_replace() -> None: - """Checks whether are there in end svg image. - Pango should handle tabs and line breaks.""" - size = 1 - temp_pango_text = Text("hello\thi\nf") - assert temp_pango_text.text == "hellohif" - surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(WIDTH)) - fontdesc = pangocffi.FontDescription() - fontdesc.set_size(pangocffi.units_from_double(size * 10)) - layout.set_font_description(fontdesc) - layout.set_text("hellohif") - pangocairocffi.show_layout(context, layout) - surface.finish() - assert compare_SVGObject_with_PangoText(temp_pango_text, filename) - - -def test_t2s() -> None: - size = 1 - temp_pango_text = Text("Helloworld", t2s={"world": ITALIC}) - surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) - context = cairocffi.Context(surface) - context.move_to(START_X, START_Y) - layout = pangocairocffi.create_layout(context) - layout.set_width(pangocffi.units_from_double(WIDTH)) - fontdesc = pangocffi.FontDescription() - fontdesc.set_size(pangocffi.units_from_double(size * 10)) - layout.set_font_description(fontdesc) - layout.set_markup('Helloworld') # yay, pango markup - pangocairocffi.show_layout(context, layout) - surface.finish() - assert compare_SVGObject_with_PangoText(temp_pango_text, filename)