pax_global_header00006660000000000000000000000064143436502000014507gustar00rootroot0000000000000052 comment=08894db83de3dac18508f981183db42174783e35 utidylib-0.9/000077500000000000000000000000001434365020000132045ustar00rootroot00000000000000utidylib-0.9/.github/000077500000000000000000000000001434365020000145445ustar00rootroot00000000000000utidylib-0.9/.github/FUNDING.yml000066400000000000000000000000411434365020000163540ustar00rootroot00000000000000github: [nijel] liberapay: nijel utidylib-0.9/.github/dependabot.yml000066400000000000000000000005451434365020000174000ustar00rootroot00000000000000# This file is generated in https://github.com/WeblateOrg/meta/ version: 2 updates: - package-ecosystem: github-actions directory: / schedule: interval: daily labels: - dependencies - automerge - package-ecosystem: pip directory: / schedule: interval: daily labels: - dependencies - automerge utidylib-0.9/.github/matchers/000077500000000000000000000000001434365020000163525ustar00rootroot00000000000000utidylib-0.9/.github/matchers/flake8.json000066400000000000000000000004441434365020000204210ustar00rootroot00000000000000{ "problemMatcher": [ { "owner": "flake8", "pattern": [ { "code": 4, "column": 3, "file": 1, "line": 2, "message": 5, "regexp": "^([^:]*):(\\d+):(\\d+): (\\w+\\d\\d\\d) (.*)$" } ] } ] } utidylib-0.9/.github/workflows/000077500000000000000000000000001434365020000166015ustar00rootroot00000000000000utidylib-0.9/.github/workflows/flake8.yml000066400000000000000000000015641434365020000205040ustar00rootroot00000000000000name: Flake8 on: push: branches-ignore: - "dependabot/**" - weblate pull_request: jobs: flake8: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 with: path: | ~/.cache/pip ~/.cache/pre-commit key: ${{ runner.os }}-pip-lint-${{ hashFiles('**/requirements*.txt') }}-${{ hashFiles('.pre-commit-config.yaml') }} - name: Setup Python uses: actions/setup-python@v4 with: python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip wheel pip install -r requirements-lint.txt - name: Run flake8 run: | echo "::add-matcher::.github/matchers/flake8.json" pre-commit run flake8 --all echo "::remove-matcher owner=flake8::" utidylib-0.9/.github/workflows/pre-commit.yml000066400000000000000000000014031434365020000213760ustar00rootroot00000000000000name: Pre-commit check on: push: branches-ignore: - "dependabot/**" - weblate pull_request: jobs: pre-commit: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 with: path: | ~/.cache/pip ~/.cache/pre-commit key: ${{ runner.os }}-pre-commit-${{ hashFiles('**/requirements*.txt') }}-${{ hashFiles('.pre-commit-config.yaml') }} - name: Setup Python uses: actions/setup-python@v4 with: python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip wheel pip install -r requirements-lint.txt - name: pre-commit run: pre-commit run --all utidylib-0.9/.github/workflows/setup.yml000066400000000000000000000016321434365020000204660ustar00rootroot00000000000000name: Distribution on: [push, pull_request] jobs: setup: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-setup-${{ hashFiles('**/requirements*.txt') }} - name: Setup Python uses: actions/setup-python@v4 with: python-version: 3.8 - name: Install dependencies run: | python -m pip install --upgrade pip wheel pip install -r requirements-test.txt - name: build run: python ./setup.py sdist bdist_wheel - name: twine run: twine check dist/* - name: Publish package if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@master with: user: __token__ password: ${{ secrets.pypi_password }} utidylib-0.9/.github/workflows/test.yml000066400000000000000000000035441434365020000203110ustar00rootroot00000000000000name: Test on: [push, pull_request] jobs: test: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: - ubuntu-22.04 - macos-latest python-version: - "3.7" - "3.8" - "3.9" - "3.10" - "3.11" tidy-version: - "5.6.0" include: - os: ubuntu-22.04 python-version: "3.11" tidy-version: "5.8.0" - os: ubuntu-20.04 python-version: "3.11" tidy-version: "os" name: ${{ matrix.os }}, Python ${{ matrix.python-version }}, tidy ${{ matrix.tidy-version }} steps: - uses: actions/checkout@v3 - name: Cache pip uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements*.txt') }} - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install tidy run: ./scripts/install-tidy.sh ${{ matrix.tidy-version }} - name: Install pip dependencies run: | python -m pip install --upgrade pip wheel pip install -r requirements.txt -r requirements-test.txt - name: Test run: | py.test --cov=tidy tidy - name: Coverage run: | coverage xml - name: Install editable run: pip install -e . - name: Check used library run: python -c 'import tidy.lib; print(tidy.lib._tidy.lib._name, tidy.lib.getTidyVersion())' - uses: codecov/codecov-action@v3 with: token: ${{secrets.CODECOV_TOKEN}} flags: unittests name: Python ${{ matrix.python-version }}, ${{ matrix.os }}, tidy ${{ matrix.tidy-version }} utidylib-0.9/.gitignore000066400000000000000000000001321434365020000151700ustar00rootroot00000000000000*.swp *.pyc /build/ /dist/ /.venv* /uTidylib.egg-info/ .coverage /.cache/ /.pytest_cache/ utidylib-0.9/.pre-commit-config.yaml000066400000000000000000000030621434365020000174660ustar00rootroot00000000000000# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: requirements-txt-fixer - id: check-merge-conflict - id: check-json - id: debug-statements - id: mixed-line-ending args: [--fix=lf] - repo: https://github.com/adrienverge/yamllint rev: v1.26.3 hooks: - id: yamllint - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: - id: isort - repo: https://github.com/asottile/pyupgrade rev: v2.32.0 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black rev: 22.3.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: - id: flake8 additional_dependencies: - flake8-bugbear - flake8-builtins - flake8-comprehensions - flake8-django - flake8-docstrings - flake8-eradicate - flake8-executable - flake8-logging-format - flake8-mutable - flake8-polyfill - flake8-print - flake8-return - flake8-self - pep8-naming - repo: https://github.com/asottile/blacken-docs rev: v1.12.1 hooks: - id: blacken-docs - repo: meta hooks: - id: check-hooks-apply - id: check-useless-excludes exclude: "^docs/make.bat$" utidylib-0.9/.yamllint.yml000066400000000000000000000001401434365020000156310ustar00rootroot00000000000000extends: default rules: line-length: max: 500 level: error document-start: disable utidylib-0.9/CHANGES.rst000066400000000000000000000014341434365020000150100ustar00rootroot00000000000000Changes ======= 0.9 --- * Dropped support for Python 3.6. * Added support for Python 3.10 and 3.11. * Compatibility with html-tidy 5.8.0. * Added support for specifying library full path using TIDY_LIBRARY_FULL_PATH. * Added getTidyVersion to get libtidy version. 0.8 --- * Code cleanups. * Fixed typo in 0.7 release notes. 0.7 --- * Dropped support for Python 2. 0.6 --- * First official release PyPI. 0.5 --- * Fixed compatibility with Debian patched libtidy5deb1. 0.4 --- * Compatibility with html-tidy 5.6.0. * Added support for Python 3. 0.3 --- * Initial release under new maintainer. * Incorporated Debian patches. * Various compatiblity fixes (eg. with 64-bit machines). * Various code cleanups. * New test suite. * New documentation. * Support for new HTML 5 tidy library. utidylib-0.9/LICENSE000066400000000000000000000022061434365020000142110ustar00rootroot00000000000000The MIT License Copyright (c) 2003 Cory Dodt Copyright (c) 2014-2018 Michal Čihař Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. utidylib-0.9/MANIFEST.in000066400000000000000000000004161434365020000147430ustar00rootroot00000000000000include LICENSE include *.py include scripts/* include README.* include CHANGES.* include MANIFEST.in include docs/conf.py include docs/Makefile include docs/make.bat include pytest.ini include requirements.txt include requirements-test.txt recursive-include docs *.rst utidylib-0.9/README.rst000066400000000000000000000035601434365020000146770ustar00rootroot00000000000000uTidylib ======== .. image:: https://travis-ci.org/nijel/utidylib.svg?branch=master :target: https://travis-ci.org/nijel/utidylib :alt: Build Status .. image:: https://codecov.io/gh/nijel/utidylib/branch/master/graph/badge.svg :target: https://codecov.io/gh/nijel/utidylib :alt: Coverage Status .. image:: https://readthedocs.org/projects/utidylib/badge/?version=latest :target: http://utidylib.readthedocs.org/en/latest/ :alt: Documentation This is fork of uTidylib with permission with original author. Originally it incorporated patches from Debian and other distributions, now it also brings compatibility with recent html-tidy versions and works with Python 3. The package is available on PyPI . This is uTidylib, the Python wrapper for the HTML cleaning library named TidyLib. It supports both original Tidy and new HTML5 enabled Tidy . Once installed, there are two ways to get help. The simplest is: .. code-block:: sh $ python >>> import tidy >>> help(tidy) . . . Then, of course, there's the API documentation, which is available at . 10 Second Tutorial ------------------ .. code-block:: pycon >>> import tidy >>> print( ... tidy.parseString( ... "Hello Tidy!", ... output_xhtml=1, ... add_xml_decl=1, ... indent=1, ... tidy_mark=0, ... doctype="transitional", ... ) ... ) Hello Tidy! Good luck! utidylib-0.9/docs/000077500000000000000000000000001434365020000141345ustar00rootroot00000000000000utidylib-0.9/docs/.gitignore000066400000000000000000000000071434365020000161210ustar00rootroot00000000000000_build utidylib-0.9/docs/Makefile000066400000000000000000000151621434365020000156010ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/uTidylib.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/uTidylib.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/uTidylib" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/uTidylib" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." utidylib-0.9/docs/conf.py000066400000000000000000000057231434365020000154420ustar00rootroot00000000000000# # uTidylib documentation build configuration file, created by # sphinx-quickstart on Wed Aug 13 11:25:46 2014. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import os import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath("..")) os.environ["IGNORE_MISSING_TIDY"] = "1" # -- General configuration ------------------------------------------------ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", ] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix of source filenames. source_suffix = ".rst" # The master toctree document. master_doc = "index" # General information about the project. project = "uTidylib" copyright = "2014-2021, Michal Čihař" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = "0.4" # The full version, including alpha/beta/rc tags. release = version # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ["_build"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = "default" # Output file base name for HTML help builder. htmlhelp_basename = "uTidylibdoc" # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ("index", "uTidylib.tex", "uTidylib Documentation", "Michal Čihař", "manual"), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [("index", "utidylib", "uTidylib Documentation", ["Michal Čihař"], 1)] # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. epub_title = "uTidylib" epub_author = "Michal Čihař" epub_publisher = "Michal Čihař" epub_copyright = copyright # A list of files that should not be packed into the epub file. epub_exclude_files = ["search.html"] utidylib-0.9/docs/index.rst000066400000000000000000000025601434365020000160000ustar00rootroot00000000000000Welcome to uTidylib's documentation! ==================================== .. automodule:: tidy .. autofunction:: parse .. autofunction:: parseString .. autoclass:: Document :members: .. autoclass:: ReportItem :members: .. autoexception:: TidyLibError .. autoexception:: InvalidOptionError .. autoexception:: OptionArgError Installing ========== To use uTidylib, you need to have HTML tidy library installed. Check for instructions how to obtain it. Once you have installed the library, install uTidylib: .. code-block:: sh pip install uTidylib Contributing ============ You are welcome to contribute on GitHub, we use it for source code management, issue tracking and patches submission, see . Running testsuite ================= The testsuite can be exececuted using both py.test or setuptools, choose whatever approach you prefer: .. code-block:: sh ./setup.py test py.test tidy Building documentation ====================== To build the doc, just run: .. code-block:: sh make -C docs html This requires that you have Sphinx installed. The API documentation will be built in the :file:`docs/_build/html/` directory. License ======= .. include:: ../LICENSE .. include:: ../CHANGES.rst Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` utidylib-0.9/docs/make.bat000066400000000000000000000150611434365020000155440ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\uTidylib.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\uTidylib.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end utidylib-0.9/pytest.ini000066400000000000000000000000451434365020000152340ustar00rootroot00000000000000[pytest] addopts = --doctest-modules utidylib-0.9/requirements-lint.txt000066400000000000000000000000311434365020000174260ustar00rootroot00000000000000pre-commit==2.20.0 twine utidylib-0.9/requirements-test.txt000066400000000000000000000000771434365020000174510ustar00rootroot00000000000000-r requirements-lint.txt -r requirements.txt pytest pytest-cov utidylib-0.9/requirements.txt000066400000000000000000000000001434365020000164560ustar00rootroot00000000000000utidylib-0.9/scripts/000077500000000000000000000000001434365020000146735ustar00rootroot00000000000000utidylib-0.9/scripts/create-release000077500000000000000000000013101434365020000174750ustar00rootroot00000000000000#!/bin/sh set -e if [ "x$1" = "x--help" -o "x$1" = "x-h" ] ; then echo "Usage: ./scripts/create-release [--tag]" exit 1 fi if ! git diff --exit-code --quiet ; then echo "There are not committed changes!" exit 1 fi # Grab version version=`python -c 'import tidy; print(tidy.__version__)'` # What are we going to build? if [ "x$1" = "x--tag" ] ; then git tag -s v$version -m "Version $version" fi # Create tarball ./setup.py sdist --formats bztar,gztar,zip # Optionally upload if [ "x$1" = "x--tag" ] ; then twine upload --sign --identity 63CB1DF1EF12CF2AC0EE5A329C27B31342B7511D dist/uTidylib-$version.tar.gz scp dist/uTidylib-$version.* web:/srv/http/dl.cihar.com/utidylib/ fi utidylib-0.9/scripts/install-tidy.sh000077500000000000000000000011211434365020000176420ustar00rootroot00000000000000#!/bin/sh set -e if [ -z "$1" ] ; then echo "Usage: install-tidy.sh VERSION" exit 1 fi CMAKE_ARGS="" if which apt-get ; then if [ "$1" = "os" ] ; then sudo apt-get install -y libtidy5deb1 exit 0 else sudo apt-get purge libtidy5deb1 tidy libtidy-dev fi CMAKE_ARGS="-DCMAKE_INSTALL_PREFIX=/usr" fi wget -O tidy.tar.gz https://github.com/htacg/tidy-html5/archive/$1.tar.gz mkdir tidy-source tar xvf tidy.tar.gz --strip-components=1 -C tidy-source rm tidy.tar.gz cd tidy-source/build/cmake/ cmake ../.. -DCMAKE_BUILD_TYPE=Release $CMAKE_ARGS make sudo make install utidylib-0.9/setup.cfg000066400000000000000000000033531434365020000150310ustar00rootroot00000000000000[metadata] name = uTidylib version = 0.9 author = Michal Čihař author_email = michal@cihar.com license = MIT description = Wrapper for HTML Tidy url = https://cihar.com/software/utidylib/ project_urls = Issue Tracker=https://github.com/nijel/utidylib/issues Documentation=https://utidylib.readthedocs.io/ Source Code=https://github.com/nijel/utidylib Funding=https://liberapay.com/nijel download_url = https://github.com/nijel/utidylib long_description = file: README.rst long_description_content_type = text/x-rst classifiers = Development Status :: 4 - Beta Topic :: Internet License :: OSI Approved :: MIT License Intended Audience :: Developers Environment :: Web Environment Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 [options] packages = tidy python_requires = >=3.7 include_package_data = 1 [options.package_data] tidy = test_data/*.html [flake8] max-complexity = 16 select = E,W1,W2,W3,W504,W505,W6 enable-extensions = B,C,D,F,G,I,M,N,R,SF # Should be fixed: # D10 - we are missing many docstrings # D20* - wrong docstring formatting # D40* - many strings need rephrasing ignore = D10,D200,D202,D204,D205,D209,D400,D401,SF01,N816,N802 exclude = .git,.venv*,build max-line-length = 88 [pycodestyle] select = E,W1,W2,W3,W504,W505,W6 exclude = .git,.venv*,build max-line-length = 88 [isort] multi_line_output = 3 include_trailing_comma = True force_grid_wrap = 0 use_parentheses = True line_length = 88 known_first_party = tidy utidylib-0.9/setup.py000077500000000000000000000001451434365020000147210ustar00rootroot00000000000000#! /usr/bin/env python """Setup file for easy installation""" from setuptools import setup setup() utidylib-0.9/tidy/000077500000000000000000000000001434365020000141555ustar00rootroot00000000000000utidylib-0.9/tidy/__init__.py000066400000000000000000000032461434365020000162730ustar00rootroot00000000000000"""The Tidy wrapper. I am the main interface to TidyLib. This package supports processing HTML with Tidy, with all the options that the tidy command line supports. For more information on the tidy options, see the reference. These options can be given as keyword arguments to parse and parseString, by changing dashes (-) to underscores(_). For example: >>> import tidy >>> from __future__ import print_function >>> print(tidy.parseString( ... 'Hello Tidy!', ... output_xhtml=1, add_xml_decl=1, indent=1, tidy_mark=0, ... doctype='transitional' ... )) Hello Tidy! For options like newline and output_encoding, which must be set to one of a fixed number of choices, you can provide either the numeric or string version of the choice; so both tidy.parseString('foo', newline=2) and tidy.parseString('foo', newline='CR') do the same thing. There are no plans to support other features of TidyLib, such as document-tree traversal, since Python has several quality DOM implementations. (The author uses Twisted's implementation, twisted.web.microdom). """ from tidy.error import InvalidOptionError, OptionArgError, TidyLibError from tidy.lib import Document, ReportItem, parse, parseString __all__ = [ "error", "lib", "parse", "parseString", "Document", "ReportItem", "TidyLibError", "InvalidOptionError", "OptionArgError", ] __version__ = "0.7" utidylib-0.9/tidy/error.py000066400000000000000000000007261434365020000156650ustar00rootroot00000000000000""" Exceptions for uTidylib """ __all__ = ("TidyLibError", "InvalidOptionError", "OptionArgError") class TidyLibError(Exception): """ Generic Tidy exception. """ pass class InvalidOptionError(TidyLibError): """ Exception for invalid option. """ def __str__(self): return "%s was not a valid Tidy option." % (self.args[0]) class OptionArgError(TidyLibError): """ Exception for invalid parameter. """ pass utidylib-0.9/tidy/lib.py000066400000000000000000000223301434365020000152750ustar00rootroot00000000000000import ctypes import io import os import os.path import weakref from typing import Optional, Tuple from tidy.error import InvalidOptionError, OptionArgError LIBNAMES = ( # Linux "libtidy.so", # MacOS "libtidy.dylib", # Windows "tidy", # Cygwin "cygtidy-0-99-0", # Linux, full soname "libtidy-0.99.so.0", # Linux, full soname "libtidy-0.99.so.0.0.0", # HTML tidy "libtidy.so.5", # Linux, HTML tidy v5.8 "libtidy.so.58", # Debian changed soname "libtidy.so.5deb1", # Windows? "libtidy", # Windows? "tidylib", ) class Loader: """I am a trivial wrapper that eliminates the need for tidy.tidyFoo, so you can just access tidy.Foo """ def __init__(self, libnames: Optional[Tuple[str, ...]] = None): self.lib = None self.libnames = libnames or LIBNAMES # Add package directory to search path os.environ["PATH"] = "".join( (os.path.dirname(__file__), os.pathsep, os.environ["PATH"]) ) # Add full path to a library lib_path = os.environ.get("TIDY_LIBRARY_FULL_PATH") if lib_path: self.libnames = (lib_path,) + self.libnames # Try loading library for libname in self.libnames: try: self.lib = ctypes.CDLL(libname) break except OSError: continue # Fail in case we could not load it if self.lib is None and "IGNORE_MISSING_TIDY" not in os.environ: raise OSError("Couldn't find libtidy, please make sure it is installed.") # Adjust some types if self.lib is not None: self.Create.restype = ctypes.POINTER(ctypes.c_void_p) self.LibraryVersion.restype = ctypes.c_char_p def __getattr__(self, name): return getattr(self.lib, "tidy%s" % name) _tidy = Loader() _putByteFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_char) # define a callback to pass to Tidylib @_putByteFunction def putByte(handle, char): """Lookup sink by handle and call its putByte method""" sinkfactory[handle].putByte(char) return 0 class _OutputSink(ctypes.Structure): _fields_ = [("sinkData", ctypes.c_int), ("putByte", _putByteFunction)] class _Sink: def __init__(self, handle): self._data = io.BytesIO() self.struct = _OutputSink() self.struct.putByte = putByte self.handle = handle def putByte(self, byte): self._data.write(byte) def getvalue(self): return self._data.getvalue() class ReportItem: """ Error report item as returned by tidy. :attribute severity: D, W, E or C indicating severity :attribute line: Line where error was fired (can be None) :attribute col: Column where error was fired (can be None) :attribute message: Error message itsef :attribute err: Whole error message as returned by tidy """ severities = {"W": "Warning", "E": "Error", "C": "Config", "D": "Document"} def __init__(self, err): # TODO - parse emacs mode self.err = err if err.startswith("line"): tokens = err.split(" ", 6) self.full_severity = tokens[5] self.severity = tokens[5][0] # W, E or C self.line = int(tokens[1]) self.col = int(tokens[3]) self.message = tokens[6] else: tokens = err.split(" ", 1) self.full_severity = tokens[0] self.severity = tokens[0][0] self.message = tokens[1] self.line = None self.col = None def get_severity(self): try: return self.severities[self.severity] except KeyError: return self.full_severity.strip().rstrip(":") def __str__(self): if self.line: return "line {} col {} - {}: {}".format( self.line, self.col, self.get_severity(), self.message ) return f"{self.get_severity()}: {self.message}" def __repr__(self): return "{}('{}')".format(self.__class__.__name__, str(self).replace("'", "\\'")) class FactoryDict(dict): """I am a dict with a create method and no __setitem__. This allows me to control my own keys. """ def create(self): """Subclasses should implement me to generate a new item""" def _setitem(self, name, value): dict.__setitem__(self, name, value) def __setitem__(self, name, value): raise TypeError("Use create() to get a new object") class SinkFactory(FactoryDict): """Mapping for lookup of sinks by handle""" def __init__(self): super().__init__() self.lastsink = 0 def create(self): sink = _Sink(self.lastsink) sink.struct.sinkData = self.lastsink FactoryDict._setitem(self, self.lastsink, sink) self.lastsink = self.lastsink + 1 return sink sinkfactory = SinkFactory() class Document: """ Document object as returned by :func:`parseString` or :func:`parse`. """ def __init__(self, options): self.cdoc = _tidy.Create() self.options = options self.errsink = sinkfactory.create() _tidy.SetErrorSink(self.cdoc, ctypes.byref(self.errsink.struct)) self._set_options() def _set_options(self): for key, value in self.options.items(): # this will flush out most argument type errors... if value is None: value = "" _tidy.OptParseValue( self.cdoc, key.replace("_", "-").encode("utf-8"), str(value).encode("utf-8"), ) if self.errors: for error in ERROR_MAP: if self.errors[-1].message.startswith(error): raise ERROR_MAP[error](self.errors[-1].message) def __del__(self): del sinkfactory[self.errsink.handle] def write(self, stream): """ :param stream: Writable file like object. Writes document to the stream. """ stream.write(self.getvalue()) def get_errors(self): """ Returns list of errors as a list of :class:`ReportItem`. """ ret = [] for line in self.errsink.getvalue().decode("utf-8").splitlines(): line = line.strip() if line: ret.append(ReportItem(line)) return ret errors = property(get_errors) def getvalue(self): """Raw string as returned by tidy.""" stlen = ctypes.c_int(8192) string_buffer = ctypes.create_string_buffer(stlen.value) result = _tidy.SaveString(self.cdoc, string_buffer, ctypes.byref(stlen)) if result == -12: # buffer too small string_buffer = ctypes.create_string_buffer(stlen.value) _tidy.SaveString(self.cdoc, string_buffer, ctypes.byref(stlen)) return string_buffer.value def gettext(self): """Unicode text for output returned by tidy.""" return self.getvalue().decode(self.options["output_encoding"]) def __str__(self): return self.gettext() return self.getvalue() ERROR_MAP = { "missing or malformed argument for option: ": OptionArgError, "unknown option: ": InvalidOptionError, } class DocumentFactory(FactoryDict): @staticmethod def load(doc, arg, loader): status = loader(doc.cdoc, arg) if status > 0: _tidy.CleanAndRepair(doc.cdoc) def loadFile(self, doc, filename): self.load(doc, filename.encode("utf-8"), _tidy.ParseFile) def loadString(self, doc, text): self.load(doc, text, _tidy.ParseString) def _create(self, **kwargs): enc = kwargs.get("char-encoding", "utf8") if "output_encoding" not in kwargs: kwargs["output_encoding"] = enc if "input_encoding" not in kwargs: kwargs["input_encoding"] = enc doc = Document(kwargs) ref = weakref.ref(doc, self.releaseDoc) FactoryDict._setitem(self, ref, doc.cdoc) return doc def parse(self, filename, **kwargs): """ :param kwargs: named options to pass to TidyLib for processing the input file. :param filename: the name of a file to process :return: a :class:`Document` object Open and process filename as an HTML file, returning a processed document object. """ doc = self._create(**kwargs) self.loadFile(doc, filename) return doc def parseString(self, text, **kwargs): """ :param kwargs: named options to pass to TidyLib for processing the input file. :param text: the string to parse :return: a :class:`Document` object Use text as an HTML file, and process it, returning a document object. """ doc = self._create(**kwargs) if isinstance(text, str): text = text.encode(doc.options["input_encoding"]) self.loadString(doc, text) return doc def releaseDoc(self, ref): _tidy.Release(self[ref]) docfactory = DocumentFactory() parse = docfactory.parse parseString = docfactory.parseString def getTidyVersion(): return _tidy.lib.tidyLibraryVersion().decode() utidylib-0.9/tidy/test_data/000077500000000000000000000000001434365020000161255ustar00rootroot00000000000000utidylib-0.9/tidy/test_data/test.html000066400000000000000000000001521434365020000177700ustar00rootroot00000000000000

