pxDoc Common Librairies

pxDoc - Common Libraries and Plugins

pxDoc Common Libraries and Plugins are a set of pxDoc Modules and/or Java classes or interfaces providing useful capabilities reusable in any pxDoc Generator. Among others, you can:

  • query and include diagrams from your models,
  • provide generic templates for EMF model,
  • manipulate images (convert to AWT, split large images on several pages...)
  • ...

The language renderers are part of the pxDoc common plugins but they are described in a dedicated section.

There is no obligation to use these common libraries. You can also develop your own libraries, or extend the provided ones to match your specific needs.

Importing sources into your workspace

You can of course import the common libraries in your workspace to get a view on the common Modules and libraries included in pxDoc

Common Services / org.pragmaticmodeling.pxdoc.common.lib

The Common Services library is provided for demonstration purpose, and as a support for the set of generator examples shipped with pxDoc. You are free to use or not this library, or find inspiration to define your own "common lib".

CommonServices.pxdoc Module

The CommonServices.pxdoc module provides generic templates and functions that can be used by every documentation generator:
  • manage basic presentation of an object (so far, bookmarks management and objects descriptions retrieval). This is useful if your generator consumes many different java objects, with different ways of storing documentation, occasionally in many different documentation formats (raw text, html, markdown...)
  • provide basic reusable templates for optional or required documentation
  • provide a way to improve your documents, with the suggestImprovements boolean parameter. When set to true, warnings are generated in the document to enforce writing a documentation for the concerned objects.
  • ... and more useful generic services to come in the next releases!

CommonServices setup

OPTIONAL - When using the CommonServices module in your generator, you can inject your custom instance of IDescriptionProvider (see example below).

The IDescriptionProvider Interface

Among all properties that an object can hold, its human readable descriptions play a particular role. They are usually generated early when documenting an object, while other business properties are treated differently in following document sections.

The IDescriptionProvider interface gives the ability to return a description for every object processed by a pxDoc generator, as well as the expected description format (e.g., html, raw text, markdown...)

It is also responsible to provide a valid bookmark id for every object processed during generation, and decide which objects should be generated with a bookmark.

The class DefaultDescriptionProvider is the default implementation of IDescriptionProvider. It returns null as a description for every object, but is able to generate valid bookmarks for every object.

If you plan to use the CommonServices module, you will need to :

  • provide your own IDescriptionProvider by subclassing DefaultDescriptionProvider and provide your own implementations of the getDescription*(*) methods.
  • inject your IDescriptionProvider instance to the CommonServices when starting the generation (in the root template):
					root template main(Object model) {
					
						// Commons lib configuration : set a description provider able to get information about object description
						descriptionProvider = new MyDescriptionProvider(this)
						
						document {
							// content...
						}
					
					}

EMF Services / org.pragmaticmodeling.pxdoc.emf.lib

The Emf Services library is provided for demonstration purpose, and as a support for the set of generator examples shipped with pxDoc. You are free to use or not this library, or find inspiration to define your own "emf lib".

The EmfServices module is a set of templates and functions that allow to generate documentation for any EMF EObject. It takes benefit of the reflective EMF API to transform EObjects into documentation.

It defines two ways of EObject-to-doc transformation:

  • DocKind.form, for a form-like presentation of EObject features (attributes, references, methods)
  • DocKind.table, for a table regrouping all EObject features

You can get your documentation for an EObject by invoking the genericDoc template:

									var int level = 1
									var boolean recursive = true
									apply genericDoc(anEObject, DocKind.^table, level, recursive)

With:

  • anEObject, the model object
  • docKind, between form or table
  • level gives the heading (title) level that should be applied to the model object
  • recursive, to generate the documentation recursively on the object's children

And because some EObject's attributes are too technical, or rarely/never used, the EmfServices module provide a way to filter some EStructuralFeature from the generation. This is the role of the field excludedFeatures, which you can access the following way:

									root template main(Object model) {
									
										// exclude some EClasses
										excludedEClasses += EcorePackage.Literals.EANNOTATION
										// exclude EStructualFeatures
										excludedFeatures += EcorePackage.Literals.ECLASSIFIER__DEFAULT_VALUE
										excludedFeatures += EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS
										
										document {
											// content...
										}
									
									}
									

The EmfServices.pxdoc files contains comments to explain each template. Do not hesitate to have a look at it.

You can also refer to the EMF Example to see how these templates can be used.

EmfServices setup

OPTIONAL - When using the EmfServices module in your generator, you can inject your custom instances of:

  • labelProvider = myLabelProvider
  • contentProvider = myContentProvider

