Blame pagure/doc_utils.py

Pierre-Yves Chibon 33b534
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
"""
Pierre-Yves Chibon d16623
 (c) 2014-2016 - Copyright Red Hat Inc
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
 Authors:
Pierre-Yves Chibon 9f7aba
   Ralph Bean <rbean@redhat.com></rbean@redhat.com>
Pierre-Yves Chibon 9f7aba
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
"""
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Aurélien Bompard dcf6f6
Pierre-Yves Chibon 9f7aba
import docutils
Pierre-Yves Chibon 1a4999
import docutils.core
Pierre-Yves Chibon 83a3ac
import docutils.examples
Shengjing Zhu 0ab13c
import jinja2
Pierre-Yves Chibon 195dd8
import kitchen.text.converters as ktc
Pierre-Yves Chibon 9f7aba
import markupsafe
Pierre-Yves Chibon 83a3ac
import textwrap
Pierre-Yves Chibon 9f7aba
Slavek Kabrda 45252f
from pagure.config import config as pagure_config
Pierre-Yves Chibon 930073
import pagure.lib.query
Pierre-Yves Chibon 195dd8
import pagure.lib.encoding_utils
Pierre-Yves Chibon d16623
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon abd4d7
def modify_rst(rst, view_file_url=None):
Pierre-Yves Chibon 9f7aba
    """ Downgrade some of our rst directives if docutils is too old. """
Pierre-Yves Chibon c073d7
    if view_file_url:
Pierre-Yves Chibon 9c2953
        rst = rst.replace(".. image:: ", ".. image:: %s" % view_file_url)
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon e04c77
    # We catch Exception if we want :-p
Pierre-Yves Chibon 22a554
    # pylint: disable=broad-except
Pierre-Yves Chibon 9f7aba
    try:
Pierre-Yves Chibon 9f7aba
        # The rst features we need were introduced in this version
Pierre-Yves Chibon 9f7aba
        minimum = [0, 9]
Pierre-Yves Chibon 9c2953
        version = [int(cpt) for cpt in docutils.__version__.split(".")]
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
        # If we're at or later than that version, no need to downgrade
Pierre-Yves Chibon 9f7aba
        if version >= minimum:
Pierre-Yves Chibon 9f7aba
            return rst
Pierre-Yves Chibon 9f7aba
    except Exception:  # pragma: no cover
Pierre-Yves Chibon 9f7aba
        # If there was some error parsing or comparing versions, run the
Pierre-Yves Chibon 9f7aba
        # substitutions just to be safe.
Pierre-Yves Chibon 9f7aba
        pass
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
    # On Fedora this will never work as the docutils version is to recent
Pierre-Yves Chibon 9f7aba
    # Otherwise, make code-blocks into just literal blocks.
Pierre-Yves Chibon 9c2953
    substitutions = {".. code-block:: javascript": "::"}  # pragma: no cover
Pierre-Yves Chibon abd4d7
Pierre-Yves Chibon 9f7aba
    for old, new in substitutions.items():  # pragma: no cover