woot


é utidylib-0.9/tidy/test_tidy.py000066400000000000000000000113671434365020000165470ustar00rootroot00000000000000from __future__ import unicode_literals import io import os import unittest import tidy import tidy.lib DATA_STORAGE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_data") class TidyTestCase(unittest.TestCase): input1 = "" input2 = "\n" + "

asdkfjhasldkfjhsldjas\n" * 100 test_file = os.path.join(DATA_STORAGE, "test.html") def default_docs(self): doc1 = tidy.parseString(self.input1) doc2 = tidy.parseString(self.input2) doc3 = tidy.parse(self.test_file, char_encoding="ascii") return (doc1, doc2, doc3) def test_bad_options(self): badopts = [{"foo": 1}] for opts in badopts: with self.assertRaisesRegex( tidy.InvalidOptionError, "not a valid Tidy option" ): tidy.parseString(self.input2, **opts) def test_bad_option_values(self): badopts = [{"indent": "---"}, {"indent_spaces": None}] for opts in badopts: with self.assertRaisesRegex( tidy.OptionArgError, "missing or malformed argument" ): tidy.parseString(self.input2, **opts) def test_encodings(self): text = ( open(self.test_file, "rb") .read() .decode("utf8") .encode("ascii", "xmlcharrefreplace") ) doc1u = tidy.parseString(text, input_encoding="ascii", output_encoding="latin1") self.assertTrue(doc1u.getvalue().find(b"\xe9") >= 0) doc2u = tidy.parseString(text, input_encoding="ascii", output_encoding="utf8") self.assertTrue(doc2u.getvalue().find(b"\xc3\xa9") >= 0) def test_error_lines(self): for doc in self.default_docs(): self.assertEqual(doc.errors[0].line, 1) def test_nonexisting(self): os.environ.pop("IGNORE_MISSING_TIDY", None) doc = tidy.parse(os.path.join(DATA_STORAGE, "missing.html")) self.assertEqual(str(doc).strip(), "") self.assertIn("missing.html", doc.errors[0].message) if doc.errors[0].severity == "E": self.assertEqual(doc.errors[0].severity, "E") self.assertTrue(str(doc.errors[0]).startswith("Error")) else: # Tidy 5.5.19 and newer self.assertEqual(doc.errors[0].severity, "D") self.assertTrue(str(doc.errors[0]).startswith("Document")) def test_options(self): doc1 = tidy.parseString( self.input1, add_xml_decl=1, show_errors=1, newline="CR", output_xhtml=1 ) self.assertIn("CDATA", str(doc1)) doc2 = tidy.parseString( "", add_xml_decl=1, show_errors=1, newline="CR", output_xhtml=1 ) self.assertTrue(str(doc2).startswith("", str(doc1)) self.assertIn("", str(doc2)) self.assertIn("", doc3.gettext()) def test_big(self): text = "x" * 16384 doc = tidy.parseString(f"{text}") self.assertIn(text, str(doc)) def test_unicode(self): doc = tidy.parseString("zkouška") self.assertIn("zkouška", doc.gettext()) def test_write(self): doc = tidy.parseString(self.input1) handle = io.BytesIO() doc.write(handle) self.assertEqual(doc.getvalue(), handle.getvalue()) def test_errors(self): doc = tidy.parseString(self.input1) for error in doc.errors: self.assertTrue(str(error).startswith("line")) self.assertTrue(repr(error).startswith("ReportItem")) def test_report_item(self): item = tidy.ReportItem("Invalid: error") self.assertEqual(item.get_severity(), "Invalid") def test_missing_load(self): with self.assertRaises(OSError): tidy.lib.Loader(libnames=("not-existing-library",)) def test_lib_from_environ(self): os.environ["TIDY_LIBRARY_FULL_PATH"] = "/foo/bar/tidy" loader = tidy.lib.Loader() expected_libnames = ( "/foo/bar/tidy", "libtidy.so", "libtidy.dylib", "tidy", "cygtidy-0-99-0", "libtidy-0.99.so.0", "libtidy-0.99.so.0.0.0", "libtidy.so.5", "libtidy.so.58", "libtidy.so.5deb1", "libtidy", "tidylib", ) self.assertEqual(loader.libnames, expected_libnames)