OPTIONAL - You can also define filters to exclude some model elements or features from the generation, by adding EClass or EStructuralFeature to the two following sets:

  • excludedEClasses += MyEmfPackage.Literals.MY_CLASS
  • excludedFeatures += MyEmfPackage.Literals.MY_CLASS__FEATURE

Diagram Services / org.pragmaticmodeling.pxdoc.diagrams.lib

The Diagram Services library is provided for demonstration purpose, and as a support for the set of generator examples shipped with pxDoc. You are free to use or not this library, or find inspiration to define your own "diagrams lib".

pxDoc Diagrams metamodel

A very simple EMF metamodel has been defined to manipulate diagrams in pxDoc. It is composed of a root object Diagrams, which contains a list of Diagram.

pxDoc Diagrams runtime

The diagrams library provides a set of interfaces to query diagrams from an object.

The diagrams library provides a set of interfaces to query diagrams from an object:

  • IDiagramProvider: this is the entry point to query diagrams, by invoking its createQuery(modelObject) method, which returns an IDiagramQueryBuilder object.
  • IDiagramQueryBuilder: defines a set of simple queries (by name, by type, by non empty diagrams...), that can be stacked to the query. When the query is complete, the execute() method has to be called to run the query. For example, there are 2 unit queries in the following query: diagramProvider.createQuery(sourceObjectWithDiagrams).type("CDB").notEmpty().execute.
  • IDiagramQuery: a POJO for the diagram query
  • IDiagramQueryRunner: will run the IDiagramQuery

The Diagram library provides useful templates to include diagrams.

You can also find samples in the examples provided with the pxDoc enablers

DiagramServices.pxdoc Module

Diagram queries with queryDiagrams(Object)

Samples of queries:

							
											// diagrams owned by the 'model' object
											var List<Diagram> ownedDiagrams = queryDiagrams(model).execute;
								
											// all diagrams owned directly and indirectly by the 'model' object
											var allOwnedDiagrams = queryDiagrams(model).searchNested.execute;
								
											// diagrams owned by the 'model' object, with some content
											var ownedNonEmptyDiagrams = queryDiagrams(model).notEmpty.execute;
								
											// look for a diagram owned by 'model' and named 'A diagram name'
											var diagramsByName = queryDiagrams(model).name('A diagram name').execute;
								
											// look for a diagram owned by 'model' with name staring with 'ABC'
											var diagramsByNameStartingWith = queryDiagrams(model).nameStartsWith('ABC').execute;
								
											// diagrams by type
											var diagramsByType_CDB = queryDiagrams(model).type('CDB').execute;
											var diagramsByType_ES = queryDiagrams(model).type('ES').execute;
											var diagramsByType_CDI = queryDiagrams(model).type('CDI').execute;
								
											// diagrams with type 'CDB' and name starting with 'MyString'
											var cdbStartingWithMyString = queryDiagrams(model).type('CDB').nameStartsWith('MyString').execute;

Include diagrams with the includeDiagram(Diagram) template

You can use the includeDiagram template to include your diagrams:

							
											// Get a list of matching diagrams
											var List<Diagram> myDiagrams = queryDiagrams(model).execute;
								
											// insert the list of diagrams
											apply includeDiagram(myDiagrams)

Or you can also insert diagrams with your own template, as shown in the following example:

// To insert the diagram image by yourself:
											for (diagram : myDiagrams) {
												
								// use the pxdoc 'image' keyword with diagram image file path 
								// stored in the 'path' diagram attribute (was 'data' in pxDoc v1.1 and previous).
								image path:diagram.path  
								// add a title with a style
								#Figure keepWithNext align:center {
								diagram.name
								}
								// include diagram documentation if any
								if (!diagram.documentation.empty) {
									#BodyText {diagram.documentation}
								}
							}

And you can get the source diagram object to extract some information from it (get the semantic elements...):

							
							for (diagram : myDiagrams) {
								//Below, 'MyDiagramType' to be replaced according to your environment: 'DDiagram' for Sirius, 'Diagram' for Papyrus...
								var myDiagramObject=diagram.diagramObject as MyDiagramType 
							
								// Do whatever you need with the object...
							}

DiagramServices setup

REQUIRED - When using the DiagramServices module in your generator, you must inject an IDiagramProvider suited to your target platform.

diagramProvider = myToolDiagramProvider

Images Services / org.pragmaticmodeling.pxdoc.images.lib

The Images Services library is provided for demonstration purpose, and as a support for the set of generator examples shipped with pxDoc. You are free to use or not this library, or find inspiration to define your own "images lib".
Set of functions allowing to:
  • Split large images in to several ones (and calculate automatically if split is necessary)
  • Crop an image, to display only a part of it
  • Scale an image to keep its aspect ratio
  • Convert a Java Image object into an AWT object (pxDoc can manipulate image files or AWT objects)