aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2018-05-04 07:37:47 -0700
committerDavid Lord <davidism@gmail.com>2018-05-04 07:46:55 -0700
commitb7a31f5f151a3641975df1b113573947efe923a8 (patch)
treeed36b41fcdae730b66fd3fd11d16eed8dae806b9 /docs
parentf6a491d9348597e67e3bed5f4d0ff3cbf38857e3 (diff)
downloadmarkupsafe-b7a31f5f151a3641975df1b113573947efe923a8.tar.gz
add sphinx docs, update docstrings
Diffstat (limited to 'docs')
-rw-r--r--docs/Makefile20
-rw-r--r--docs/conf.py72
-rw-r--r--docs/escaping.rst21
-rw-r--r--docs/formatting.rst77
-rw-r--r--docs/html.rst51
-rw-r--r--docs/index.rst35
-rw-r--r--docs/make.bat36
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">&lt;script&gt;</span>')
+ >>> Markup('<p>User: {user:link}').format(user=user)
+ Markup('<p>User: <a href="/user/3"><span class="user">&lt;script&gt;</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">&lt;script&gt;</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">&lt;script&gt;</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('&lt;em&gt;Hello&lt;/em&gt;')
+>>> escape(hello)
+Markup('&lt;em&gt;Hello&lt;/em&gt;')
+>>> hello + ' <strong>World</strong>'
+Markup('&lt;em&gt;Hello&lt;/em&gt; &lt;strong&gt;World&lt;/strong&gt;')
+
+.. 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