CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
pytorch

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: pytorch/tutorials
Path: blob/main/custom_directives.py
Views: 492
1
from docutils.parsers.rst import Directive, directives
2
from docutils.statemachine import StringList
3
from docutils import nodes
4
import re
5
import os
6
import sphinx_gallery
7
8
try:
9
FileNotFoundError
10
except NameError:
11
FileNotFoundError = IOError
12
13
14
class IncludeDirective(Directive):
15
"""Include source file without docstring at the top of file.
16
17
Implementation just replaces the first docstring found in file
18
with '' once.
19
20
Example usage:
21
22
.. includenodoc:: /beginner/examples_tensor/two_layer_net_tensor.py
23
24
"""
25
26
# defines the parameter the directive expects
27
# directives.unchanged means you get the raw value from RST
28
required_arguments = 1
29
optional_arguments = 0
30
final_argument_whitespace = True
31
has_content = False
32
add_index = False
33
34
docstring_pattern = r'"""(?P<docstring>(?:.|[\r\n])*?)"""\n'
35
docstring_regex = re.compile(docstring_pattern)
36
37
def run(self):
38
document = self.state.document
39
env = document.settings.env
40
rel_filename, filename = env.relfn2path(self.arguments[0])
41
42
try:
43
text = open(filename).read()
44
text_no_docstring = self.docstring_regex.sub('', text, count=1)
45
46
code_block = nodes.literal_block(text=text_no_docstring)
47
return [code_block]
48
except FileNotFoundError as e:
49
print(e)
50
return []
51
52
53
class GalleryItemDirective(Directive):
54
"""
55
Create a sphinx gallery thumbnail for insertion anywhere in docs.
56
57
Optionally, you can specify the custom figure and intro/tooltip for the
58
thumbnail.
59
60
Example usage:
61
62
.. galleryitem:: intermediate/char_rnn_generation_tutorial.py
63
:figure: _static/img/char_rnn_generation.png
64
:intro: Put your custom intro here.
65
66
If figure is specified, a thumbnail will be made out of it and stored in
67
_static/thumbs. Therefore, consider _static/thumbs as a 'built' directory.
68
"""
69
70
required_arguments = 1
71
optional_arguments = 0
72
final_argument_whitespace = True
73
option_spec = {'figure': directives.unchanged,
74
'intro': directives.unchanged}
75
has_content = False
76
add_index = False
77
78
def run(self):
79
args = self.arguments
80
fname = args[-1]
81
82
env = self.state.document.settings.env
83
fname, abs_fname = env.relfn2path(fname)
84
basename = os.path.basename(fname)
85
dirname = os.path.dirname(fname)
86
87
try:
88
if 'intro' in self.options:
89
intro = self.options['intro'][:195] + '...'
90
else:
91
_, blocks = sphinx_gallery.gen_rst.split_code_and_text_blocks(abs_fname)
92
intro, _ = sphinx_gallery.gen_rst.extract_intro_and_title(abs_fname, blocks[0][1])
93
94
thumbnail_rst = ''
95
#sphinx_gallery.backreferences._thumbnail_div(
96
# dirname, basename, intro)
97
98
if 'figure' in self.options:
99
rel_figname, figname = env.relfn2path(self.options['figure'])
100
save_figname = os.path.join('_static/thumbs/',
101
os.path.basename(figname))
102
103
try:
104
os.makedirs('_static/thumbs')
105
except OSError:
106
pass
107
108
sphinx_gallery.gen_rst.scale_image(figname, save_figname,
109
400, 280)
110
# replace figure in rst with simple regex
111
thumbnail_rst = re.sub(r'..\sfigure::\s.*\.png',
112
'.. figure:: /{}'.format(save_figname),
113
thumbnail_rst)
114
115
thumbnail = StringList(thumbnail_rst.split('\n'))
116
thumb = nodes.paragraph()
117
self.state.nested_parse(thumbnail, self.content_offset, thumb)
118
119
return [thumb]
120
except FileNotFoundError as e:
121
print(e)
122
return []
123
124
125
GALLERY_TEMPLATE = """
126
.. raw:: html
127
128
<div class="sphx-glr-thumbcontainer" tooltip="{tooltip}">
129
130
.. only:: html
131
132
.. figure:: {thumbnail}
133
134
{description}
135
136
.. raw:: html
137
138
</div>
139
"""
140
141
142
class CustomGalleryItemDirective(Directive):
143
"""Create a sphinx gallery style thumbnail.
144
145
tooltip and figure are self explanatory. Description could be a link to
146
a document like in below example.
147
148
Example usage:
149
150
.. customgalleryitem::
151
:tooltip: I am writing this tutorial to focus specifically on NLP for people who have never written code in any deep learning framework
152
:figure: /_static/img/thumbnails/babel.jpg
153
:description: :doc:`/beginner/deep_learning_nlp_tutorial`
154
155
If figure is specified, a thumbnail will be made out of it and stored in
156
_static/thumbs. Therefore, consider _static/thumbs as a 'built' directory.
157
"""
158
159
required_arguments = 0
160
optional_arguments = 0
161
final_argument_whitespace = True
162
option_spec = {'tooltip': directives.unchanged,
163
'figure': directives.unchanged,
164
'description': directives.unchanged}
165
166
has_content = False
167
add_index = False
168
169
def run(self):
170
try:
171
if 'tooltip' in self.options:
172
tooltip = self.options['tooltip'][:195] + '...'
173
else:
174
raise ValueError('tooltip not found')
175
176
if 'figure' in self.options:
177
env = self.state.document.settings.env
178
rel_figname, figname = env.relfn2path(self.options['figure'])
179
thumbnail = os.path.join('_static/thumbs/', os.path.basename(figname))
180
181
try:
182
os.makedirs('_static/thumbs')
183
except FileExistsError:
184
pass
185
186
sphinx_gallery.gen_rst.scale_image(figname, thumbnail, 400, 280)
187
else:
188
thumbnail = '_static/img/thumbnails/default.png'
189
190
if 'description' in self.options:
191
description = self.options['description']
192
else:
193
raise ValueError('description not doc found')
194
195
except FileNotFoundError as e:
196
print(e)
197
return []
198
except ValueError as e:
199
print(e)
200
raise
201
return []
202
203
thumbnail_rst = GALLERY_TEMPLATE.format(tooltip=tooltip,
204
thumbnail=thumbnail,
205
description=description)
206
thumbnail = StringList(thumbnail_rst.split('\n'))
207
thumb = nodes.paragraph()
208
self.state.nested_parse(thumbnail, self.content_offset, thumb)
209
return [thumb]
210
211
212
class CustomCardItemDirective(Directive):
213
option_spec = {'header': directives.unchanged,
214
'image': directives.unchanged,
215
'link': directives.unchanged,
216
'card_description': directives.unchanged,
217
'tags': directives.unchanged}
218
219
def run(self):
220
try:
221
if 'header' in self.options:
222
header = self.options['header']
223
else:
224
raise ValueError('header not doc found')
225
226
if 'image' in self.options:
227
image = "<img src='" + self.options['image'] + "'>"
228
else:
229
image = '_static/img/thumbnails/default.png'
230
231
if 'link' in self.options:
232
link = self.options['link']
233
else:
234
link = ''
235
236
if 'card_description' in self.options:
237
card_description = self.options['card_description']
238
else:
239
card_description = ''
240
241
if 'tags' in self.options:
242
tags = self.options['tags']
243
else:
244
tags = ''
245
246
except FileNotFoundError as e:
247
print(e)
248
return []
249
except ValueError as e:
250
print(e)
251
raise
252
return []
253
254
card_rst = CARD_TEMPLATE.format(header=header,
255
image=image,
256
link=link,
257
card_description=card_description,
258
tags=tags)
259
card_list = StringList(card_rst.split('\n'))
260
card = nodes.paragraph()
261
self.state.nested_parse(card_list, self.content_offset, card)
262
return [card]
263
264
265
CARD_TEMPLATE = """
266
.. raw:: html
267
268
<div class="col-md-12 tutorials-card-container" data-tags={tags}>
269
270
<div class="card tutorials-card">
271
272
<a href="{link}">
273
274
<div class="card-body">
275
276
<div class="card-title-container">
277
<h4>{header}</h4>
278
</div>
279
280
<p class="card-summary">{card_description}</p>
281
282
<p class="tags">{tags}</p>
283
284
<div class="tutorials-image">{image}</div>
285
286
</div>
287
288
</a>
289
290
</div>
291
292
</div>
293
"""
294
295
class CustomCalloutItemDirective(Directive):
296
option_spec = {'header': directives.unchanged,
297
'description': directives.unchanged,
298
'button_link': directives.unchanged,
299
'button_text': directives.unchanged}
300
301
def run(self):
302
try:
303
if 'description' in self.options:
304
description = self.options['description']
305
else:
306
description = ''
307
308
if 'header' in self.options:
309
header = self.options['header']
310
else:
311
raise ValueError('header not doc found')
312
313
if 'button_link' in self.options:
314
button_link = self.options['button_link']
315
else:
316
button_link = ''
317
318
if 'button_text' in self.options:
319
button_text = self.options['button_text']
320
else:
321
button_text = ''
322
323
except FileNotFoundError as e:
324
print(e)
325
return []
326
except ValueError as e:
327
print(e)
328
raise
329
return []
330
331
callout_rst = CALLOUT_TEMPLATE.format(description=description,
332
header=header,
333
button_link=button_link,
334
button_text=button_text)
335
callout_list = StringList(callout_rst.split('\n'))
336
callout = nodes.paragraph()
337
self.state.nested_parse(callout_list, self.content_offset, callout)
338
return [callout]
339
340
CALLOUT_TEMPLATE = """
341
.. raw:: html
342
343
<div class="col-md-6">
344
<div class="text-container">
345
<h3>{header}</h3>
346
<p class="body-paragraph">{description}</p>
347
<a class="btn with-right-arrow callout-button" href="{button_link}">{button_text}</a>
348
</div>
349
</div>
350
"""
351
352