Pierre-Yves Chibon 9f7aba
        rst = rst.replace(old, new)
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
    return rst  # pragma: no cover
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
def modify_html(html):
Pierre-Yves Chibon 9f7aba
    """ Perform style substitutions where docutils doesn't do what we want.
Pierre-Yves Chibon 9f7aba
    """
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
    substitutions = {
Pierre-Yves Chibon 9c2953
        '<tt class="docutils literal">': "",</tt>
Pierre-Yves Chibon 9c2953
        "": "",
Pierre-Yves Chibon 9c2953
        "$$FLAG_STATUSES_COMMAS$$": ", ".join(
Pierre-Yves Chibon 9c2953
            sorted(pagure_config["FLAG_STATUSES_LABELS"].keys())
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
        "$$FLAG_SUCCESS$$": pagure_config["FLAG_SUCCESS"],
Pierre-Yves Chibon 9c2953
        "$$FLAG_FAILURE$$": pagure_config["FLAG_FAILURE"],
Pierre-Yves Chibon 9c2953
        "$$FLAG_PENDING$$": pagure_config["FLAG_PENDING"],
Pierre-Yves Chibon 9f7aba
    }
Pierre-Yves Chibon 9f7aba
    for old, new in substitutions.items():
Pierre-Yves Chibon 9f7aba
        html = html.replace(old, new)
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
    return html
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon abd4d7
def convert_doc(rst_string, view_file_url=None):
Pierre-Yves Chibon 9f7aba
    """ Utility to load an RST file and turn it into fancy HTML. """
Pierre-Yves Chibon abd4d7
    rst = modify_rst(rst_string, view_file_url)
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon 9c2953
    overrides = {"report_level": "quiet"}
Pierre-Yves Chibon fd8afd
    try:
Pierre-Yves Chibon fd8afd
        html = docutils.core.publish_parts(
Pierre-Yves Chibon 9c2953
            source=rst, writer_name="html", settings_overrides=overrides
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 1fc6d8
    except Exception:
Pierre-Yves Chibon 9c2953
        return "
%s
" % jinja2.escape(rst)
Pierre-Yves Chibon fd8afd
Pierre-Yves Chibon fd8afd
    else:
Pierre-Yves Chibon 1a4999
Pierre-Yves Chibon 9c2953
        html_string = html["html_body"]
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon fd8afd
        html_string = modify_html(html_string)
Pierre-Yves Chibon 9f7aba
Pierre-Yves Chibon fd8afd
        html_string = markupsafe.Markup(html_string)
Pierre-Yves Chibon fd8afd
        return html_string
Pierre-Yves Chibon c8507f
Pierre-Yves Chibon c8507f
Pierre-Yves Chibon abd4d7
def convert_readme(content, ext, view_file_url=None):
Pierre-Yves Chibon 9c2953
    """ Convert the provided content according to the extension of the file
Pierre-Yves Chibon c8507f
    provided.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 195dd8
    output = pagure.lib.encoding_utils.decode(ktc.to_bytes(content))
Pierre-Yves Chibon 761436
    safe = False
Pierre-Yves Chibon 9c2953
    if ext and ext in [".rst"]:
Pierre-Yves Chibon 761436
        safe = True
Pierre-Yves Chibon 195dd8
        output = convert_doc(output, view_file_url)
Pierre-Yves Chibon 9c2953
    elif ext and ext in [".mk", ".md", ".markdown"]:
Pierre-Yves Chibon 930073
        output = pagure.lib.query.text2markdown(output, readme=True)
Pierre-Yves Chibon 761436
        safe = True
Pierre-Yves Chibon 9c2953
    elif not ext or (ext and ext in [".text", ".txt"]):
Pierre-Yves Chibon 761436
        safe = True
Pierre-Yves Chibon 9c2953
        output = "
%s
" % jinja2.escape(output)
Pierre-Yves Chibon 761436
    return output, safe
Pierre-Yves Chibon 83a3ac
Pierre-Yves Chibon 83a3ac
Pierre-Yves Chibon 83a3ac
def load_doc(endpoint):
Pierre-Yves Chibon 83a3ac
    """ Utility to load an RST file and turn it into fancy HTML. """
Pierre-Yves Chibon 83a3ac
Aurélien Bompard 831553
    rst = modify_rst(textwrap.dedent(endpoint.__doc__))
Pierre-Yves Chibon 83a3ac
Pierre-Yves Chibon 83a3ac
    api_docs = docutils.examples.html_body(rst)
Pierre-Yves Chibon 83a3ac
Pierre-Yves Chibon 83a3ac
    api_docs = modify_html(api_docs)
Pierre-Yves Chibon 83a3ac
Pierre-Yves Chibon 83a3ac
    api_docs = markupsafe.Markup(api_docs)
Pierre-Yves Chibon 83a3ac
    return api_docs