Skip to content

Commit

Permalink
Render rst documents
Browse files Browse the repository at this point in the history
  • Loading branch information
dstufft committed Feb 27, 2014
1 parent 73ca888 commit f3cde47
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
91 changes: 91 additions & 0 deletions readme/rst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright 2014 Donald Stufft
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, division, print_function

import io

from docutils.core import publish_parts
from docutils.writers.html4css1 import HTMLTranslator, Writer
from docutils.utils import SystemMessage

from .utils import Rendered


SETTINGS = {
# Cloaking email addresses provides a small amount of additional
# privacy protection for email addresses inside of a chunk of ReST.
"cloak_email_addresses": True,

# Prevent a lone top level heading from being promoted to document
# title, and thus second level headings from being promoted to top
# level.
"doctitle_xform": True,

# Set our initial header level
"initial_header_level": 2,

# Prevent local files from being included into the rendered output.
# This is a security concern because people can insert files
# that are part of the system, such as /etc/passwd.
"file_insertion_enabled": False,

# Halt rendering and throw an exception if there was any errors or
# warnings from docutils.
"halt_level": 2,

This comment has been minimized.

Copy link
@msabramo

msabramo Dec 18, 2014

Contributor

Why set halt_level to 2? Maybe to be compatible with what PyPI is currently doing? Because I personally find that aspect of PyPI to be rather annoying, as PyPI is much stricter than tools that people would think to run locally, resulting in a lot of broken descriptions on PyPI (see https://bitbucket.org/pypa/pypi/pull-request/60/fix-bb-214-make-rst-rendering-not-fail-for/diff).


# Output math blocks as LaTeX that can be interpreted by MathJax for
# a prettier display of Math formulas.
"math_output": "MathJax",

# Disable raw html as enabling it is a security risk, we do not want
# people to be able to include any old HTML in the final output.
"raw_enabled": False,

# Disable all system messages from being reported.
"report_level": 5,

# Use typographic quotes, and transform --, ---, and ... into their
# typographic counterparts.
"smart_quotes": True,

# Strip all comments from the rendered output.
"strip_comments": True,

# Use the short form of syntax highlighting so that the generated
# Pygments CSS can be used to style the output.
"syntax_highlight": "short",
}


def render(markup):
# Use a io.StringIO as the warning stream to prevent warnings from being
# printed to sys.stderr.
settings = SETTINGS.copy()
settings["warning_stream"] = io.StringIO()

writer = Writer()
writer.translator_class = HTMLTranslator

try:
parts = publish_parts(
markup,
writer=writer,
settings_overrides=settings,
)
except SystemMessage:
rendered = None
else:
rendered = parts.get("fragment")

return Rendered.from_rendered(markup, rendered)
36 changes: 36 additions & 0 deletions readme/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2014 Donald Stufft
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, division, print_function

import six


class Rendered(six.text_type):

raw = None
rendered = False

@classmethod
def from_rendered(cls, raw, rendered=None):
# Use the rendered content and fallback to the raw content
content = rendered if rendered is not None else raw

# Create an instance of this type with the content
obj = cls(content)

# Store some details about the content
obj.raw = raw
obj.rendered = True if rendered is not None else False

return obj
5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,10 @@
"Programming Language :: Python :: Implementation :: PyPy",
],

install_requires=[
"docutils",
"six",
],

packages=setuptools.find_packages(exclude=["tests", "tests.*"]),
)

0 comments on commit f3cde47

Please sign in to comment.