aboutsummaryrefslogtreecommitdiffstats
path: root/docs/extending.rst
blob: 010c8106532795350159fc0056dc863b7c10f6d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
***************
Extending QFace
***************

QFace is easy to use and easy to extend. Your generator is just a small python
script using the qface library.

The script iterates over the domain model and writes files using a template
language.

See template engine documentation:

* http://jinja.pocoo.org
* http://jinja.pocoo.org/docs/dev/templates


.. code-block:: python

    from qface.generator import FileSystem, Generator

    def generate(input, output):
        # parse the interface files
        system = FileSystem.parse(input)
        # setup the generator
        generator = Generator(search_path='templates')
        # create a context object
        ctx = {'output': output, 'system': system}
        # apply the context on the template and write the output to file
        generator.write('{{output}}/modules.csv', 'modules.csv', ctx)

This script reads the input directory returns a system object from the domain
model. This is used as the root object for the code generation inside the
template. The  context object is applied to the file path as also on the named
template document. The output of the template is then written to the given file
path.

Below is a simple template which generates a CSV document of all interfaces,
structs and enums.

.. code-block:: jinja

    {% for module in system.modules %}
        {%- for interface in module.interfaces -%}
        INTERFACE, {{module}}.{{interface}}
        {% endfor -%}
        {%- for struct in module.structs -%}
        STRUCT , {{module}}.{{struct}}
        {% endfor -%}
        {%- for enum in module.enums -%}
        ENUM   , {{module}}.{{enum}}
        {% endfor -%}
    {% endfor %}

The template code iterates over the domain objects and generates text using a
mixture of output blocks ``{{}}`` and control blocks ``{%%}``.


Rule Base Generation
====================

The `RuleGenerator` allows you to extract the documentation rules into an external yaml file. This makes the python script more compact.


.. code-block:: python

    from qface.generator import FileSystem, RuleGenerator
    from path import Path

    here = Path(__file__).dirname()

    def generate(input, output):
        # parse the interface files
        system = FileSystem.parse(input)
        # setup the generator
        generator = RuleGenerator(search_path=here/'templates', destination=output)
        generator.process_rules(here/'docs.yaml', system)

The rules document is divided into several targets. Each target can have an own destination. A target is typical for exampe and app, client, server. Each target can have rules for the different symbols (system, module, interface, struct, enum). An each rule finally consists of a destination modifier, additional context and a documents collection.

.. code-block:: python

    <target>:
        <symbol>:
            context: {}
            destination: ''
            documents:
                <target>:<source>

* ``<target>`` is a name of the current target (e.g. client, server, plugin)
* ``<symbol>`` must be either system, module, interface, struct or enum


Here is an example (``docs.yaml``)

.. code-block:: yaml

    global:
        destination: '{{dst}}'
        system:
            documents:
                '{{project}}.pro': 'project.pro'
                '.qmake.conf': 'qmake.conf'
                'CMakeLists.txt': 'CMakeLists.txt'
    plugin:
        destination: '{{dst}}/plugin'
        module:
            context: {'module_name': '{{module|identifier}}'}
            documents:
                '{{module_name}}.pro': 'plugin/plugin.pro'
                'CMakeLists.txt': 'plugin/CMakeLists.txt'
                'plugin.cpp': 'plugin/plugin.cpp'
                'plugin.h': 'plugin/plugin.h'
                'qmldir': 'plugin/qmldir'
        interface:
            documents:
                '{{interface|lower}}.h': 'plugin/interface.h'
                '{{interface|lower}}.cpp': 'plugin/interface.cpp'
        struct:
            documents:
                '{{struct|lower}}.h': 'plugin/struct.h'
                '{{struct|lower}}.cpp': 'plugin/struct.cpp'


The rule generator adds the ``dst``, ``project`` as also the corresponding symbols to the context automatically. On each level you are able to change the destination or update the context.