Skip to content

Commit dad7166

Browse files
committed
*: Add support for tutorial
Signed-off-by: Ce Gao <ce.gao@outlook.com>
1 parent 762c075 commit dad7166

22 files changed

+262
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
test.rpde
22
docs/
3+
.vscode/

scripts/generate-reference.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ ROOT=$(dirname "${BASH_SOURCE}")/..
55
cd ${ROOT}
66
mv docs/.git cache.git.dir
77
rm -rf docs/
8-
mkdir -p docs/reference
8+
mkdir -p docs/reference docs/tutorials
99
mv cache.git.dir docs/.git
1010
cp -r content/* docs/
11+
cp -r tutorials/* docs/tutorials/
1112
exec python3 ./src/generate.py $@
1213
cd - > /dev/null

src/generate.py

Lines changed: 98 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1+
"""Generate Documentation"""
2+
13
import logging
24
import os
3-
import jinja2
4-
import click
55
import tempfile
66
from subprocess import call
7-
import string
8-
import time
9-
import shutil
10-
import yaml
117
import datetime
8+
import markdown
9+
import yaml
10+
import jinja2
11+
import click
1212

1313
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
1414

1515
img_dir = 'img'
16-
property_dir = '.property.yml'
16+
property_file = '.property.yml'
1717

1818

1919
class Generator(object):
2020
def __init__(self, root, env, jar):
2121
self.reference_generator = ReferenceGenerator(root, env, jar)
2222
self.cover_generator = CoverGenerator(env)
23-
23+
self.tutorial_generator = TurotialGenerator(env)
24+
2425
def generate(self):
2526
self.cover_generator.generate()
2627
self.reference_generator.generate()
28+
self.tutorial_generator.generate()
2729

2830

2931
class CoverGenerator(object):
@@ -37,6 +39,59 @@ def generate(self):
3739
f.write(cover_template.render())
3840

3941

42+
class TurotialGenerator(object):
43+
def __init__(self, env):
44+
self.env = env
45+
self.input_dir = tutorials_dir
46+
self.output_dir = output_tutorials_dir
47+
48+
def generate(self):
49+
file_name = os.path.join(self.input_dir, 'index.yml')
50+
items = []
51+
with open(file_name) as f:
52+
raw_yaml_doc = f.read()
53+
yaml_obj = yaml.load(raw_yaml_doc)
54+
items = yaml_obj['index']
55+
tutorial_items = []
56+
for item in items:
57+
tutorial_item = TutorialItem(
58+
self.env, self.input_dir, item, self.output_dir)
59+
with open(os.path.join(self.output_dir, item, 'index.html'), 'w+') as f:
60+
item_template = self.env.get_template(
61+
'tutorial_item_template.jinja')
62+
f.write(item_template.render(tutorial=tutorial_item))
63+
tutorial_items.append(tutorial_item)
64+
index_template = self.env.get_template('tutorial_index_template.jinja')
65+
with open(os.path.join(self.output_dir, 'index.html'), 'w+') as f:
66+
f.write(index_template.render(tutorials=tutorial_items))
67+
68+
69+
class TutorialItem(object):
70+
def __init__(self, env, input_dir, item, output_dir):
71+
self.env = env
72+
self.input_dir = input_dir
73+
self.item = item
74+
self.item_input_dir = os.path.join(self.input_dir, self.item)
75+
self.output_dir = output_dir
76+
self.item_output_dir = os.path.join(self.output_dir, self.item)
77+
self.parse_property()
78+
79+
def parse_property(self):
80+
with open(os.path.join(self.item_input_dir, property_file), 'r') as f:
81+
raw_yaml_doc = f.read()
82+
yaml_obj = yaml.load(raw_yaml_doc)
83+
self.title = yaml_obj['title']
84+
# The directory must be named 'imgs'.
85+
self.image = os.path.join(self.item, 'imgs', yaml_obj['image'])
86+
self.url = self.item + '/'
87+
self.author = yaml_obj['author']
88+
self.introduction = yaml_obj['introduction']
89+
self.level = yaml_obj['level']
90+
with open(os.path.join(
91+
self.item_input_dir, 'index.md'), 'r') as index_f:
92+
self.content = markdown.markdown(index_f.read())
93+
94+
4095
class ReferenceGenerator(object):
4196
def __init__(self, root, env, jar):
4297
self.root_dir = root
@@ -62,9 +117,11 @@ def parse_reference(self):
62117

63118
def render_reference_items(self):
64119
for item in self.reference_items:
65-
reference_template = self.env.get_template('reference_item_template.jinja')
120+
reference_template = self.env.get_template(
121+
'reference_item_template.jinja')
66122
with open(os.path.join(self.output_html_dir, ('%s.html' % item.name)), 'w+') as f:
67-
f.write(reference_template.render(item=item, today=datetime.datetime.now().ctime()))
123+
f.write(reference_template.render(
124+
item=item, today=datetime.datetime.now().ctime()))
68125

69126
def render_reference_index(self):
70127
categories = dict()
@@ -74,9 +131,11 @@ def render_reference_index(self):
74131
if item.category is '':
75132
# print(item.category)
76133
path = (item.category, '')
77-
if path == ('', ''): continue
134+
if path == ('', ''):
135+
continue
78136
# Fields and Methods aren't included in the index
79-
if path[1] in ('Method', 'Field'): continue
137+
if path[1] in ('Method', 'Field'):
138+
continue
80139
if path not in categories:
81140
categories[path] = list()
82141
categories[path].append(item)
@@ -139,8 +198,10 @@ def render_reference_index(self):
139198
current_cat = cat
140199
if subcat != current_subcat:
141200
if current_subcat is not None:
142-
elements.append({'type': 'end-subcategory', 'content': None})
143-
elements.append({'type': 'start-subcategory', 'content': subcat})
201+
elements.append(
202+
{'type': 'end-subcategory', 'content': None})
203+
elements.append(
204+
{'type': 'start-subcategory', 'content': subcat})
144205
current_subcat = subcat
145206
elements.append({'type': 'start-list', 'content': None})
146207
# For demo.
@@ -152,10 +213,12 @@ def render_reference_index(self):
152213
elements.append({'type': 'end-subcategory', 'content': None})
153214
elements.append({'type': 'end-category', 'content': None})
154215

155-
index_template = self.env.get_template('reference_index_template.jinja')
216+
index_template = self.env.get_template(
217+
'reference_index_template.jinja')
156218
with open(os.path.join(self.output_html_dir, 'index.html'), 'w+') as f:
157219
f.write(index_template.render(elements=elements))
158220

221+
159222
class ReferenceItem(object):
160223
def __init__(self, root, name, jar, output_img_dir):
161224
self.name = name
@@ -167,9 +230,9 @@ def __init__(self, root, name, jar, output_img_dir):
167230

168231
self.parse_reference_item()
169232
self.parse_property()
170-
233+
171234
def parse_property(self):
172-
file_name = os.path.join(self.item_dir, property_dir)
235+
file_name = os.path.join(self.item_dir, property_file)
173236
with open(file_name) as f:
174237
raw_yaml_doc = f.read()
175238
yaml_obj = yaml.load(raw_yaml_doc)
@@ -204,9 +267,10 @@ def parse_reference_item(self):
204267
continue
205268
sketchFile = '%s/%s/%s.rpde' % (self.item_dir, filename, filename)
206269
with open(sketchFile, 'r') as f:
207-
print("Interpreting " + sketchFile)
270+
print('Interpreting ' + sketchFile)
208271
code = f.read()
209-
img_path = os.path.join(self.output_img_dir, ('%s.png' % filename))
272+
img_path = os.path.join(
273+
self.output_img_dir, ('%s.png' % filename))
210274
testConfigFile = '%s/%s/.test.yml' % (self.item_dir, filename)
211275
if os.path.isfile(testConfigFile) is not True:
212276
self.examples.append({
@@ -231,19 +295,22 @@ def generate_image(self, code, to):
231295
for i in range(pos, len(code) - 1):
232296
if code[i] is '\n' and code[i + 1] is '}':
233297
footer = '\n processing$saveFrame("%s")\n processing$exit()\n' % to
234-
actual_code = code[:i] + footer + code[i+1:]
298+
actual_code = code[:i] + footer + code[i + 1:]
235299
else:
236300
footer = 'processing$saveFrame("%s")\nprocessing$exit()\n' % to
237301
actual_code = '%s\n%s' % (code, footer)
238302

239-
# I don't know why temp file could not be written directly. It must be open() and written.
240-
temp_file = tempfile.NamedTemporaryFile(prefix='Processing.R.', suffix='.tmp.rpde')
303+
# I don't know why temp file could not be written directly. It must be
304+
# open() and written.
305+
temp_file = tempfile.NamedTemporaryFile(
306+
prefix='Processing.R.', suffix='.tmp.rpde')
241307
temp_file.write(bytes(actual_code, 'utf-8'))
242308
temp_file.seek(0)
243309
retcode = call(['java', '-jar', self.jar_path, temp_file.name])
244310
if retcode is not 0:
245311
logging.error('retcode of runner.jar: %d', retcode)
246312

313+
247314
@click.command()
248315
@click.option('--core', default='', help='The location of Processing.R source code.')
249316
@click.option('--jar', default='', help='The location of runner.jar')
@@ -260,23 +327,31 @@ def generate(core, jar, docs_dir):
260327

261328
template_dir_short = 'templates'
262329
output_reference_dir_short = 'docs/reference'
330+
output_tutorial_dir_short = 'docs/tutorials'
263331
output_dir_short = 'docs'
264332
content_dir_short = 'content'
333+
tutorials_dir_short = 'tutorials'
265334

266335
global template_dir
267336
global output_dir
268337
global content_dir
338+
global tutorials_dir
269339
global output_reference_dir
340+
global output_tutorials_dir
270341

271342
template_dir = os.path.join(docs_dir, template_dir_short)
272343
output_dir = os.path.join(docs_dir, output_dir_short)
273344
content_dir = os.path.join(docs_dir, content_dir_short)
345+
tutorials_dir = os.path.join(docs_dir, tutorials_dir_short)
274346
output_reference_dir = os.path.join(docs_dir, output_reference_dir_short)
347+
output_tutorials_dir = os.path.join(docs_dir, output_tutorial_dir_short)
275348

276-
env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir), trim_blocks='true')
349+
env = jinja2.Environment(loader=jinja2.FileSystemLoader(
350+
template_dir), trim_blocks='true')
277351

278352
generator = Generator(core, env, jar)
279353
generator.generate()
280354

355+
281356
if __name__ == '__main__':
282357
generate()

templates/page_template.jinja

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
<div class="navBar" id="mainnav">
2626
<a href="/">Cover</a><br/>
2727
<a href="/reference/">Reference</a><br/>
28-
<!-- <a href="/tutorials/">Tutorials</a><br/>
29-
<a href="/examples/">Examples</a><br/> -->
28+
<a href="/tutorials/">Tutorials</a><br/>
29+
<!-- <a href="/examples/">Examples</a><br/> -->
3030
<a href="https://github.com/gaocegege/Processing.R/issues">Bugs</a>
3131
</div>
3232
</div>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{% extends "page_template.jinja" %}
2+
3+
{% block title %}Tutorials{% endblock %}
4+
5+
{% block content %}
6+
<div id="Tutorials">
7+
<h1 class="large-header"><span class="black">Processing.R Tutorials.</span> A collection of step-by-step lessons introducing Processing (with R).</h1>
8+
9+
<p>Many of these tutorials were directly translated into R from their <a
10+
href="http://processing.org/tutorials">Java counterparts</a> by the
11+
Processing.R documentation team and are accordingly credited to their original
12+
authors. <a href="https://github.com/processing-r/Processing.R-docs-tools/issues">Please
13+
report any mistakes or inaccuracies in the Processing.R documentation
14+
GitHub.</a></p>
15+
16+
<table width="679" cellspacing="1" cellpadding="0" border="0">
17+
<tbody>
18+
{% for tutorial_batch in tutorials|batch(3) %}
19+
<tr>
20+
{% for tutorial in tutorial_batch %}
21+
<td><div class="curated-item">
22+
<a href="{{ tutorial.url }}">
23+
<img src="{{ tutorial.image }}" width="223" height="72" alt="Preview image" title="{{tutorial.title}}">
24+
</a>
25+
<p>
26+
<br />
27+
<a href="{{ tutorial.url }}">{{ tutorial.title }}</a>
28+
<br />
29+
by {{ tutorial.author }}
30+
</p>
31+
<p>{{ tutorial.introduction }}</p>
32+
<p>Level: {{ tutorial.level }}</p>
33+
</div></td>
34+
{% endfor %}
35+
</tr>
36+
{% endfor %}
37+
</tbody>
38+
</table>
39+
</div>
40+
{% endblock %}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{% extends "page_template.jinja" %}
2+
3+
{% block title %}{{ tutorial.title }}{% endblock %}
4+
5+
{% block content %}
6+
<body>
7+
<h1>{{ tutorial.title }}</h1>
8+
9+
<table width="656">
10+
<tr>
11+
<td>
12+
{{ tutorial.content }}
13+
</td>
14+
</tr>
15+
</table>
16+
</body>
17+
{% endblock %}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
image: gettingstarted.gif
2+
title: Getting Started
3+
author: Casey Reas and Ben Fry
4+
introduction: Welcome to Processing! This tutorial covers the basics of writing Processing code in R mode.
5+
level: Beginner
1.07 KB
Loading
22.7 KB
Loading
18.7 KB
Loading
19.2 KB
Loading
19.9 KB
Loading
1.45 KB
Loading
1.73 KB
Loading
1.33 KB
Loading
1.17 KB
Loading
1.38 KB
Loading
Loading
1.18 KB
Loading
3.99 KB
Loading

0 commit comments

Comments
 (0)