summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/Makefile19
-rw-r--r--docs/changes.rst4
-rw-r--r--docs/conf.py52
-rw-r--r--docs/escaping.rst21
-rw-r--r--docs/formatting.rst77
-rw-r--r--docs/html.rst49
-rw-r--r--docs/index.rst47
-rw-r--r--docs/license.rst4
-rw-r--r--docs/make.bat35
9 files changed, 308 insertions, 0 deletions
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..5128596
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,19 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+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)
diff --git a/docs/changes.rst b/docs/changes.rst
new file mode 100644
index 0000000..955deaf
--- /dev/null
+++ b/docs/changes.rst
@@ -0,0 +1,4 @@
+Changes
+=======
+
+.. include:: ../CHANGES.rst
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..bba34c0
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,52 @@
+from pallets_sphinx_themes import get_version
+from pallets_sphinx_themes import ProjectLink
+
+# Project --------------------------------------------------------------
+
+project = "MarkupSafe"
+copyright = "2010 Pallets"
+author = "Pallets"
+release, version = get_version("MarkupSafe")
+
+# General --------------------------------------------------------------
+
+master_doc = "index"
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.intersphinx",
+ "pallets_sphinx_themes",
+ "sphinxcontrib.log_cabinet",
+ "sphinx_issues",
+]
+autodoc_typehints = "description"
+intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)}
+issues_github_path = "pallets/markupsafe"
+
+# HTML -----------------------------------------------------------------
+
+html_theme = "jinja"
+html_theme_options = {"index_sidebar_logo": False}
+html_context = {
+ "project_links": [
+ ProjectLink("Donate", "https://palletsprojects.com/donate"),
+ 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/"),
+ ProjectLink("Website", "https://palletsprojects.com/p/markupsafe/"),
+ ProjectLink("Twitter", "https://twitter.com/PalletsTeam"),
+ ProjectLink("Chat", "https://discord.gg/pallets"),
+ ]
+}
+html_sidebars = {
+ "index": ["project.html", "localtoc.html", "searchbox.html", "ethicalads.html"],
+ "**": ["localtoc.html", "relations.html", "searchbox.html", "ethicalads.html"],
+}
+singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]}
+html_title = f"MarkupSafe Documentation ({version})"
+html_show_sourcelink = False
+
+# LaTeX ----------------------------------------------------------------
+
+latex_documents = [
+ (master_doc, f"MarkupSafe-{version}.tex", html_title, author, "manual")
+]
diff --git a/docs/escaping.rst b/docs/escaping.rst
new file mode 100644
index 0000000..9e7000a
--- /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_str
diff --git a/docs/formatting.rst b/docs/formatting.rst
new file mode 100644
index 0000000..c14f917
--- /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..dec87af
--- /dev/null
+++ b/docs/html.rst
@@ -0,0 +1,49 @@
+.. 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 f'<img src="{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 f'<a href="/user/{self.id}">{escape(self.name)}</a>'
+
+.. 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..5c45e64
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,47 @@
+.. 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;')
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+ pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+Table of Contents
+-----------------
+
+.. toctree::
+ :maxdepth: 2
+
+ escaping
+ html
+ formatting
+ license
+ changes
diff --git a/docs/license.rst b/docs/license.rst
new file mode 100644
index 0000000..a53a98c
--- /dev/null
+++ b/docs/license.rst
@@ -0,0 +1,4 @@
+BSD-3-Clause License
+====================
+
+.. include:: ../LICENSE.rst
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..7893348
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+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