Skip to content

Commit a057276

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

File tree

2 files changed

+74
-36
lines changed

2 files changed

+74
-36
lines changed

doc/make.py

+74-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,36 @@ 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(['{!r}'.format(i) for i in ['**.ipynb_checkpoints'] + rst_files])
65+
66+
return exclude_patterns
67+
68+
69+
def _write_temp_file(classtype, module, function):
70+
71+
s = """{1}.{2}
72+
=================================
73+
74+
.. currentmodule:: {1}
75+
76+
.. auto{0}:: {2}""".format(classtype, module, function)
77+
78+
with open(os.path.join(SOURCE_PATH, "temp.rst"), 'w') as f:
79+
f.write(s)
80+
81+
5182
@contextmanager
5283
def _maybe_exclude_notebooks():
5384
"""Skip building the notebooks if pandoc is not installed.
@@ -96,8 +127,9 @@ class DocBuilder:
96127
All public methods of this class can be called as parameters of the
97128
script.
98129
"""
99-
def __init__(self, num_jobs=1):
130+
def __init__(self, num_jobs=1, exclude_patterns=None):
100131
self.num_jobs = num_jobs
132+
self.exclude_patterns = exclude_patterns
101133

102134
@staticmethod
103135
def _create_build_structure():
@@ -142,8 +174,8 @@ def _sphinx_build(self, kind):
142174
self._run_os('sphinx-build',
143175
'-j{}'.format(self.num_jobs),
144176
'-b{}'.format(kind),
145-
'-d{}'.format(os.path.join(BUILD_PATH,
146-
'doctrees')),
177+
'-d{}'.format(os.path.join(BUILD_PATH, 'doctrees')),
178+
# TODO integrate exclude_patterns
147179
SOURCE_PATH,
148180
os.path.join(BUILD_PATH, kind))
149181

@@ -199,6 +231,23 @@ def zip_html(self):
199231
'-q',
200232
*fnames)
201233

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

203252
def main():
204253
cmds = [method for method in dir(DocBuilder) if not method.startswith('_')]
@@ -228,15 +277,34 @@ def main():
228277
type=str,
229278
default=os.path.join(DOC_PATH, '..'),
230279
help='path')
280+
argparser.add_argument('--docstring',
281+
metavar='FILENAME',
282+
type=str,
283+
default=None,
284+
help=('method or function name to compile, '
285+
'e.g. "DataFrame.join"'))
231286
args = argparser.parse_args()
232287

233288
if args.command not in cmds:
234289
raise ValueError('Unknown command {}. Available options: {}'.format(
235290
args.command, ', '.join(cmds)))
236291

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

241309

242310
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)