diff options
author | David Lord <davidism@gmail.com> | 2018-05-04 07:37:47 -0700 |
---|---|---|
committer | David Lord <davidism@gmail.com> | 2018-05-04 07:46:55 -0700 |
commit | b7a31f5f151a3641975df1b113573947efe923a8 (patch) | |
tree | ed36b41fcdae730b66fd3fd11d16eed8dae806b9 /docs | |
parent | f6a491d9348597e67e3bed5f4d0ff3cbf38857e3 (diff) | |
download | markupsafe-b7a31f5f151a3641975df1b113573947efe923a8.tar.gz |
add sphinx docs, update docstrings
Diffstat (limited to 'docs')
-rw-r--r-- | docs/Makefile | 20 | ||||
-rw-r--r-- | docs/conf.py | 72 | ||||
-rw-r--r-- | docs/escaping.rst | 21 | ||||
-rw-r--r-- | docs/formatting.rst | 77 | ||||
-rw-r--r-- | docs/html.rst | 51 | ||||
-rw-r--r-- | docs/index.rst | 35 | ||||
-rw-r--r-- | docs/make.bat | 36 |
7 files changed, 312 insertions, 0 deletions
diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d10ee88 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = MarkupSafe +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..0fe75a4 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function + +from pallets_sphinx_themes import ProjectLink, get_version + +# Project -------------------------------------------------------------- + +project = 'MarkupSafe' +copyright = '2010 Pallets team' +author = 'Pallets team' +release, version = get_version('MarkupSafe') + +# General -------------------------------------------------------------- + +master_doc = 'index' + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', +] + +intersphinx_mapping = { + 'python': ('https://docs.python.org/3/', None), +} + +# HTML ----------------------------------------------------------------- + +html_theme = 'flask' +html_context = { + 'project_links': [ + ProjectLink( + 'Donate to Pallets', + 'https://psfmember.org/civicrm/contribute/transact?reset=1&id=20'), + ProjectLink( + 'MarkupSafe Website', 'https://palletsprojects.com/p/markupsafe/'), + ProjectLink('PyPI Releases', 'https://pypi.org/project/MarkupSafe/'), + ProjectLink('Source Code', 'https://github.com/pallets/markupsafe/'), + ProjectLink( + 'Issue Tracker', 'https://github.com/pallets/MarkupSafe/issues/'), + ], +} +html_sidebars = { + 'index': [ + 'project.html', + 'searchbox.html', + ], + '**': [ + 'localtoc.html', + 'relations.html', + 'searchbox.html', + ] +} +html_show_sourcelink = False + +# LaTeX ---------------------------------------------------------------- + +latex_documents = [ + ( + master_doc, 'MarkupSafe.tex', 'MarkupSafe Documentation', + 'Pallets team', 'manual' + ), +] +latex_use_modindex = False +latex_elements = { + 'papersize': 'a4paper', + 'pointsize': '12pt', +} +latex_use_parts = True + +# linkcheck ------------------------------------------------------------ + +linkcheck_anchors = False diff --git a/docs/escaping.rst b/docs/escaping.rst new file mode 100644 index 0000000..d99674d --- /dev/null +++ b/docs/escaping.rst @@ -0,0 +1,21 @@ +.. module:: markupsafe + +Working With Safe Text +====================== + +.. autofunction:: escape + +.. autoclass:: Markup + :members: escape, unescape, striptags + + +Optional Values +--------------- + +.. autofunction:: escape_silent + + +Convert an Object to a String +----------------------------- + +.. autofunction:: soft_unicode diff --git a/docs/formatting.rst b/docs/formatting.rst new file mode 100644 index 0000000..c425134 --- /dev/null +++ b/docs/formatting.rst @@ -0,0 +1,77 @@ +.. currentmodule:: markupsafe + +String Formatting +================= + +The :class:`Markup` class can be used as a format string. Objects +formatted into a markup string will be escaped first. + + +Format Method +------------- + +The ``format`` method extends the standard :meth:`str.format` behavior +to use an ``__html_format__`` method. + +#. If an object has an ``__html_format__`` method, it is called as a + replacement for the ``__format__`` method. It is passed a format + specifier if it's given. The method must return a string or + :class:`Markup` instance. + +#. If an object has an ``__html__`` method, it is called. If a format + specifier was passed and the class defined ``__html__`` but not + ``__html_format__``, a ``ValueError`` is raised. + +#. Otherwise Python's default format behavior is used and the result + is escaped. + +For example, to implement a ``User`` that wraps its ``name`` in a +``span`` tag, and adds a link when using the ``'link'`` format +specifier: + +.. code-block:: python + + class User(object): + def __init__(self, id, name): + self.id = id + self.name = name + + def __html_format__(self, format_spec): + if format_spec == 'link': + return Markup( + '<a href="/user/{}">{}</a>' + ).format(self.id, self.__html__()) + elif format_spec: + raise ValueError('Invalid format spec') + return self.__html__() + + def __html__(self): + return Markup( + '<span class="user">{0}</span>' + ).format(self.name) + + +.. code-block:: pycon + + >>> user = User(3, '<script>') + >>> escape(user) + Markup('<span class="user"><script></span>') + >>> Markup('<p>User: {user:link}').format(user=user) + Markup('<p>User: <a href="/user/3"><span class="user"><script></span></a> + +See Python's docs on :ref:`format string syntax <python:formatstrings>`. + + +printf-style Formatting +----------------------- + +Besides escaping, there's no special behavior involved with percent +formatting. + +.. code-block:: pycon + + >>> user = User(3, '<script>') + >>> Markup('<a href="/user/%d">"%s</a>') % (user.id, user.name) + Markup('<a href="/user/3"><script></a>') + +See Python's docs on :ref:`printf-style formatting <python:old-string-formatting>`. diff --git a/docs/html.rst b/docs/html.rst new file mode 100644 index 0000000..3a0c11b --- /dev/null +++ b/docs/html.rst @@ -0,0 +1,51 @@ +.. currentmodule:: markupsafe + +HTML Representations +==================== + +In many frameworks, if a class implements an ``__html__`` method it +will be used to get the object's representation in HTML. MarkupSafe's +:func:`escape` function and :class:`Markup` class understand and +implement this method. If an object has an ``__html__`` method it will +be called rather than converting the object to a string, and the result +will be assumed safe and not escaped. + +For example, an ``Image`` class might automatically generate an +``<img>`` tag: + +.. code-block:: python + + class Image: + def __init__(self, url): + self.url = url + + def __html__(self): + return '<img src="%s">' % self.url + +.. code-block:: pycon + + >>> img = Image('/static/logo.png') + >>> Markup(img) + Markup('<img src="/static/logo.png">') + +Since this bypasses escaping, you need to be careful about using +user-provided data in the output. For example, a user's display name +should still be escaped: + +.. code-block:: python + + class User: + def __init__(self, id, name): + self.id = id + self.name = name + + def __html__(self): + return '<a href="/user/{}">{}</a>'.format( + self.id, escape(self.name) + ) + +.. code-block:: pycon + + >>> user = User(3, '<script>') + >>> escape(user) + Markup('<a href="/users/3"><script></a>') diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..016fd1c --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,35 @@ +.. currentmodule:: markupsafe + +MarkupSafe +========== + +MarkupSafe escapes characters so text is safe to use in HTML and XML. +Characters that have special meanings are replaced so that they display +as the actual characters. This mitigates injection attacks, meaning +untrusted user input can safely be displayed on a page. + +The :func:`escape` function escapes text and returns a :class:`Markup` +object. The object won't be escaped anymore, but any text that is used +with it will be, ensuring that the result remains safe to use in HTML. + +>>> from markupsafe import escape +>>> hello = escape('<em>Hello</em>') +>>> hello +Markup('<em>Hello</em>') +>>> escape(hello) +Markup('<em>Hello</em>') +>>> hello + ' <strong>World</strong>' +Markup('<em>Hello</em> <strong>World</strong>') + +.. note:: + + The docs assume you're using Python 3. The terms "text" and "string" + refer to the :class:`str` class. In Python 2, this would be the + ``unicode`` class instead. + +.. toctree:: + :maxdepth: 2 + + escaping + html + formatting diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..7639bf3 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=MarkupSafe + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 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 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd |