Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Packaging #6

Open
wants to merge 13 commits into
base: packaging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ThingDoc is a clever things comment parser.

It uses syntax similar to Javadoc and is able to generate:
It uses syntax similar to Javadoc and is able to generate from .tdoc and .scad files (output in docs folder):

* BoM text file
* HTML documentation
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Jinja>=1.2
Jinja2>=2.7
31 changes: 31 additions & 0 deletions sample.tdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Printer
*
* @root
* @id RepRap
* @name RepRap
* @using 2 frame
* @using 1 x-axis
* @step Make sure you have [frame] ready.
* @step Second you make the [x-axis].
*/

/**
* Printer base
*
* @id frame
* @name frame
* @assembled
* @step Do the side triangles.
* @step Connect triangles into frame.
*/

/**
* x axis
*
* @id x-axis
* @name x-axis
* @step Prepare x-end-motor
* @step Prepare x-end-idler
* @step Put both together with rods.
*/
4 changes: 2 additions & 2 deletions thingdoc/data/facebox.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
settings: {
opacity : 0.2,
overlay : false,
loadingImage : '/facebox/loading.gif',
closeImage : '/facebox/closelabel.png',
loadingImage : 'html_data/facebox/loading.gif',
closeImage : 'html_data/facebox/closelabel.png',
imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ],
faceboxHtml : '\
<div id="facebox" style="display:none;"> \
Expand Down
2 changes: 1 addition & 1 deletion thingdoc/data/template.bom
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bill of Materials: {{ title }}
{% for category in bom %}
{{ category }}
{{ (category|length) * '=' }}
{% for id, cnt in bom[category].iteritems() -%}
{% for id, cnt in bom[category].items() -%}
- {{ cnt }}x {{tree[id].name}}
{% endfor -%}
{% endfor %}
Expand Down
13 changes: 7 additions & 6 deletions thingdoc/data/template.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ title|e }} by ThingDoc</title>
Expand Down Expand Up @@ -54,7 +55,7 @@ <h2>Bill of Materials</h2>
{% for category in bom %}
<h3>{{ category|e }}</h3>
<table id="bomtable">
{%- for id, cnt in bom[category].iteritems() %}
{%- for id, cnt in bom[category].items() %}
<tr>
<td>
<input type="checkbox" class="bom_checkbox" name="{{ id|e }}">
Expand All @@ -74,9 +75,9 @@ <h3>{{ category|e }}</h3>
<div id="things">
<h2>Things Overview</h2>
<p>List of things and their descriptions</p>
{% for thing in tree.itervalues() %}
{% for (id, thing) in tree.items() %}
<div id="thing_{{ thing.id|e }}" class="thing_overview" >
{%- if thing.id != 1 %}
{% if id != 1 %}
<h3>{{ thing.name|e }}</h3>
<div class="stuff">
{%- if thing.desc %}
Expand All @@ -86,7 +87,7 @@ <h3>{{ thing.name|e }}</h3>
<img src="{{ imagedir|e }}/{{ thing.image|e }}" width="256" />
{%- endif %}
</div>
{% endif -%}
{% endif %}
</div>
{% endfor %}
</div>
Expand All @@ -100,7 +101,7 @@ <h3>Assemble {{ tree[i[0]].name|e }}</h3>
{%- if tree[i[0]].using %}
<p>Things needed:</p>
<table id="bomtable">
{%- for id, cnt in tree[i[0]].using.iteritems() %}
{%- for id, cnt in tree[i[0]].using.items() %}
<tr>
<td class="right">
<strong>{{ cnt|e }} x</strong>
Expand Down Expand Up @@ -133,7 +134,7 @@ <h3>Assemble {{ tree[i[0]].name|e }}</h3>
{% endfor %}
</div>

<div class="generated">Generated by ThingDOC</span>
<div class="generated">Generated by ThingDOC</div>
</div>
</div>
</body>
Expand Down
6 changes: 3 additions & 3 deletions thingdoc/data/template.tex
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ \section{Bill of Materials}
{% for category in bom %}
\subsection{ {{- category|el }}}
\begin{itemize}
{% for id, cnt in bom[category].iteritems() %}
{% for id, cnt in bom[category].items() %}
{%- if tree[id].common -%}
\item {{ cnt|el }}x {{ tree[id].name|el }}
{% else -%}
Expand All @@ -45,7 +45,7 @@ \subsection{ {{- category|el }}}

