Skip to content

Commit dbdbdea

Browse files
committed
Refine titlepath
- Drop "subtitle" support - Retrurn list of nodes.title but not string - include_project is not need
1 parent d25ea30 commit dbdbdea

File tree

2 files changed

+26
-78
lines changed

2 files changed

+26
-78
lines changed

sphinxnotes/snippet/ext.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from .picker import pick
2626
from .cache import Cache, Item
2727
from .keyword import Extractor
28-
from .utils.titlepath import resolve_fullpath
28+
from .utils import titlepath
2929
from .builder import Builder
3030

3131

@@ -110,10 +110,7 @@ def on_doctree_resolved(app:Sphinx, doctree:nodes.document, docname:str) -> None
110110
tags=extract_tags(s),
111111
excerpt=extract_excerpt(s),
112112
keywords=extract_keywords(s),
113-
titlepath=resolve_fullpath(app.env,
114-
docname,
115-
n,
116-
include_project=True)))
113+
titlepath=[x.astext() for x in titlepath.resolve(app.env, docname, n)]))
117114
if len(doc) == 0:
118115
del cache[(app.config.project, docname)]
119116

sphinxnotes/snippet/utils/titlepath.py

Lines changed: 24 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -8,103 +8,54 @@
88
:license: BSD, see LICENSE for details.
99
"""
1010
from __future__ import annotations
11-
from typing import List, Optional, Tuple, TYPE_CHECKING
11+
from typing import List, TYPE_CHECKING
1212

1313
from docutils import nodes
1414

1515
if TYPE_CHECKING:
1616
from sphinx.enviornment import BuilderEnviornment
1717

1818

19-
def _safe_descend(node:nodes.Node, *args: int) -> Optional[nodes.Node]:
20-
"""Get node descend in a safe way."""
21-
try:
22-
for index in args:
23-
node = node[index]
24-
return node
25-
except:
26-
return None
19+
def resolve(env: BuilderEnviornment, docname:str, node:nodes.Node) -> List[nodes.title]:
20+
return resolve_section(node) + resolve_document(env, docname)
2721

2822

29-
def resolve_fullpath(env: BuilderEnviornment, docname:str, node:nodes.Node,
30-
include_project:bool=False) -> List[str]:
31-
return [x.astext() for x in resolve_sectpath(node.document, node)] + \
32-
resolve_docpath(env, docname, include_project=include_project)
33-
34-
35-
def resolve_sectpath(doctree:nodes.document, node:nodes.Node) -> List[nodes.title]:
23+
def resolve_section(node:nodes.section) -> List[nodes.title]:
3624
# FIXME: doc is None
37-
_, subtitlenode = resolve_doctitle(doctree)
3825
titlenodes = []
3926
while node:
40-
secttitle = resolve_secttitle(node)
27+
if len(node) > 0 and isinstance(node[0], nodes.title):
28+
titlenodes.append(node[0])
4129
node = node.parent
42-
if not secttitle or secttitle == subtitlenode:
43-
continue
44-
titlenodes.append(secttitle)
4530
return titlenodes
4631

4732

48-
def resolve_secttitle(node:nodes.Node) -> Optional[nodes.title]:
49-
titlenode = _safe_descend(node.parent, 0)
50-
if not isinstance(titlenode, nodes.title):
51-
return None
52-
return titlenode
53-
54-
55-
def resolve_docpath(env:BuilderEnviornment, docname:str, include_project:bool=False) -> List[str]:
33+
def resolve_document(env:BuilderEnviornment, docname:str) -> List[nodes.title]:
34+
"""
35+
.. note:: Title of document itself does not included in the returned list
36+
"""
5637
titles = []
57-
58-
if include_project:
59-
titles.append(env.config.project)
60-
6138
master_doc = env.config.master_doc
6239
v = docname.split('/')
63-
if v.pop() == master_doc:
64-
if v:
65-
# If docname is "a/b/index", we need titles of "a"
66-
v.pop()
67-
else:
68-
# docname is "index", no need to get docpath, it is root doc
69-
return []
40+
41+
# Exclude self
42+
if v.pop() == master_doc and v:
43+
# If self is master_doc, like: "a/b/c/index", we only return titles
44+
# of "a/b/", so pop again
45+
v.pop()
46+
47+
# Collect master doc title in docname
7048
while v:
7149
master_docname = '/'.join(v + [master_doc])
7250
if master_docname in env.titles:
73-
title = env.titles[master_docname].astext()
51+
title = env.titles[master_docname]
7452
else:
75-
title = v[-1].title()
53+
title = nodes.title(text=v[-1].title()) # FIXME: Create mock title for now
7654
titles.append(title)
7755
v.pop()
7856

79-
return titles[::-1] # Reverse inplace
80-
81-
82-
def resolve_doctitle(doctree:nodes.document) -> Tuple[Optional[nodes.title],
83-
Optional[nodes.title]]:
84-
85-
toplevel_sectnode = doctree.next_node(nodes.section)
86-
if not toplevel_sectnode:
87-
return (None, None)
57+
# Include title of top-level master doc
58+
if master_doc in env.titles:
59+
titles.append(env.titles[master_doc])
8860

89-
titlenode = _safe_descend(toplevel_sectnode, 0)
90-
# NOTE: nodes.subtitle does not make senses beacuse Sphinx doesn't support
91-
# subtitle:
92-
#
93-
# > Sphinx does not support a "subtitle".
94-
# > Sphinx recognizes it as a mere second level section
95-
#
96-
# ref:
97-
# - https://github.com/sphinx-doc/sphinx/issues/3574#issuecomment-288722585
98-
# - https://github.com/sphinx-doc/sphinx/issues/3567#issuecomment-288093991
99-
if len(toplevel_sectnode) != 2:
100-
return (titlenode, None)
101-
# HACK: For our convenience, we regard second level section title
102-
# (under document) as subtitle::
103-
# <section>
104-
# <title>
105-
# <section>
106-
# <(sub)title>
107-
subtitlenode = toplevel_sectnode[1][0]
108-
if not isinstance(subtitlenode, nodes.title):
109-
return (titlenode, None)
110-
return (titlenode, subtitlenode)
61+
return titles

0 commit comments

Comments
 (0)