Skip to content

Commit

Permalink
Merge pull request #434 from peuter/new-docs
Browse files Browse the repository at this point in the history
- add scaffolding for plugins
  • Loading branch information
ChristianMayer committed Oct 16, 2016
2 parents d034964 + ed210de commit c9fe5ed
Show file tree
Hide file tree
Showing 20 changed files with 764 additions and 94 deletions.
12 changes: 12 additions & 0 deletions .doc/commands/__init__.py
Expand Up @@ -17,8 +17,16 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
import os
import sys
import gettext
import ConfigParser

kwargs = {}
if sys.version_info[0] < 3:
kwargs['unicode'] = True

gettext.install('messages', **kwargs)


class Command(object):

Expand All @@ -27,5 +35,9 @@ def __init__(self):
self.config.read(os.path.join('.doc', 'config.ini'))
self.root_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..', '..'))

def init_locale(self, lang):
t = gettext.translation('messages', localedir=self.config.get("DEFAULT", "locale"), languages=[lang])
t.install(**kwargs)

def process_output(self, line):
print(line.rstrip())
76 changes: 54 additions & 22 deletions .doc/commands/scaffolding.py
Expand Up @@ -30,40 +30,60 @@ def __init__(self):
self.log = logging.getLogger("scaffolder")
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

def _run(self, language, widget_name, force=False):
def _run(self, language, widget_name, plugin_name, force=False):
self.init_locale(language)
section = "manual-%s" % language
template = os.path.join(self.root_dir, self.config.get(section, "widget-template"))
if not os.path.exists(template):
self.log.error("widget template '%s' language '%s' not found" % (widget_name,language))
exit(1)

mode = 'widget'if widget_name else 'plugin'
name = widget_name if widget_name else plugin_name
widgets = []
for file in os.listdir(os.path.join("src", "structure", "pure")):
if file.endswith(".js") and not file.startswith("_"):
# this is a widget
found_widget = os.path.splitext(file)[0]
if widget_name == "ALL" or widget_name.lower() == found_widget.lower():
widgets.append(found_widget)
if widget_name:
template = os.path.join(self.root_dir, self.config.get(section, "widget-template"))
if not os.path.exists(template):
self.log.error("widget template '%s' language '%s' not found" % (widget_name, language))
exit(1)

for file in os.listdir(os.path.join("src", "structure", "pure")):
if file.endswith(".js") and not file.startswith("_"):
# this is a widget
found_widget = os.path.splitext(file)[0]
if widget_name == "ALL" or widget_name.lower() == found_widget.lower():
widgets.append(found_widget)
elif plugin_name:
template = os.path.join(self.root_dir, self.config.get(section, "plugin-template"))
if not os.path.exists(template):
self.log.error("plugin template '%s' language '%s' not found" % (plugin_name, language))
exit(1)

plugin_dir = os.path.join("src", "plugins")
if plugin_name == 'ALL':
widgets = [name for name in os.listdir(plugin_dir) if os.path.isdir(os.path.join(plugin_dir, name))]
else:
widgets = [name for name in os.listdir(plugin_dir)
if os.path.isdir(os.path.join(plugin_dir, name)) and name.lower() == plugin_name.lower()
]

if len(widgets) == 0:
self.log.error("widget '%s' does not exist" % widget_name)
self.log.error("%s '%s' does not exist" % (mode, name))
exit(1)

if len(widgets) > 1:
# do not allow forced overriding of multiple widgets, too dangerous
force = False

target_path = os.path.join(self.root_dir, self.config.get(section, "%ss" % mode))

for widget_name in widgets:
print("Generating doc source for '%s' widget in language '%s'" % (widget_name, language))
target = os.path.join(self.root_dir, self.config.get(section, "widgets"), widget_name.lower(), "index.rst")
print("Generating doc source for '%s' %s in language '%s'" % (widget_name, mode, language))
target = os.path.join(target_path, widget_name.lower(), "index.rst")

if force is False and os.path.exists(target):
self.log.error("widget documentation already exists for widget '%s' in language '%s'" % (widget_name, language))
self.log.error("%s documentation already exists for '%s' in language '%s'" % (mode, widget_name, language))
continue

headline = "Das %s Widget" % widget_name
headline_mark = "=" * len(headline)
headline += "\n%s" % headline_mark
headline = _("The %s widget") % widget_name if mode == 'widget' else _("The %s plugin") % widget_name
headline_mark = u"=" * len(headline)
headline += u"\n%s" % headline_mark
headline = headline.encode('utf-8')

with open(template, "r") as f:
source = f.read()
Expand All @@ -88,10 +108,22 @@ def run(self, args):
parser.add_argument("--widget", "-w", dest="widget",
help="Name of the widget to generate docs for")

parser.add_argument("--plugin", "-p", dest="plugin",
help="Name of the plugin to generate docs for")

options = parser.parse_args(args)

if 'widget' not in options:
self.log.error("please provide a widget name" % options.type)
if 'widget' not in options and 'plugin' not in options:
self.log.error("please provide a widget or plugin name")
print(options)
exit(1)