\section{Things Overview}
List of things and their descriptions.
{% for thing in tree.itervalues() %}
{% for thing in tree.items() %}
{%- if thing.id != 1 and thing.common == False %}
\hypertarget{thing_{{ thing.id|el }}}{\subsection{ {{- thing.name|el }}}}
{%- if thing.desc %}
Expand All @@ -64,7 +64,7 @@ \subsection{Assemble {{ tree[i[0]].name|el }}}
{%- if tree[i[0]].using %}
Things needed:
\begin{itemize}
{%- for id, cnt in tree[i[0]].using.iteritems() %}
{%- for id, cnt in tree[i[0]].using.items() %}
{%- if tree[id].common %}
\item {{ cnt|el }}x {{ tree[id].name|el }}
{%- else %}
Expand Down
2 changes: 1 addition & 1 deletion thingdoc/data/template.wiki
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
! scope="col" | Type
! scope="col" class="unsortable" | Comments
! scope="col" class="unsortable" | Diagram
{% for id, cnt in bom[category].iteritems() -%}
{% for id, cnt in bom[category].items() -%}
|-
| {{ cnt }} || {{ tree[id].name }} || {{ tree[id].type }} || {{ tree[id].comment|join('; ') if tree[id].comment }} ||{{ ' [[File:%s|50px]]' % tree[id].image if tree[id].image }}
{% endfor -%}
Expand Down
75 changes: 42 additions & 33 deletions thingdoc/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import shutil
import sys
import time
import distutils.dir_util

from jinja2 import Environment, FileSystemLoader
from optparse import OptionParser

Expand All @@ -32,7 +34,7 @@
class Thing:

def __init__(self):
self.id = None # unique id, root has id = 0 (numeric) which cannot be overriden
self.id = None # unique id, root has id = 1 (numeric) which cannot be overriden
self.name = None # name of the thing
self.common = False # is this thing common?
self.assembled = False # is this thing assembled?
Expand Down Expand Up @@ -94,15 +96,15 @@ def parse(self, indir, outdir, imagedir):


def warning(self, string):
print >> sys.stderr, 'Warning:', string
print('Warning:', string, file=sys.stderr)


def error(self, string):
print >> sys.stderr, 'Error:', string
print('Error:', string, file=sys.stderr)


def fatal(self, string):
print >> sys.stderr, 'Fatal:', string
print('Fatal:', string, file=sys.stderr)
sys.exit(1)


Expand All @@ -116,13 +118,15 @@ def process_file(self, absname, things):
success = True
thing = None
linenum = 0
isRoot = False
for line in f:
linenum += 1
if line.startswith('/**'):
if thing:
self.error('Start of the comment (/**) found but the previous one is still open (%s:%d)' % (absname, linenum))
success = False
thing = Thing()
isRoot = False
continue
if line.startswith(' */'):
if not thing:
Expand Down Expand Up @@ -155,15 +159,21 @@ def process_file(self, absname, things):
continue
(key, _, value) = line[3:].strip().partition(' ')
if key == '@id':
thing.id = value
#id is not mandatory for root object
if not isRoot:
thing.id = value
else:
continue
elif key == '@name':
thing.name = value
elif key == '@root':
thing.id = 1
isRoot = True
elif key == '@common':
thing.common = True
elif key == '@assembled':
thing.assembled = True
thing.category = "Assembled"
elif key == '@since':
thing.since = value
elif key == '@category':
Expand Down Expand Up @@ -196,7 +206,7 @@ def process_file(self, absname, things):
elif key == '@weight':
thing.weight = float(value)
elif key == '@time':
thing.weight = float(time)
thing.time = float(value)
elif key.startswith('@'):
self.error('Unknown tag %s (%s:%d)' % (key, absname, linenum))
success = False
Expand All @@ -219,15 +229,15 @@ def generate_tree(self):
if self.parse_only_files is not False:
if not name in self.parse_only_files:
continue
print name
print(name)
absname = os.path.join(root, name)
self.process_file(absname, things)
return things


def check_tree(self):

if not 1 in self.tree:
if not filter(lambda thing: thing.id == 1, iter(self.tree.values())):
self.fatal('Nothing was declared as @root')

# do iterative BFS on dependency graph
Expand All @@ -236,21 +246,21 @@ def check_tree(self):
queue = [1]
while queue:
thing = queue.pop()
if not thing in self.tree.iterkeys():
if not thing in iter(self.tree.keys()):
if not thing in missing:
missing.append(thing)
continue
if not thing in used:
used.append(thing)
queue += self.tree[thing].using.keys()
queue += list(self.tree[thing].using.keys())
# do various alterations of items
if os.path.exists('%s/%s.jpg' % (self.imagedir, thing)):
self.tree[thing].image = '%s.jpg' % thing
elif os.path.exists('%s/%s.png' % (self.imagedir, thing)):
self.tree[thing].image = '%s.png' % thing

# handle unused things
for thing in self.tree.iterkeys():
for thing in self.tree.keys():
if not thing in used:
self.warning("Thing '%s' is defined but unused" % thing)

Expand All @@ -259,15 +269,15 @@ def check_tree(self):
# handle undefined things
for thing in missing:
parents = []
for k, v in self.tree.iteritems():
for k, v in self.tree.items():
if thing in v.using:
parents.append(k == 1 and '@root' or ("'" + k + "'"))
parents.sort()
self.error("Thing '%s' is not defined and required by: %s" % (thing, ', '.join(parents)))
valid = False

