diff options
author | Jan Pokorný <jpokorny@redhat.com> | 2013-03-28 14:32:11 +0100 |
---|---|---|
committer | Jan Pokorný <jpokorny@redhat.com> | 2013-03-28 14:32:11 +0100 |
commit | ecfa44f1a8d78798ce850b63dcc618f813b225df (patch) | |
tree | ac8e78d8978078ab8c1b6859ec4f9fe4860035a5 | |
parent | 823cb61b8532eb7234cac405d7787484a9c95a76 (diff) | |
download | ontogen-ecfa44f1a8d78798ce850b63dcc618f813b225df.tar.gz ontogen-ecfa44f1a8d78798ce850b63dcc618f813b225df.tar.xz ontogen-ecfa44f1a8d78798ce850b63dcc618f813b225df.zip |
Make the whole toolchain run smoothly incl. generating the graph
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
-rw-r--r-- | isaviz-postprocess.xsl | 39 | ||||
-rw-r--r-- | isaviz-preprocess.xsl | 15 | ||||
-rw-r--r-- | ontogen.py | 95 | ||||
-rw-r--r-- | ontogen.template | 2 | ||||
-rw-r--r-- | quickstart/Makefile | 135 | ||||
-rwxr-xr-x | quickstart/template.py | 36 |
6 files changed, 283 insertions, 39 deletions
diff --git a/isaviz-postprocess.xsl b/isaviz-postprocess.xsl new file mode 100644 index 0000000..a614cc1 --- /dev/null +++ b/isaviz-postprocess.xsl @@ -0,0 +1,39 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> + <xsl:template match="@*[starts-with(., 'file:/')]"> + <xsl:attribute name="{name()}"> + <xsl:value-of select="concat('.#', substring-after(., '#'))"/> + </xsl:attribute> + </xsl:template> + <xsl:template match="text()[starts-with(normalize-space(.), 'file:/')]"> + <xsl:variable name="space-prefix"> + <xsl:call-template name="iter-concat"> + <xsl:with-param name="itercat" select="' '"/> + <xsl:with-param name="itercount" + select="floor(string-length(substring-before(., '#')) div 3 * 2)"/> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat($space-prefix, '#', substring-after(., '#'))"/> + </xsl:template> + + <xsl:template name="iter-concat"> + <xsl:param name="itercat"/> + <xsl:param name="itercount"/> + <xsl:choose> + <xsl:when test="$itercount = 0"/> + <xsl:otherwise> + <xsl:value-of select="$itercat"/> + <xsl:call-template name="iter-concat"> + <xsl:with-param name="itercat" select="$itercat"/> + <xsl:with-param name="itercount" select="$itercount - 1"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:template> +</xsl:stylesheet> diff --git a/isaviz-preprocess.xsl b/isaviz-preprocess.xsl new file mode 100644 index 0000000..b85a180 --- /dev/null +++ b/isaviz-preprocess.xsl @@ -0,0 +1,15 @@ +<!-- + shamelessly copied from + http://en.wikipedia.org/wiki/Identity_transform#Using_XSLT + --> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:owl="http://www.w3.org/2002/07/owl#" + xmlns:ex="http://purl.org/net/ns/ex#"> + <xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> + <xsl:template match="owl:Ontology|ex:Example|comment()"/> +</xsl:stylesheet> @@ -6,8 +6,10 @@ from sys import stdout, stderr from datetime import date from textwrap import TextWrapper, dedent -from os import extsep, mkdir, symlink, remove -from os.path import basename, dirname, exists, isdir, islink, join, splitext +from os import extsep, getcwd, mkdir, symlink, remove +from os.path import basename, dirname, exists, isdir, isfile, islink, join, \ + splitext, sep as pathsep +from shutil import copy2 as copy from subprocess import call from shlex import split #import codecs @@ -18,8 +20,10 @@ logging.basicConfig() log = logging.getLogger(__name__) +#VERSIONSEP = sep # non-unix paths -> problems VERSIONSEP = '/' ONTSEP = '#' +INDEX = 'index.html' TEMPLATE_GENSHI = join(dirname(__file__), 'ontogen.template') TEMPLATE_XSLT = join(dirname(__file__), 'ns-schema.xsl') @@ -48,16 +52,20 @@ class ClassProperty(property): # another common fixer (adjusted): http://stackoverflow.com/a/13937525 class InheritDocstring(type): def __init__(this, name, bases, attrs): - if getattr(this, '__doc__', None) is None: - setattr(this, '__doc__', super(this, this).__doc__) + if not getattr(this, '__doc__', None): + this.__doc__ = super(this, this).__doc__ + super(InheritDocstring, InheritDocstring).__init__(this, name, + bases, attrs) -def force_symlink(source, link_name): +def custom_symlink(source, link_name, report=False): if exists(link_name): if islink(link_name): remove(link_name) else: raise RuntimeError('{0} is in our way'.format(link_name)) + if report is not False: + print '{0}: {1}'.format(report, link_name) symlink(source, link_name) @@ -89,6 +97,19 @@ class Example(object): return '' +# combine this "example" with Makefile to trigger the magic +class ExampleSelfFigureProto(type): + def __new__(self, ontology): + base = ontology.base + class ExampleSelfFigure(Example): + """Illustrative figure of the vocabulary""" + image_full = ontology.version + VERSIONSEP + base + extsep + 'svg' + image = base + extsep + 'svg' # referenced from html + symlink = base + extsep + 'svg' + + return ExampleSelfFigure + + # # Abstract RDF level # @@ -223,11 +244,17 @@ class Ontology(RDFEntity): @ClassProperty @classmethod - def base(this): + def base_uri_full(this): return this.base_uri + VERSIONSEP + this.version @ClassProperty @classmethod + def base(this): + # TODO: cache me please? + return this.base_uri.rpartition('/')[2] + + @ClassProperty + @classmethod def creator(this): return '' @@ -286,13 +313,14 @@ class Ontology(RDFEntity): return proper_subclasses and unique_ids @classmethod - def _auto_filename(this): - base = this.base_uri.rpartition('/')[2] - if not exists(base): - mkdir(base) - elif not isdir(base): - raise RuntimeError('{0} is not a directory'.format(base)) - return (base + VERSIONSEP + this.version + extsep + 'rdf', + def _prepare_targets(this): + base = this.base + version = this.version + if not exists(version): + mkdir(version) + elif not isdir(version): + raise RuntimeError('{0} is not a directory'.format(version)) + return (version + VERSIONSEP + base + extsep + 'rdf', base + extsep + 'rdf') @classmethod @@ -306,8 +334,8 @@ class Ontology(RDFEntity): ) log.debug('running {0}'.format(split(cmd))) if call(split(cmd)): - raise RuntimeError('Something went wrong while running {0}' - .format(cmd)) + raise RuntimeError('Something went wrong while running {0}; pwd={1}' + .format(cmd, getcwd())) @classmethod def generate(this, ontologies=(), template=None, outfile='-', gendoc=True): @@ -334,7 +362,7 @@ class Ontology(RDFEntity): outobj = stdout else: if outfile == 'AUTO': - outfile, symfile = this._auto_filename() + outfile, symfile = this._prepare_targets() outobj = open(outfile, "w") tmpldict = dict(Ontology=this, namespaces=namespaces) @@ -345,14 +373,21 @@ class Ontology(RDFEntity): # htmldoc htmlfile = None if gendoc and outfile != '-': - htmlfile = splitext(outfile)[0] + extsep + 'html' + htmlfile = join(dirname(outfile), INDEX) this.gendoc(outfile, htmlfile) # symlink to base (non-versioned) only for the newest ontology if ontologies[-1] is this and symfile: - force_symlink(outfile, symfile) + custom_symlink(outfile, symfile, 'output') if htmlfile: - force_symlink(htmlfile, splitext(symfile)[0] + extsep + 'html') + custom_symlink(htmlfile, splitext(symfile)[0] + extsep + 'html', + 'html') + for ex in [e for e in this.examples if e.image]: + if ex.__name__ == 'ExampleSelfFigure': + custom_symlink(ex.image_full, ex.symlink, 'self-figure') + elif not pathsep in img: + img = ex.image + custom_symlink(join(this.base, img), img, 'image') if outobj is not stdout: outobj.close() @@ -362,6 +397,27 @@ class Ontology(RDFEntity): this.generate() +class PrependFigure(InheritDocstring): + def __new__(this, name, bases, attrs): + ret = super(PrependFigure, PrependFigure).__new__(this, name, bases, + attrs) + try: + if all(map(lambda x: isinstance(x, basestring), + map(lambda x: getattr(ret, x, None), + ('base', 'version'))) + ) or True: + setattr(ret, 'examples', [ExampleSelfFigureProto(ret)] + + list(getattr(ret, 'examples', ()))) + except NotImplementedError: + pass + finally: + return ret + + +class OntologyWithFigure(Ontology): + __metaclass__ = PrependFigure + + # # Generalized view # @@ -379,6 +435,7 @@ class Ontologies(object): assert all(map(lambda o: o.valid(), ontologies)) assert reduce(lambda a, b: issubclass(a, b) or issubclass(b, a), ontologies) + map(lambda a: setattr(a, '_final', True), ontologies) merge = self._ontologies + list(ontologies) self._ontologies = list(sorted(set(merge), key=lambda o: o.version)) # make it decorator-compatible diff --git a/ontogen.template b/ontogen.template index 7bdc287..a885b98 100644 --- a/ontogen.template +++ b/ontogen.template @@ -22,7 +22,7 @@ <owl:imports rdf:resource="http://purl.org/dc/elements/1.1/"/> <owl:versionInfo>${Ontology.version}</owl:versionInfo><!--! --><py:if test="Ontology.priorVersion"> - <owl:priorVersion>${Ontology.priorVersion.base}</owl:priorVersion><!--! + <owl:priorVersion>${Ontology.priorVersion.base_uri_full}</owl:priorVersion><!--! --></py:if><py:if test="Ontology.label"> <rdfs:label>${Ontology.label}</rdfs:label><!--! --></py:if><py:if test="Ontology.comment"> diff --git a/quickstart/Makefile b/quickstart/Makefile new file mode 100644 index 0000000..07359b2 --- /dev/null +++ b/quickstart/Makefile @@ -0,0 +1,135 @@ +# prerequisities: +# - xsltproc +# - inkscape +# - isaviz (http://www.w3.org/2001/11/IsaViz/) + +#DEBUG = 1 +ifndef DEBUG + DEBUG = 0 +endif +ifeq (${DEBUG},0) + DEBUG_RM_DEP = rm -f -- $< +else + DEBUG_RM_DEP = +endif + +ONTOGEN_dir ?= ontogen +HTML_NSSCHEMAXSL_file = ${ONTOGEN_dir}/ns-schema.xsl +RDF_ISAVIZPREPROCESSXSL_file = ${ONTOGEN_dir}/isaviz-preprocess.xsl +RDF_ISAVIZPOSTPROCESSXSL_file = ${ONTOGEN_dir}/isaviz-postprocess.xsl + +SVG_ISAVIZ_path ?= ~/wrkspc/sw/IsaViz +SVG_ISAVIZ_runner ?= ./run.sh +SVG_ISAVIZ_cfg = ~/isaviz.cfg +SVG_ISAVIZ_font = Liberation Mono +SVG_ISAVIZ_fontsize = 10 +# LR or TB (not recommended) +SVG_ISAVIZ_orientation = LR +SVG_ISAVIZ_charcount = 30 + +SVG_BIGGERXSL_url = http://inkscape-forum.andreas-s.net/attachment/2730/bigger.xsl +#SVG_BIGGERXSL_url = http://sourceforge.net/mailarchive/attachment.php?list_name=inkscape-user&message_id=20080925142218.2ba4194e%40nrri.umn.edu +#SVG_BIGGERXSL_file ?= $(shell \ +# wget -nv -nc --content-disposition --delete-after ${SVG_BIGGERXSL_url} \ +# | cut -d' ' -f6 \ +#) +SVG_BIGGERXSL_file = bigger.xsl +SVG_BIGGERXSL_scale = 0.9 + +TARGETS_PY = $(shell \ + find -maxdepth 1 -name '*.py' -and -executable -and -type f -printf '%f\n' \ +) +TARGETS = $(TARGETS_PY:.py=) +REMOVE = ${TARGETS:=.requires} ${TARGETS:=.1.rdf} ${TARGETS:=.1.svg} ${TARGETS:=.2.svg} +REMOVE_SYMLINKS = ${TARGETS:=.rdf} ${TARGETS:=.html} ${TARGETS:=.svg} + +.PHONY = ${TARGETS} clean mrproper + +# top-level wrapper +${TARGETS}: %: %.requires + ${DEBUG_RM_DEP} + +ifneq ($(MAKECMDGOALS),clean) + $(foreach target,${TARGETS},$(eval -include ${target:=.requires})) +endif + +# rdf + html +$(TARGETS:=.requires): %.requires: %.rdf + touch $< + +$(TARGETS:=.rdf) : %.rdf: %.py + ./$< AUTO | grep -E '^self-figure: ' | cut -d' ' -f2 \ + | xargs -I'{}' find -L {} -printf '$(@:.rdf=): %f\n' \ + >> $(@:.rdf=.requires) + # ^ -not/-empty condition? + +# only used if html accidentally deleted and rdf kept +$(TARGETS:=.html):: %.html: %.rdf + xsltproc --stringparam xmlfile $< ${HTML_NSSCHEMAXSL_file} $< > $@ + +$(TARGETS:=.svg): %.svg: %.2.svg ${SVG_BIGGERXSL_file} + xsltproc --stringparam scale ${SVG_BIGGERXSL_scale} \ + ${SVG_BIGGERXSL_file} $< > $@ + inkscape $@ --verb FitCanvasToDrawing --verb FileVacuum \ + --verb FileSave --verb FileClose + ${DEBUG_RM_DEP} + +$(TARGETS:=.1.rdf): %.1.rdf: %.rdf ${RDF_ISAVIZPREPROCESSXSL_file} + xsltproc ${RDF_ISAVIZPREPROCESSXSL_file} $< > $@ + +$(TARGETS:=.2.svg): %.2.svg: %.1.svg ${RDF_ISAVIZPOSTPROCESSXSL_file} + xsltproc ${RDF_ISAVIZPOSTPROCESSXSL_file} $< > $@ + ${DEBUG_RM_DEP} + +$(TARGETS:=.1.svg): %.svg: %.rdf ${SVG_ISAVIZ_path}/${SVG_ISAVIZ_runner} + @echo " Sorry, this part currently requires manual actions:" + @echo " 1. File - Import - Replace - RDF/XML from file: $<" + @echo " 2. View - Suggest Layout (only to get a better form; 14pt?)" + @echo " 3. Optionally increase font size for better final look" + @echo " via Edit - Preferences - Rendering/GSS" + @echo " 4. Export - SVG: $@" + mv ${SVG_ISAVIZ_cfg} ${SVG_ISAVIZ_cfg}.$(@:.1.svg=) || : + touch ${SVG_ISAVIZ_cfg} + echo '<?xml version="1.0" encoding="UTF-8"?>' >>${SVG_ISAVIZ_cfg} + echo '<isv:config xmlns:isv="http://www.w3.org/2001/10/IsaViz">' >>${SVG_ISAVIZ_cfg} + echo ' <isv:directories>' >>${SVG_ISAVIZ_cfg} + echo ' <isv:tmpDir value="true">/tmp</isv:tmpDir>' >>${SVG_ISAVIZ_cfg} + echo ' <isv:projDir>/tmp</isv:projDir>' >>${SVG_ISAVIZ_cfg} + echo ' <isv:rdfDir>$(CURDIR)</isv:rdfDir>' >>${SVG_ISAVIZ_cfg} + echo ' <isv:dotExec>/bin/dot</isv:dotExec>' >>${SVG_ISAVIZ_cfg} + #echo ' <isv:graphvizFontDir>/tmp</isv:graphvizFontDir>' >>${SVG_ISAVIZ_cfg} + echo ' </isv:directories>' >>${SVG_ISAVIZ_cfg} + echo ' <isv:constants abbrevSyntax="true"' >>${SVG_ISAVIZ_cfg} + echo ' alwaysIncludeLang="false"' >>${SVG_ISAVIZ_cfg} + echo ' anonymousNodes="genid:"' >>${SVG_ISAVIZ_cfg} + echo ' antialiasing="false"' >>${SVG_ISAVIZ_cfg} + echo ' backgroundColor="-1579033"' >>${SVG_ISAVIZ_cfg} + echo ' defaultLang="en"' >>${SVG_ISAVIZ_cfg} + echo ' defaultNamespace=""' >>${SVG_ISAVIZ_cfg} + echo ' displayLabels="false"' >>${SVG_ISAVIZ_cfg} + echo ' graphFont="${SVG_ISAVIZ_font} Plain ${SVG_ISAVIZ_fontsize}"' \ + >>${SVG_ISAVIZ_cfg} + echo ' graphOrient="${SVG_ISAVIZ_orientation}"' >>${SVG_ISAVIZ_cfg} + echo ' incGSSstyling="false"' >>${SVG_ISAVIZ_cfg} + echo ' maxLitCharCount="${SVG_ISAVIZ_charcount}"' >>${SVG_ISAVIZ_cfg} + echo ' parsingMode="0"' >>${SVG_ISAVIZ_cfg} + echo ' prefixInTf="true"' >>${SVG_ISAVIZ_cfg} + echo ' saveWindowLayout="false"' >>${SVG_ISAVIZ_cfg} + echo ' showAnonIds="false" swingFont="SansSerif Plain 12"/>' \ + >>${SVG_ISAVIZ_cfg} + echo '</isv:config>' >>${SVG_ISAVIZ_cfg} + pushd ${SVG_ISAVIZ_path} 2>/dev/null && \ + ( ${SVG_ISAVIZ_runner} || : ) && \ + popd 2>/dev/null + mv ${SVG_ISAVIZ_cfg}.$(@:.1.svg=) ${SVG_ISAVIZ_cfg} || rm -f ${SVG_ISAVIZ_cfg} + ${DEBUG_RM_DEP} + +${SVG_BIGGERXSL_file}: + wget -nv -nc --content-disposition ${SVG_BIGGERXSL_url} -O- > $@ + +clean: + for f in ${REMOVE_SYMLINKS}; do rm -f -- $$(readlink $$f) $$f; done + rm -f -- ${REMOVE} + +mrproper: clean + rm -f -- ${SVG_BIGGERXSL_file} diff --git a/quickstart/template.py b/quickstart/template.py index 0eaea7f..ead6874 100755 --- a/quickstart/template.py +++ b/quickstart/template.py @@ -4,9 +4,13 @@ from sys import argv #from genshi.input import XML -from ontogen.ontogen import Property, Class, Example, Ontology, Ontologies +from ontogen.ontogen import Property, Class, Example, OntologyWithFigure, \ + Ontologies -BASE = 'http://purl.org/net/foo' +#from ontogen.ontogen import log +#log.setLevel('DEBUG') + +BASE = 'http://example.org/net/template' # @@ -26,6 +30,7 @@ class TFoo(Foo): Represents foos that are special because of the T-shape. """ + # # properties # @@ -49,21 +54,15 @@ class baz(bar): # examples # -# v0.1 - -class ex_0_1_schema(Example): - """Illustrative figure of the vocabulary.""" - image = '0.1.svg' - class ex_0_1(Example): """An example snippet. -<foo:tfoo about="#mytfoo"> - <foo:baz>test</foo:baz> -</foo:tfoo> +<tmpl:tfoo about="#mytfoo"> + <tmpl:baz>test</tmpl:baz> +</tmpl:tfoo> """ - pfx = 'foo:' + pfx = 'tmpl:' # @@ -74,7 +73,7 @@ class ex_0_1(Example): ontologies = Ontologies() -class foo(Ontology): +class template(OntologyWithFigure): """Descriptive vocabulary for foos This vocabulary serves a purpose of shedding light into semantics @@ -82,13 +81,13 @@ class foo(Ontology): """ base_uri = BASE #creator = XML('''\ - # <dc:foo xmlns:dc="http://purl.org/dc/elements/1.1/" - # >John Doe</dc:foo>''') + # <dc:X xmlns:dc="http://purl.org/dc/elements/1.1/" + # >John Doe</dc:X>''') creator = 'John Doe' @ontologies.include -class foo_0_1(foo): +class template_0_1(template): version = '0.1' issued = '2013-02-19' modified = '2013-03-20' @@ -101,14 +100,13 @@ class foo_0_1(foo): baz, ] examples = [ - ex_0_1_schema, ex_0_1, ] #@ontologies.include -#@foo_0_1.supersededBy -#class foo_0_2(foo): +#@template_0_1.supersededBy +#class template_0_2(template): # ... |