if 'widget' in options and options.widget is not None and \
'plugin' in options and options.plugin is not None:
self.log.error("please provide either a widget or a plugin name")
exit(1)

self._run(options.language, options.widget, force=options.force)
self._run(options.language,
options.widget if 'widget' in options else None,
options.plugin if 'plugin' in options else None,
force=options.force)
1 change: 1 addition & 0 deletions .doc/commands/translation.py
Expand Up @@ -31,6 +31,7 @@ def __init__(self):
def _run(self):
pygettext = sh.Command("pygettext")
pygettext("-d", "messages", "-p", self.config.get("DEFAULT", "locale"), ".doc/docutils/directives/*.py",
".doc/commands/*.py",
_out=self.process_output, _err=self.process_output)

def run(self, args):
Expand Down
3 changes: 2 additions & 1 deletion .doc/config.ini
Expand Up @@ -15,13 +15,14 @@ target=out/redirect-structure.map
[manual-de]
source=%(manual-basedir)s/de
widgets=%(manual-basedir)s/de/config/widgets
plugins=%(manual-basedir)s/de/config/plugins
plugins=%(manual-basedir)s/de/config/widgets/plugins
target=out/docs/de/manual
source-type=rst
target-type=html

widget-template=%(manual-templates)s/de/widget-template.rst
widget-examples-cache=%(cachedir)s/widget_examples/manual
plugin-template=%(manual-templates)s/de/plugin-template.rst
header-file=%(manual-basedir)s/de/parts/header.rst

[api]
Expand Down
4 changes: 3 additions & 1 deletion .doc/docutils/directives/common.py
Expand Up @@ -42,7 +42,9 @@ def init_type_mapping(self):
'string': _('string'),
'decimal': _('decimal'),
'uri': _('uri'),
'addr': _('addr')
'addr': _('addr'),
'nonNegativeInteger': _('nonNegativeInteger'),
'dimension': _('dimension')
}

def init_locale(self):
Expand Down
12 changes: 10 additions & 2 deletions .doc/docutils/directives/widget_example.py
Expand Up @@ -191,12 +191,16 @@ def run(self):
# read meta settings
design = settings_node.get("design", "metal")
settings['selector'] = settings_node.get("selector", ".widget_container")
if settings_node.get("sleep"):
settings['sleep'] = settings_node.get("sleep")

for screenshot in settings_node.iter('screenshot'):
shot = {
"name": screenshot.get("name", name + str(counters[name] + shot_index)),
"data": []
}
if screenshot.get("sleep"):
shot['sleep'] = screenshot.get("sleep")
if screenshot.get("clickpath", None):
shot['clickPath'] = screenshot.get('clickpath')
if screenshot.get("waitfor", None):
Expand All @@ -205,10 +209,14 @@ def run(self):
shot_index += 1

for data in screenshot.iter('data'):
shot['data'].append({
values = {
'address': data.get("address", "0/0/0"),
'value': data.text
})
}
if data.get("type"):
values['type'] = data.get("type")

shot['data'].append(values)

for caption in screenshot.iter('caption'):
if 'caption' not in shot:
Expand Down
3 changes: 3 additions & 0 deletions .doc/protractor.conf.js
Expand Up @@ -25,6 +25,9 @@ exports.config = {
if (config.params && config.params.subDir) {
browser.onlySubDir = config.params.subDir;
}
if (config.params && config.params.screenshots) {
browser.screenshots = config.params.screenshots;
}
});
}
};
23 changes: 21 additions & 2 deletions .doc/screenshots-spec.js
Expand Up @@ -162,6 +162,7 @@ describe('generation screenshots from jsdoc examples', function () {
});

var examplesDir = path.join("cache", "widget_examples");
var whiteList = browser.screenshots ? browser.screenshots.split(",") : [];