# detect oriented cycles
todo = self.tree.keys()
todo = list(self.tree.keys())
while todo:
node = todo.pop()
stack = [node]
Expand Down Expand Up @@ -298,23 +308,23 @@ def print_tree(self):
while queue:
(id, cnt, level) = queue.pop(0)
if id == 1:
print '@root', '(' + self.tree[id].name + ')'
print('@root', '(' + self.tree[id].name + ')')
else:
print level * ' ', '-', str(cnt) + 'x', self.tree[id].id, '(' + self.tree[id].name + ')'
queue = map(lambda (id, cnt): (id, cnt, level + 1), self.tree[id].using.iteritems()) + queue
print(level * ' ', '-', str(cnt) + 'x', self.tree[id].id, '(' + self.tree[id].name + ')')
queue = [(id_cnt[0], id_cnt[1], level + 1) for id_cnt in iter(self.tree[id].using.items())] + queue


def graphviz_tree(self):

print 'digraph thingdoc {'
print '\tnode [style=filled, colorscheme=pastel19];'
print '\tedge [dir=back];'
print('digraph thingdoc {')
print('\tnode [style=filled, colorscheme=pastel19];')
print('\tedge [dir=back];')
# perform iterative DFS on tree
queue = [(1, 0, ['root'])]
while queue:
(id, cnt, path) = queue.pop(0)
if id == 1:
print '\t"root"[label="%s", fillcolor=9];' % self.tree[id].name
print('\t"root"[label="%s", fillcolor=9];' % self.tree[id].name)
else:
name = self.tree[id].name
if cnt > 1:
Expand All @@ -324,18 +334,18 @@ def graphviz_tree(self):
elif not self.tree[id].category:
color = 8
else:
i = self.bom.keys().index(self.tree[id].category)
i = list(self.bom.keys()).index(self.tree[id].category)
color = (i % 6) + 2 # 2-7
print '\t"%s"[label="%s", fillcolor=%d];' % ('/'.join(path), name, color)
print '\t"%s" -> "%s";' % ('/'.join(path[:-1]), '/'.join(path))
queue = map(lambda (id, cnt): (id, cnt, path + [id]), self.tree[id].using.iteritems()) + queue
print '}'
print('\t"%s"[label="%s", fillcolor=%d];' % ('/'.join(path), name, color))
print('\t"%s" -> "%s";' % ('/'.join(path[:-1]), '/'.join(path)))
queue = [(id_cnt1[0], id_cnt1[1], path + [id_cnt1[0]]) for id_cnt1 in iter(self.tree[id].using.items())] + queue
print('}')


def extract_bom(self):

# perform iterative BFS on tree
queue = [ self.tree[1].using.items() ]
queue = [ list(self.tree[1].using.items()) ]
bom = {}
while queue:
using = queue.pop(0)
Expand All @@ -347,9 +357,8 @@ def extract_bom(self):
else:
bom[thing.category][id] = cnt
else:
if thing.category:
bom[thing.category] = {id: cnt}
queue += [ map(lambda (a, b): (a, b*cnt), thing.using.items()) ]
bom[thing.category] = {id: cnt}
queue += [ [(a_b[0], a_b[1]*cnt) for a_b in list(thing.using.items())] ]
return bom


Expand Down Expand Up @@ -390,8 +399,8 @@ def generate_html(self):
pass

# copy static files
for i in ('facebox.css', 'facebox.js', 'iphone.css', 'jquery.js', 'jquery.cookie.js', 'logo.png', 'logo120.png', 'thingdoc.css', 'thingdoc.js'):
shutil.copy(self.datadir + i, 'html_data/' + i)
#for i in ('facebox.css', 'facebox.js', 'iphone.css', 'jquery.js', 'jquery.cookie.js', 'logo.png', 'logo120.png', 'thingdoc.css', 'thingdoc.js'):
distutils.dir_util.copy_tree(self.datadir, 'html_data/')

template = self.jinja.get_template('template.html')
f.write(template.render(title = self.tree[1].name, unique="153431534841", titleimg = self.tree[1].image, titledesc = self.tree[1].desc, start = self.start, tree = self.tree, bom = self.bom, instr = self.instr, imagedir = self.imagedir))
Expand Down Expand Up @@ -462,7 +471,7 @@ def main():

if options.lint:
if thingdoc.process_file(options.lint, {}):
print 'No syntax errors detected'
print('No syntax errors detected')
sys.exit(0)
else:
sys.exit(1)
Expand All @@ -486,7 +495,7 @@ def main():
if options.wiki:
thingdoc.generate_wiki()

print 'All Done!'
print('All Done!')


if __name__ == '__main__':
Expand Down