Skip to content

Commit cbadfc2

Browse files
committed
Get rid of inheritance
Introduce zope.interface
1 parent c2f342a commit cbadfc2

16 files changed

Lines changed: 567 additions & 357 deletions

File tree

doc2dash/__main__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import click
1212

1313
from . import __version__, parsers
14+
from .parsers.utils import patch_anchors
1415

1516

1617
log = logging.getLogger(__name__)
@@ -110,7 +111,7 @@ def main(source, force, name, quiet, verbose, destination, add_to_dash,
110111
)
111112
raise SystemExit(errno.EINVAL)
112113
docs, db_conn = prepare_docset(source, dest, name, index_page)
113-
doc_parser = dt(docs)
114+
doc_parser = dt(doc_path=docs)
114115
log.info(('Converting ' + click.style('{parser_name}', bold=True) +
115116
' docs from "{src}" to "{dst}".')
116117
.format(parser_name=dt.name,
@@ -119,7 +120,7 @@ def main(source, force, name, quiet, verbose, destination, add_to_dash,
119120

120121
with db_conn:
121122
log.info('Parsing documentation...')
122-
toc = doc_parser.add_toc(show_progressbar=not quiet)
123+
toc = patch_anchors(doc_parser, show_progressbar=not quiet)
123124
for entry in doc_parser.parse():
124125
db_conn.execute(
125126
'INSERT INTO searchIndex VALUES (NULL, ?, ?, ?)',
@@ -139,7 +140,7 @@ def main(source, force, name, quiet, verbose, destination, add_to_dash,
139140
add_icon(icon_data, dest)
140141

141142
if add_to_dash or add_to_global:
142-
log.info('Adding to dash...')
143+
log.info('Adding to Dash.app...')
143144
os.system('open -a dash "{}"'.format(dest))
144145

145146

doc2dash/parsers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
DOCTYPES = [
77
intersphinx.InterSphinxParser,
8-
sphinx.SphinxParser,
98
pydoctor.PyDoctorParser,
9+
sphinx.SphinxParser,
1010
]
1111

1212

doc2dash/parsers/base.py

Lines changed: 0 additions & 131 deletions
This file was deleted.

doc2dash/parsers/intersphinx.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import logging
44
import os
55

6+
from characteristic import attributes
67
from six import iteritems
78
from sphinx.ext.intersphinx import read_inventory_v2
9+
from zope.interface import implementer
810

911
from . import types
10-
from .base import _BaseParser, ParserEntry
11-
from .sphinx import find_and_patch_entry
12+
from .utils import (
13+
APPLE_REF_TEMPLATE,
14+
IParser,
15+
ParserEntry,
16+
has_file_with,
17+
)
1218

1319

1420
log = logging.getLogger(__name__)
@@ -36,24 +42,28 @@
3642
}
3743

3844

39-
class InterSphinxParser(_BaseParser):
45+
@implementer(IParser)
46+
@attributes(["doc_path"])
47+
class InterSphinxParser(object):
4048
"""
4149
Parser for Sphinx-base documentation that generates an objects.inv file for
4250
the intersphinx extension.
4351
"""
4452
name = "intersphinx"
4553

46-
DETECT_FILE = "objects.inv"
47-
DETECT_PATTERN = b"# Sphinx inventory version 2"
54+
@staticmethod
55+
def detect(path):
56+
return has_file_with(
57+
path, "objects.inv", b"# Sphinx inventory version 2"
58+
)
4859

4960
def parse(self):
5061
"""
51-
Parse sphinx docs at self.docpath.
62+
Parse sphinx docs at self.doc_path.
5263
53-
yield tuples of symbol name, type and path
64+
yield `ParserEntry`s.
5465
"""
55-
log.info('Creating database...')
56-
with open(os.path.join(self.docpath, "objects.inv"), "rb") as inv_f:
66+
with open(os.path.join(self.doc_path, "objects.inv"), "rb") as inv_f:
5767
inv_f.readline() # skip version line that is verified in detection
5868
for pe in _inv_to_entries(
5969
read_inventory_v2(inv_f, "", os.path.join)
@@ -64,6 +74,23 @@ def find_and_patch_entry(self, soup, entry): # pragma: nocover
6474
return find_and_patch_entry(soup, entry)
6575

6676

77+
def find_and_patch_entry(soup, entry):
78+
"""
79+
Modify soup so Dash.app can generate TOCs on the fly.
80+
"""
81+
link = soup.find('a', {'class': 'headerlink'}, href='#' + entry.anchor)
82+
tag = soup.new_tag('a')
83+
tag['name'] = APPLE_REF_TEMPLATE.format(entry.type, entry.name)
84+
if link:
85+
link.parent.insert(0, tag)
86+
return True
87+
elif entry.anchor.startswith('module-'):
88+
soup.h1.parent.insert(0, tag)
89+
return True
90+
else:
91+
return False
92+
93+
6794
def _inv_to_entries(inv):
6895
"""
6996
Iterate over a dictionary as returned from Sphinx's object.inv parser and

doc2dash/parsers/pydoctor.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,45 @@
44
import os
55

66
from bs4 import BeautifulSoup
7+
from characteristic import attributes
8+
from zope.interface import implementer
79

810
from . import types
9-
from .base import _BaseParser, APPLE_REF_TEMPLATE, ParserEntry
11+
from .utils import APPLE_REF_TEMPLATE, ParserEntry, has_file_with, IParser
1012

1113

1214
log = logging.getLogger(__name__)
1315

1416

15-
class PyDoctorParser(_BaseParser):
17+
PYDOCTOR_HEADER = b'''\
18+
This documentation was automatically generated by
19+
<a href="http://codespeak.net/~mwh/pydoctor/">pydoctor</a>'''
20+
21+
22+
@implementer(IParser)
23+
@attributes(["doc_path"])
24+
class PyDoctorParser(object):
1625
"""
1726
Parser for pydoctor-based documentation: mainly Twisted.
1827
"""
1928
name = 'pydoctor'
2029

21-
DETECT_FILE = 'index.html'
22-
DETECT_PATTERN = b'''\
23-
This documentation was automatically generated by
24-
<a href="http://codespeak.net/~mwh/pydoctor/">pydoctor</a>'''
30+
@classmethod
31+
def detect(self, path):
32+
return has_file_with(
33+
path, "index.html", PYDOCTOR_HEADER
34+
)
2535

2636
def parse(self):
2737
"""
28-
Parse pydoctor docs at *docpath*.
38+
Parse pydoctor docs at *doc_path*.
2939
30-
yield ParserEntrys
40+
yield `ParserEntry`s
3141
"""
3242
soup = BeautifulSoup(
33-
open(os.path.join(self.docpath, 'nameIndex.html')),
43+
open(os.path.join(self.doc_path, 'nameIndex.html')),
3444
'lxml'
3545
)
36-
log.info('Creating database...')
3746
for tag in soup.body.find_all('a'):
3847
path = tag.get('href')
3948
if path and not path.startswith('#'):

0 commit comments

Comments
 (0)