AppyPrinciplesGetting started
appy.pod The Renderer reference

Here is the complete description of the Renderer constructor.

    def __init__(self, template, context, result, pythonWithUnoPath=None,
      ooServer='localhost', ooPort=2002, stream='auto', stylesMapping={},
      stylesOutlineDeltas=None, html=False, forceOoCall=False,
      finalizeFunction=None, overwriteExisting=False, raiseOnError=False,
      findImage=None, rotateImages=False, stylesTemplate=None,
      optimalColumnWidths=False, distributeColumns=False, script=None,
      evaluator=None, managePageStyles=None, resolveFields=False,
      expressionsHolders=defaultExpressionsHolders, metadata=True,
      pdfOptions='ExportNotes=True', csvOptions=None, deleteTempFolder=True,
      protection=False, pageStart=1, tabbedCR=False, fonts=None, loPool=None):
        '''Base on a document template (whose path is in template), which is
           an ODT or ODS file containing special expressions and statements
           written in Python, this renderer generates an ODT file (whose path is
           in result), that is a copy of the template whose expressions and
           statements have been replaced with the objects defined in the
           context.'''

        # If result does not end with .odt or .ods, the Renderer will call
        # LibreOffice (LO) to perform a conversion. If forceOoCall is True,
        # even if result ends with .odt, LO will be called, not for performing
        # a conversion, but for updating some elements like indexes (table of
        # contents, etc) and sections containing links to external files (which
        # is the case, for example, if you use the default function "document").

        # If the Python interpreter which runs the current script is not
        # UNO-enabled, this script will run, in another process, a UNO-enabled
        # Python interpreter (whose path is pythonWithUnoPath) which will call
        # LO.

        # When pod needs to communicate with LO, it will assume LO runs on
        # server named ooServer, listening on port ooPort. If you run
        # several LibreOffice servers, ooPort may specify a list of ports. In
        # that case, pod will load-balance requests to the appropriate server.
        # Note that, when using such a "pool" of LO servers, they all must
        # reside on the same machine (ooServer); pod assumes they are all
        # up-and-running.

        # stream dictates the communication between the renderer and LO.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # stream can hold the following values.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # "auto"     | if ooServer is "localhost", exchanging the ODT result
        # (default)  | produced by the renderer (=the input) and the converted
        #            | file produced by LO (=the output) will be made via files
        #            | on disk. Else, the renderer will consider that LO runs on
        #            | another machine and the exchange will be made via streams
        #            | over the network.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # True       | If you want to force communication of the input and
        #            | output files as streams, use stream=True.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # False      | If you want to force communication of the input and
        #            | output files via the disk, use stream=False.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # "in"       | The input is streamed and the output is written on disk.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # "out"      | The input is read from disk and the output is streamed.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        # If you plan to make "XHTML to OpenDocument" conversions, via the POD
        # function "xhtml", you may specify (a) a "styles mapping" in
        # stylesMapping. You can also (b) alter the outline level of every
        # style found in your POD template, via dict stylesOutlineDeltas,
        # whose keys are style names and values are deltas to apply to their
        # outline levels. Finally, (c), if the input(s) to function "xhtml" is
        # valid HTML but not valid XHTML, specify html being True.

        # If you specify a function in finalizeFunction (or a list/tuple of
        # functions), it will be called by the renderer before re-zipping the
        # ODT/S result. This way, you can still perform some actions on the
        # content of the ODT/S file before it is zipped and potentially
        # converted. Every such function must accept 2 args:
        #  *  the absolute path to the temporary folder, containing the
        #     un-zipped content of the ODT/S result;
        #  *  the Renderer instance.

        # If you set overwriteExisting to True, the renderer will overwrite
        # the result file. Else, an exception will be thrown if the result file
        # already exists.

        # If raiseOnError is False (the default value), any error encountered
        # during the generation of the result file will be dumped into it, as a
        # Python traceback within a note. Else, the error will be raised. If the
        # template is an ODS template, exceptions cannot be dumped as inner
        # notes: raiseOnError is forced to True, whatever value you may have
        # passed to the Renderer.

        # When, in the process of converting a chunk of XHTML code to ODF, a
        # "img" tag is encountered, POD performs a HTTP GET to retrieve it. If
        # the image is stored on the same server running POD, this can be
        # problematic in two ways:
        # 1) regarding performance, it would be better to retrieve the image
        #    from disk;
        # 2) via HTTP, POD may not be allowed to retrieve the image.
        # In order to overcome these problems, place a function in "findImage".
        # While converting chunks of XHTML code, everytime an "img" tag is
        # encountered, this function will be called, with the image URL as
        # unique arg. If the function returns the absolute path to the image, it
        # will be used instead of performing a HTTP GET request. If the function
        # returns None (ie: it has detected that is is a "truly external" URL),
        # the HTTP GET will nevertheless be performed.

        # If rotateImages is True, for every image to inject in the result,
        # Appy will call ImageMagick to read EXIF data. If an orientation is
        # defined, ImageMagick will be called to effectively apply the
        # corresponding rotation to the image. Because reading EXIF data on
        # every image to import may take some processing, rotateImages is
        # False by default.

        # stylesTemplate can be the path to a LibreOffice file (ie, a .ott
        # file) whose styles will be imported within the result.

        # optimalColumnWidths corresponds to the homonym option to
        # converter.py, excepted that values "True" or "False" must be boolean
        # values. Note that the POD function "xhtml" requires this parameter to
        # be "OCW_.*" to be fully operational. When optimalColumnWidths is not
        # False, forceOoCall is forced to True.

        # distributeColumns corresponds to the homonym option to converter.py,
        # excepted that values "True" or "False" must be boolean values. Note
        # that the POD function "xhtml" requires this parameter to be "DC_.*" to
        # be fully operational. When distributeColumns is not False,
        # forceOoCall is forced to True.

        # script is the absolute path to a Python script containing functions
        # that the converter will call in order to customize the process of
        # manipulating the document via the LibreOffice UNO interface. For more
        # information, see appy/pod/converter.py, option "-s". Note that when
        # such script is specified, forceOoCall is forced to True.

        # By default, POD expressions and statement parts are evaluated using
        # the Python built-in "eval" function. If you consider this to be a
        # security problem (are POD templates written by external people ? by
        # advanced users ?), you can use pod in conjunction with the third-party
        # module named RestrictedPython:
        #
        #              https://restrictedpython.readthedocs.io
        #
        # In order to do so, pass, in attribute evaluator, an instance of
        # class appy.pod.restricted.Evaluator. For more information and options,
        # consult appy.pod.restricted.py.

        # If this document is a sub-document to be included in a master one, it
        # has sense to set a specific value for parameter managePageStyles:
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        #  "rename" | will rename all page styles with unique names. This way,
        #           | when imported into a master document, no name clash will
        #           | occur and elements tied to page styles (like headers and
        #           | footers) will be correctly imported for all included
        #           | sub-documents. The "do... pod" statement automatically
        #           | sets this parameter to "rename";
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        #   <int>   | will rename page styles similarly to "rename" and will
        #           | also restart, in the sub-document, page numbering at this
        #           | integer value. It will only work if page styles are
        #           | explicitly applied to pages in the sub-pod template. In
        #           | order to achieve this with LibreOffice, open your
        #           | template, set the cursor somewhere in the first page,
        #           | open the pane with page styles, and double-clic on the
        #           | "default style". To check if it has worked, click inside
        #           | the first paragraph in the page, open its properties and
        #           | check that a page break has been defined on it.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        # If you want to replace (some) fields with their "hard-coded" values,
        # use resolveFields. It can be useful, for instance, if the POD result
        # must be included in a master document (via statement "do ... from
        # pod"), but the total number of pages must be kept as is. If
        # resolveFields is True, all fields will be resolved, excepted special
        # ones like PageNumber. Indeed, its value is different from one page to
        # another, so resolving it to a single, hard-coded value has no sense.
        # You can also specify "PageCount" as value for resolveField. In this
        # case, only the field(s) containing the total number of pages will be
        # resolved. Use it if it is the only field you need to resolve, it will
        # be more performant. Note that when resolveFields is set,
        # forceOoCall is forced to True.

        # POD expressions may be defined at various places within a document
        # template. Possible places are listed in static variable
        # "allExpressionsHolders" hereabove. Default places are listed in static
        # variable "defaultExpressionsHolders" hereabove.

        # If metadata is True, the result will get a metadata property "title"
        # (in meta.xml) being the result file name, without its extension. If
        # metadata is a string, it will be used as title.

        # If the result must be produced in PDF, options being specific to this
        # format can be passed in pdfOptions, as a comma-separated string of
        # key=value pairs, as in

        #            ExportNotes=False,PageRange=1-20,Watermark=Sample

        # More info in appy/pod/converter.py.

        # If the result must be produced in CSV, options being specific to this
        # format can be passed in csvOptions, as an instance of class
        # CsvOptions, available on class Renderer as Renderer.CsvOptions. If
        # csvOptions is None, defauls CSV options will be used from
        # Renderer.CsvOptions.default.

        # If this renderer is called by another one (its "parent"), it may
        # receive an additional parameter, deleteTempFolder. If False, the
        # temp folder may be reused by other children of the parent renderer, so
        # we do not delete it (the parent will do it at the end of the whole
        # process).

        # if "protection" is True, you can define variables "cellProtected"
        # and/or "sectionProtected" to determine, respectively, if a cell or a
        # section must be write-protected. It is not enabled by default because
        # it has a little impact on performance and on the size of the result
        # (especially large ods results).

        # If pageStart is different from 1, the produced document will start
        # page numbering at this number. In that case, forceOoCall will be
        # forced to True.

        # By default, the *c*arriage *r*eturn (CR) char is converted to ODF tag
        # <text:line-break/>. This may cause problems with justified text. These
        # problems are overcomed by prefixing the tag with <text:tab/> for
        # producing <text:tab/><text:line-break/>. But beware: "tabbing" the CR
        # that way may cause problems when exporting the POD result to Microsoft
        # Word. This is why attribute "tabbedCR" exists.

        # Attribute "fonts" may hold the name of a font that must exist on the
        # machine running this renderer. If such a name is passed, all base
        # styles defined in the POD template will be redefined with this font.
        # On (most? all?) Linux machines, list the available fonts via a command
        # like:
        #                      fc-list :lang=en family

        # Please leave loPool attribute to None. A LO pool is a data structure
        # being internal to pod, allowing to communicate with LO. This is only
        # used by pod itself, when a main Renderer instance needs to create a
        # sub-Renderer instance, ie, for importing a sub-pod into a main pod.