fs.readdirSync(examplesDir).forEach(function(fileName) {
var subDir = path.join(examplesDir, fileName);
Expand All @@ -170,6 +171,10 @@ describe('generation screenshots from jsdoc examples', function () {
}
if (fs.statSync(subDir).isDirectory()) {
fs.readdirSync(subDir).forEach(function(fileName) {
if (whiteList.length > 0 && whiteList.indexOf(fileName) < 0) {
// skip this one
return;
}
var filePath = path.join(subDir, fileName);
var stat = fs.statSync(filePath);
if (stat.isFile()) {
Expand Down Expand Up @@ -230,7 +235,7 @@ describe('generation screenshots from jsdoc examples', function () {
}

// wait for everything to be rendered
browser.sleep(300);
browser.sleep(settings.sleep || 300);

var widget = element(by.css(selectorPrefix+settings.selector));
browser.wait(function() {
Expand All @@ -240,7 +245,18 @@ describe('generation screenshots from jsdoc examples', function () {

if (setting.data && Array.isArray(setting.data)) {
setting.data.forEach(function (data) {
cvMockup.sendUpdate(data.address, data.value);
var value = data.value;
if (data.type) {
switch(data.type) {
case "float":
value = parseFloat(value);
break;
case "int":
value = parseInt(value);
break;
}
}
cvMockup.sendUpdate(data.address, value);
});
}
if (setting.clickPath) {
Expand All @@ -258,6 +274,9 @@ describe('generation screenshots from jsdoc examples', function () {

widget.getSize().then(function (size) {
widget.getLocation().then(function (location) {
if (setting.sleep) {
browser.sleep(setting.sleep);
}
browser.takeScreenshot().then(function (data) {
var base64Data = data.replace(/^data:image\/png;base64,/, "");
var imgFile = path.join(settings.screenshotDir, setting.name + ".png");
Expand Down
3 changes: 2 additions & 1 deletion Gruntfile.js
Expand Up @@ -520,7 +520,8 @@ module.exports = function(grunt) {
configFile: ".doc/protractor.conf.js",
args: {
params: {
subDir: grunt.option('subDir')
subDir: grunt.option('subDir'),
screenshots: grunt.option('files')
},
capabilities: {
browserName: grunt.option('browserName') || 'firefox',
Expand Down
105 changes: 105 additions & 0 deletions doc/manual/_templates/de/plugin-template.rst
@@ -0,0 +1,105 @@
.. _%%%WIDGET_NAME_LOWER%%%:

%%%HEADLINE%%%

.. api-doc:: %%%WIDGET_NAME%%%

Beschreibung
------------

.. todo::

Plugin Beschreibung hinzufügen inkl. Beispielen, vorhandene Beispiele korrigieren, vervollständigen


Einstellungen
-------------

Für eine grundsätzliche Erklärung des Aufbaus der Konfiguration und der Definition der im folgenden benutzten
Begriffe (Elemente, Attribute) sollte zunächst dieser Abschnitt gelesen werden: :ref:`visu-config-details`.

Das Verhalten und Aussehen des %%%WIDGET_NAME%%%-Plugins kann durch die Verwendung von Attributen und Elementen beeinflusst werden.
Die folgenden Tabellen zeigen die erlaubten Attribute und Elemente. In den Screenshots sieht man, wie
beides über den :ref:`Editor <editor>` bearbeitet werden kann.

Nur die mit ..... unterstrichenen Attribute/Elemente müssen zwingend angegeben werden, alle anderen sind optional und können
daher weg gelassen werden.


Erlaubte Attribute im %%%WIDGET_NAME%%%-Element
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. parameter-information:: %%%WIDGET_NAME_LOWER%%%

.. widget-example::
:editor: attributes
:scale: 75
:align: center

<caption>Attribute im Editor (vereinfachte Ansicht) [#f1]_</caption>
<meta>
<plugins>
<plugin name="%%%WIDGET_NAME_LOWER%%%" />
</plugins>
</meta>
<%%%WIDGET_NAME_LOWER%%%>
<layout colspan="4" />
</%%%WIDGET_NAME_LOWER%%%>


Erlaubte Kind-Elemente und deren Attribute
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. elements-information:: %%%WIDGET_NAME_LOWER%%%

.. widget-example::
:editor: elements
:scale: 75
:align: center

<caption>Elemente im Editor</caption>
<meta>
<plugins>
<plugin name="%%%WIDGET_NAME_LOWER%%%" />
</plugins>
</meta>
<%%%WIDGET_NAME_LOWER%%%>
<layout colspan="4" />
<label>%%%WIDGET_NAME%%%</label>
<address transform="DPT:1.001" mode="readwrite">1/1/0</address>
</%%%WIDGET_NAME_LOWER%%%>

XML Syntax
----------

Alternativ kann man für das %%%WIDGET_NAME%%% Plugin auch von Hand einen Eintrag in
der :doc:`visu_config.xml <../../../xml-format>` hinzufügen.

.. CAUTION::
In der Config selbst dürfen NUR UTF-8 Zeichen verwendet
werden. Dazu muss ein auf UTF-8 eingestellter Editor verwendet werden!

Hier der minimale Beispielcode der das %%%WIDGET_NAME%%% Plugin aus dem folgenden Screenshot erzeugt:

.. widget-example::

<settings>
<screenshot name="%%%WIDGET_NAME_LOWER%%%_simple">
<caption>%%%WIDGET_NAME%%%, einfaches Beispiel</caption>
<data address="1/4/0">0</data>
</screenshot>
</settings>
<meta>
<plugins>
<plugin name="%%%WIDGET_NAME_LOWER%%%" />
</plugins>
</meta>
<%%%WIDGET_NAME_LOWER%%%>
<label>%%%WIDGET_NAME%%%</label>
<address transform="DPT:1.001" mode="readwrite">1/1/0</address>
</%%%WIDGET_NAME_LOWER%%%>


.. rubric:: Fußnoten

.. [#f1] In der vereinfachten Ansicht sind ggf. einige Dinge ausgeblendet. In der Expertenansicht ist alles zu sehen.

0 comments on commit c9fe5ed

Please sign in to comment.