Skip to content

Commit 5fd62fc

Browse files
DOC: script to build single docstring page
1 parent 02f6308 commit 5fd62fc

File tree

2 files changed

+75
-36
lines changed

2 files changed

+75
-36
lines changed

doc/make.py

+75-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import argparse
1919
from contextlib import contextmanager
2020
import jinja2
21+
import webbrowser
2122

2223

2324
DOC_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -26,7 +27,7 @@
2627
BUILD_DIRS = ['doctrees', 'html', 'latex', 'plots', '_static', '_templates']
2728

2829

29-
def _generate_index(include_api, single_doc=None):
30+
def _generate_index(include_api=True, single_doc=None):
3031
"""Create index.rst file with the specified sections.
3132
3233
Parameters
@@ -48,6 +49,37 @@ def _generate_index(include_api, single_doc=None):
4849
single_doc=single_doc))
4950

5051

52+
def _generate_exclude_pattern(include_api=True, single_doc=None):
53+
54+
if not include_api:
55+
rst_files = ['api.rst', 'generated/*.rst']
56+
elif single_doc is not None:
57+
rst_files = [f for f in os.listdir(SOURCE_PATH)
58+
if ((f.endswith('.rst') or f.endswith('.ipynb'))
59+
and (f != 'index.rst') and (f != single_doc))]
60+
rst_files += ['generated/*.rst']
61+
else:
62+
rst_files = []
63+
64+
exclude_patterns = ",".join(
65+
['{!r}'.format(i) for i in ['**.ipynb_checkpoints'] + rst_files])
66+
67+
return exclude_patterns
68+
69+
70+
def _write_temp_file(classtype, module, function):
71+
72+
s = """{1}.{2}
73+
=================================
74+
75+
.. currentmodule:: {1}
76+
77+
.. auto{0}:: {2}""".format(classtype, module, function)
78+
79+
with open(os.path.join(SOURCE_PATH, "temp.rst"), 'w') as f:
80+
f.write(s)
81+
82+
5183
@contextmanager
5284
def _maybe_exclude_notebooks():
5385
"""Skip building the notebooks if pandoc is not installed.
@@ -96,8 +128,9 @@ class DocBuilder:
96128
All public methods of this class can be called as parameters of the
97129
script.
98130
"""
99-
def __init__(self, num_jobs=1):
131+
def __init__(self, num_jobs=1, exclude_patterns=None):
100132
self.num_jobs = num_jobs
133+
self.exclude_patterns = exclude_patterns
101134

102135
@staticmethod
103136
def _create_build_structure():
@@ -142,8 +175,8 @@ def _sphinx_build(self, kind):
142175
self._run_os('sphinx-build',
143176
'-j{}'.format(self.num_jobs),
144177
'-b{}'.format(kind),
145-
'-d{}'.format(os.path.join(BUILD_PATH,
146-
'doctrees')),
178+
'-d{}'.format(os.path.join(BUILD_PATH, 'doctrees')),
179+
# TODO integrate exclude_patterns
147180
SOURCE_PATH,
148181
os.path.join(BUILD_PATH, kind))
149182

@@ -199,6 +232,23 @@ def zip_html(self):
199232
'-q',
200233
*fnames)
201234

235+
def build_docstring(self):
236+
"""Build single docstring page"""
237+
self._create_build_structure()
238+
239+
args = ('sphinx-build',
240+
'-bhtml',
241+
'-d{}'.format(os.path.join(BUILD_PATH, 'doctrees')),
242+
'-Dexclude_patterns={}'.format(self.exclude_patterns),
243+
SOURCE_PATH,
244+
os.path.join(BUILD_PATH, 'html'),
245+
os.path.join(SOURCE_PATH, 'temp.rst')
246+
)
247+
# for some reason it does not work with run_os, but it does if I
248+
# directly call the joined command
249+
# self._run_os(*args)
250+
os.system(" ".join(args))
251+
202252

203253
def main():
204254
cmds = [method for method in dir(DocBuilder) if not method.startswith('_')]
@@ -228,15 +278,34 @@ def main():
228278
type=str,
229279
default=os.path.join(DOC_PATH, '..'),
230280
help='path')
281+
argparser.add_argument('--docstring',
282+
metavar='FILENAME',
283+
type=str,
284+
default=None,
285+
help=('method or function name to compile, '
286+
'e.g. "DataFrame.join"'))
231287
args = argparser.parse_args()
232288

233289
if args.command not in cmds:
234290
raise ValueError('Unknown command {}. Available options: {}'.format(
235291
args.command, ', '.join(cmds)))
236292

237293
os.environ['PYTHONPATH'] = args.python_path
238-
_generate_index(not args.no_api, args.single)
239-
getattr(DocBuilder(args.num_jobs), args.command)()
294+
295+
if args.docstring is not None:
296+
_write_temp_file('method', 'pandas', args.docstring)
297+
exclude_patterns = _generate_exclude_pattern(single_doc='temp.rst')
298+
_generate_index(single_doc='temp.rst')
299+
DocBuilder(args.num_jobs, exclude_patterns).build_docstring()
300+
url = "file://" + os.getcwd() + "/build/html/temp.html"
301+
webbrowser.open(url, new=2)
302+
os.remove('source/temp.rst')
303+
304+
else:
305+
_generate_index(not args.no_api, args.single)
306+
exclude_patterns = _generate_exclude_pattern(
307+
not args.no_api, args.single)
308+
getattr(DocBuilder(args.num_jobs, exclude_patterns), args.command)()
240309

241310

242311
if __name__ == '__main__':

doc/source/conf.py

-30
Original file line numberDiff line numberDiff line change
@@ -83,36 +83,6 @@
8383
if any(re.match("\s*api\s*", l) for l in index_rst_lines):
8484
autosummary_generate = True
8585

86-
files_to_delete = []
87-
for f in os.listdir(os.path.dirname(__file__)):
88-
if (not f.endswith(('.ipynb', '.rst')) or
89-
f.startswith('.') or os.path.basename(f) == 'index.rst'):
90-
continue
91-
92-
_file_basename = os.path.splitext(f)[0]
93-
_regex_to_match = "\s*{}\s*$".format(_file_basename)
94-
if not any(re.match(_regex_to_match, line) for line in index_rst_lines):
95-
files_to_delete.append(f)
96-
97-
if files_to_delete:
98-
print("I'm about to DELETE the following:\n%s\n" % list(sorted(files_to_delete)))
99-
sys.stdout.write("WARNING: I'd like to delete those to speed up processing (yes/no)? ")
100-
if PY3:
101-
answer = input()
102-
else:
103-
answer = raw_input()
104-
105-
if answer.lower().strip() in ('y','yes'):
106-
for f in files_to_delete:
107-
f = os.path.join(os.path.join(os.path.dirname(__file__),f))
108-
f= os.path.abspath(f)
109-
try:
110-
print("Deleting %s" % f)
111-
os.unlink(f)
112-
except:
113-
print("Error deleting %s" % f)
114-
pass
115-
11686
# Add any paths that contain templates here, relative to this directory.
11787
templates_path = ['../_templates']
11888

0 commit comments

Comments
 (0)