Skip to content

Commit a1bfebf

Browse files
authored
feat: Support :nocomment: and :isso-thread-id: docinfos (#5)
1 parent 49323d5 commit a1bfebf

File tree

3 files changed

+70
-23
lines changed

3 files changed

+70
-23
lines changed

docs/changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ Change Log
1818
Version 1.x
1919
===========
2020

21+
.. version:: 1.2
22+
:date: 2024-09-19
23+
24+
- Skip document with ``:nocomment:`` docinfos (:pull:`5`)
25+
- Allow user specifying Isso thread ID via ``:isso-id:`` docinfo (:pull:`5`)
26+
2127
.. version:: 1.1
2228
:date: 2024-05-01
2329

docs/usage.rst

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,35 @@ Usage
33
=====
44

55
The ``isso`` directive is used to insert a Isso comment box.
6-
The docname of current document is used as Isso thread ID.
6+
Each comment thread is distinguished by Isso Thread ID (``data-isso-id``),
7+
which can be specified via the ``id`` option (see below) or via ``:isso-id``
8+
docinfo. If no thread ID given, ``/{docname}`` will be used.
79

810
The directive supports the following options:
911

1012
:id: (text)
11-
Specify a thread ID rather than use docname
13+
Specify a thread ID, optional
1214
:title: (text)
1315
Specify a thread title rather than use document title
16+
17+
Enable comments for all documents
18+
=================================
19+
20+
Use Sphinx's ``rst_epilog`` confval to append the ``isso`` directive at the
21+
end of every source file. For example:
22+
23+
.. code:: python
24+
25+
rst_epilog = """
26+
.. isso::
27+
"""
28+
29+
Disable comments for specified document
30+
---------------------------------------
31+
32+
This extension respects the ``:nocomment`` docinfo__:
33+
34+
If set, the web application won’t display a comment form for a page generated
35+
from this source file.
36+
37+
__ https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html#file-wide-metadata

src/sphinxnotes/isso/__init__.py

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import posixpath
1515

1616
from docutils import nodes
17-
from docutils.parsers.rst import directives, Directive
17+
from docutils.parsers.rst import directives
18+
from sphinx.util.docutils import SphinxDirective
19+
from sphinx.writers.html5 import HTML5Translator
1820

1921
if TYPE_CHECKING:
2022
from sphinx.application import Sphinx
@@ -51,24 +53,38 @@ def ext_config_to_isso_config(key:str, value:Any) -> Tuple[str,str]:
5153
return (key, value)
5254

5355

54-
class IssoNode(nodes.General, nodes.Element):
56+
class IssoNode(nodes.General, nodes.Element): pass
5557

56-
@staticmethod
57-
def visit(self, node):
58-
kwargs = {
59-
'data-isso-id': node['thread-id'],
60-
}
61-
if node.get('thread-title'):
62-
kwargs['data-title'] = node['thread-title']
63-
self.body.append(self.starttag(node, 'section', '', **kwargs))
58+
def html_visit_isso_node(self: HTML5Translator, node):
59+
docname = node['docname']
60+
metadata = self.builder.env.metadata[docname]
61+
62+
# If docinfo :nocomments: is set, won’t display a comment form for a page
63+
# generated from this source file.
64+
#
65+
# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html
66+
if 'nocomments' in metadata:
67+
raise nodes.SkipNode
6468

69+
thread_id = node.get('thread-id') or \
70+
metadata.get('isso-id') or \
71+
'/' + docname
72+
if not thread_id.startswith('/'):
73+
logger.warning(f'isso thread-id {thread_id} doesn\'t start with slash', location=node)
74+
75+
kwargs = {
76+
'data-isso-id': thread_id,
77+
}
78+
if node.get('thread-title'):
79+
kwargs['data-title'] = node['thread-title']
80+
self.body.append(self.starttag(node, 'section', '', **kwargs))
6581

66-
@staticmethod
67-
def depart(self, _):
68-
self.body.append('</section>')
6982

83+
def html_depart_isso_oode(self: HTML5Translator, _):
84+
self.body.append('</section>')
7085

71-
class IssoDirective(Directive):
86+
87+
class IssoDirective(SphinxDirective):
7288
"""Isso ".. isso::" rst directive."""
7389

7490
option_spec = {
@@ -84,16 +100,17 @@ def run(self):
84100

85101
node = IssoNode()
86102
node['ids'] = ['isso-thread']
103+
# Save docname for later looking up :attr:`self.env.metadata`,
104+
# which is not yet available now.
105+
node['docname'] = self.env.docname
106+
87107
if self.options.get('id'):
88-
thread_id = self.options.get('id')
89-
if not thread_id.startswith('/'):
90-
logger.warning('isso thread-id should starts with slash', location=node)
91-
node['thread-id'] = thread_id
92-
else:
93-
node['thread-id'] = '/' + self.state.document.settings.env.docname
108+
node['thread-id'] = self.options.get('id')
109+
94110
if self.options.get('title'):
95111
node['thread-title'] = self.options.get('title')
96112
else:
113+
# TODO: support section title?
97114
title = self.state.document.next_node(nodes.title)
98115
if title:
99116
node['thread-title'] = title.astext()
@@ -135,7 +152,7 @@ def setup(app:Sphinx):
135152
for cfg in CONFIG_ITEMS:
136153
app.add_config_value(cfg, None, '')
137154
app.add_directive('isso', IssoDirective)
138-
app.add_node(IssoNode, html=(IssoNode.visit, IssoNode.depart))
155+
app.add_node(IssoNode, html=(html_visit_isso_node, html_depart_isso_oode))
139156
app.connect('html-page-context', on_html_page_context)
140157

141158
return {'version': __version__}

0 commit comments

Comments
 (0)