summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2018-03-18 12:32:23 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2018-03-18 12:33:03 +0900
commitc271cc45424bdc75b280fb6311cfcb439ab27e73 (patch)
tree514ad46f6d026a6ac8fe5eea4b38ab7ff866984f
parentdc3faa57b47c0c0e1ded6740d9a8912d26ded76c (diff)
downloadsphinx-git-c271cc45424bdc75b280fb6311cfcb439ab27e73.tar.gz
Use template for generating .qhp file
-rw-r--r--sphinx/builders/qthelp.py53
-rw-r--r--sphinx/templates/qthelp/project.qhp24
-rw-r--r--tests/roots/test-need-escaped/bar.rst2
-rw-r--r--tests/roots/test-need-escaped/baz.rst2
-rw-r--r--tests/roots/test-need-escaped/conf.py5
-rw-r--r--tests/roots/test-need-escaped/foo.rst15
-rw-r--r--tests/roots/test-need-escaped/index.rst30
-rw-r--r--tests/roots/test-need-escaped/quux.rst2
-rw-r--r--tests/roots/test-need-escaped/qux.rst1
-rw-r--r--tests/test_build_qthelp.py28
10 files changed, 110 insertions, 52 deletions
diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py
index cf9776131..ef729e420 100644
--- a/sphinx/builders/qthelp.py
+++ b/sphinx/builders/qthelp.py
@@ -40,37 +40,6 @@ logger = logging.getLogger(__name__)
_idpattern = re.compile(
r'(?P<title>.+) (\((class in )?(?P<id>[\w\.]+)( (?P<descr>\w+))?\))$')
-# Qt Help Project (.qhp)
-# This is the input file for the help generator.
-# It contains the table of contents, indices and references to the
-# actual documentation files (*.html).
-# In addition it defines a unique namespace for the documentation.
-project_template = u'''\
-<?xml version="1.0" encoding="utf-8" ?>
-<QtHelpProject version="1.0">
- <namespace>%(namespace)s</namespace>
- <virtualFolder>doc</virtualFolder>
- <customFilter name="%(project)s %(version)s">
- <filterAttribute>%(outname)s</filterAttribute>
- <filterAttribute>%(version)s</filterAttribute>
- </customFilter>
- <filterSection>
- <filterAttribute>%(outname)s</filterAttribute>
- <filterAttribute>%(version)s</filterAttribute>
- <toc>
- <section title="%(title)s" ref="%(masterdoc)s.html">
-%(sections)s
- </section>
- </toc>
- <keywords>
-%(keywords)s
- </keywords>
- <files>
-%(files)s
- </files>
- </filterSection>
-</QtHelpProject>
-'''
section_template = '<section title="%(title)s" ref="%(ref)s"/>'
file_template = ' ' * 12 + '<file>%(filename)s</file>'
@@ -195,16 +164,12 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
# write the project file
with codecs.open(path.join(outdir, outname + '.qhp'), 'w', 'utf-8') as f: # type: ignore # NOQA
- f.write(project_template % {
- 'outname': htmlescape(outname),
- 'title': htmlescape(self.config.html_title),
- 'version': htmlescape(self.config.version),
- 'project': htmlescape(self.config.project),
- 'namespace': htmlescape(nspace),
- 'masterdoc': htmlescape(self.config.master_doc),
- 'sections': sections,
- 'keywords': keywords,
- 'files': projectfiles})
+ content = render_file('project.qhp', outname=outname,
+ title=self.config.html_title, version=self.config.version,
+ project=self.config.project, namespace=nspace,
+ master_doc=self.config.master_doc,
+ sections=sections, keywords=keywords, files=projectfiles)
+ f.write(content)
homepage = 'qthelp://' + posixpath.join(
nspace, 'doc', self.get_target_uri(self.config.master_doc))
@@ -279,9 +244,9 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
if id:
item = ' ' * 12 + '<keyword name="%s" id="%s" ref="%s"/>' % (
- name, id, ref[1])
+ name, id, htmlescape(ref[1]))
else:
- item = ' ' * 12 + '<keyword name="%s" ref="%s"/>' % (name, ref[1])
+ item = ' ' * 12 + '<keyword name="%s" ref="%s"/>' % (name, htmlescape(ref[1]))
item.encode('ascii', 'xmlcharrefreplace')
return item
@@ -289,7 +254,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
# type: (unicode, List[Any], Any) -> List[unicode]
keywords = [] # type: List[unicode]
- title = htmlescape(title)
+ title = htmlescape(title, quote=True)
# if len(refs) == 0: # XXX
# write_param('See Also', title)
if len(refs) == 1:
diff --git a/sphinx/templates/qthelp/project.qhp b/sphinx/templates/qthelp/project.qhp
new file mode 100644
index 000000000..92a7af0e8
--- /dev/null
+++ b/sphinx/templates/qthelp/project.qhp
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<QtHelpProject version="1.0">
+ <namespace>{{ namespace|e }}</namespace>
+ <virtualFolder>doc</virtualFolder>
+ <customFilter name="{{ project|e }} {{ version|e }}">
+ <filterAttribute>{{ outname|e }}</filterAttribute>
+ <filterAttribute>{{ version|e }}</filterAttribute>
+ </customFilter>
+ <filterSection>
+ <filterAttribute>{{ outname|e }}</filterAttribute>
+ <filterAttribute>{{ version|e }}</filterAttribute>
+ <toc>
+ <section title="{{ title|e }}" ref="{{ master_doc|e }}.html">
+{{ sections }}
+ </section>
+ </toc>
+ <keywords>
+{{ keywords }}
+ </keywords>
+ <files>
+{{ files }}
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/tests/roots/test-need-escaped/bar.rst b/tests/roots/test-need-escaped/bar.rst
new file mode 100644
index 000000000..1cccd3cb7
--- /dev/null
+++ b/tests/roots/test-need-escaped/bar.rst
@@ -0,0 +1,2 @@
+bar
+===
diff --git a/tests/roots/test-need-escaped/baz.rst b/tests/roots/test-need-escaped/baz.rst
new file mode 100644
index 000000000..52e2e72ac
--- /dev/null
+++ b/tests/roots/test-need-escaped/baz.rst
@@ -0,0 +1,2 @@
+baz
+===
diff --git a/tests/roots/test-need-escaped/conf.py b/tests/roots/test-need-escaped/conf.py
new file mode 100644
index 000000000..d65a22e07
--- /dev/null
+++ b/tests/roots/test-need-escaped/conf.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+
+master_doc = 'index'
+project = 'need <b>"escaped"</b> project'
+smartquotes = False
diff --git a/tests/roots/test-need-escaped/foo.rst b/tests/roots/test-need-escaped/foo.rst
new file mode 100644
index 000000000..70859b3fc
--- /dev/null
+++ b/tests/roots/test-need-escaped/foo.rst
@@ -0,0 +1,15 @@
+<foo>
+=====
+
+.. toctree::
+
+ quux
+
+foo "1"
+-------
+
+foo.1-1
+^^^^^^^
+
+foo.2
+-----
diff --git a/tests/roots/test-need-escaped/index.rst b/tests/roots/test-need-escaped/index.rst
new file mode 100644
index 000000000..9ef74e00a
--- /dev/null
+++ b/tests/roots/test-need-escaped/index.rst
@@ -0,0 +1,30 @@
+.. Sphinx Tests documentation master file, created by sphinx-quickstart on Wed Jun 4 23:49:58 2008.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to Sphinx Tests's documentation!
+========================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+ :numbered:
+ :caption: Table of Contents
+ :name: mastertoc
+
+ foo
+ bar
+ http://sphinx-doc.org/
+ baz
+ qux
+
+.. index::
+ pair: "subsection"; <subsection>
+
+----------
+subsection
+----------
+
+subsubsection
+-------------
diff --git a/tests/roots/test-need-escaped/quux.rst b/tests/roots/test-need-escaped/quux.rst
new file mode 100644
index 000000000..07dd0a0a3
--- /dev/null
+++ b/tests/roots/test-need-escaped/quux.rst
@@ -0,0 +1,2 @@
+quux
+====
diff --git a/tests/roots/test-need-escaped/qux.rst b/tests/roots/test-need-escaped/qux.rst
new file mode 100644
index 000000000..26176b947
--- /dev/null
+++ b/tests/roots/test-need-escaped/qux.rst
@@ -0,0 +1 @@
+qux.rst has no section title
diff --git a/tests/test_build_qthelp.py b/tests/test_build_qthelp.py
index 3beddf554..a0d4fcf2a 100644
--- a/tests/test_build_qthelp.py
+++ b/tests/test_build_qthelp.py
@@ -39,26 +39,37 @@ def test_qthelp_basic(app, status, warning):
assert '<file>Python.qch</file>' in qhcp
-@pytest.mark.sphinx('qthelp', testroot='toctree')
-def test_qthelp_toctree(app, status, warning):
+@pytest.mark.sphinx('qthelp', testroot='need-escaped')
+def test_qthelp_escaped(app, status, warning):
app.builder.build_all()
- et = etree_parse(app.outdir / 'Python.qhp')
+ et = etree_parse(app.outdir / 'needbescapedbproject.qhp')
+ customFilter = et.find('.//customFilter')
+ assert len(customFilter) == 2
+ assert customFilter.attrib == {'name': 'need <b>"escaped"</b> project '}
+ assert customFilter[0].text == 'needbescapedbproject'
+ assert customFilter[1].text is None
+
toc = et.find('.//toc')
assert len(toc) == 1
- assert toc[0].attrib == {'title': 'Python documentation',
+ assert toc[0].attrib == {'title': 'need <b>"escaped"</b> project documentation',
'ref': 'index.html'}
assert len(toc[0]) == 4
- assert toc[0][0].attrib == {'title': 'foo', 'ref': 'foo.html'}
- assert toc[0][1].attrib == {'title': 'bar', 'ref': 'bar.html'}
+ assert toc[0][0].attrib == {'title': '<foo>', 'ref': 'foo.html'}
assert toc[0][0][0].attrib == {'title': 'quux', 'ref': 'quux.html'}
- assert toc[0][0][1].attrib == {'title': 'foo.1', 'ref': 'foo.html#foo-1'}
+ assert toc[0][0][1].attrib == {'title': 'foo "1"', 'ref': 'foo.html#foo-1'}
assert toc[0][0][1][0].attrib == {'title': 'foo.1-1', 'ref': 'foo.html#foo-1-1'}
assert toc[0][0][2].attrib == {'title': 'foo.2', 'ref': 'foo.html#foo-2'}
+ assert toc[0][1].attrib == {'title': 'bar', 'ref': 'bar.html'}
assert toc[0][2].attrib == {'title': 'http://sphinx-doc.org/',
'ref': 'http://sphinx-doc.org/'}
assert toc[0][3].attrib == {'title': 'baz', 'ref': 'baz.html'}
+ keywords = et.find('.//keywords')
+ assert len(keywords) == 2
+ assert keywords[0].attrib == {'name': '<subsection>', 'ref': 'index.html#index-0'}
+ assert keywords[1].attrib == {'name': '"subsection"', 'ref': 'index.html#index-0'}
+
@pytest.mark.sphinx('qthelp', testroot='basic')
def test_qthelp_namespace(app, status, warning):
@@ -101,7 +112,8 @@ def test_qthelp_title(app, status, warning):
app.builder.build_all()
qhp = (app.outdir / 'Python.qhp').text()
- assert '<section title="Sphinx &lt;b&gt;"full"&lt;/b&gt; title" ref="index.html">' in qhp
+ assert ('<section title="Sphinx &lt;b&gt;&#34;full&#34;&lt;/b&gt; title" ref="index.html">'
+ in qhp)
qhcp = (app.outdir / 'Python.qhcp').text()
assert '<title>Sphinx &lt;b&gt;&#34;short&#34;&lt;/b&gt; title</title>' in qhcp