Skip to content

visualdynamics.io.report_template

report_template

Save a report on its own, as a template another project can use.

A report is a list of blocks with symbolic bindings, such as @basis:Frf or @other:ShapeSet, so a report written without its project is a template: the same figures and text, bound again to whatever project loads it. The file is JSON with one marker key and the fields the project file keeps for a report (title, marking, marking color, blocks, and the report features when any are enabled; see native.save_report), under its own suffix, .vdreport. A lab's house template therefore carries its choice of report features, and the laboratory's name, address and reproduction statement from the report's identification; never a report number, revision, status or issue record. A block whose binding does not resolve in the new project is an unbound card there, to be pointed at an object in the editor's pane, as an unbound block of a built-in template is.

Templates saved in templates_folder() are offered by Generate Report beside the built-in ones in every project.

Functions:

Name Description
save

Write the report as a template (JSON).

templates_folder

The folder saved templates are kept in.

saved_templates

(name, path) for every .vdreport file in templates_folder(),

Classes

Functions:

save

save(report: Report, path: str | PathLike, unit_system: Any = None, **_ignored: Any) -> None

Write the report as a template (JSON).

unit_system is accepted because every exporter takes it, and is not used: a template holds no values, only what to draw and how to bind it. So the test dates a channel table block keeps (report.calibration) are left out: the next test is judged against its own date, never the last one's.

Source code in src/visualdynamics/io/report_template.py
def save(report: Report, path: str | os.PathLike, unit_system: Any = None,
         **_ignored: Any) -> None:
    """Write the report as a template (JSON).

    `unit_system` is accepted because every exporter takes it, and is not
    used: a template holds no values, only what to draw and how to bind
    it. So the test dates a channel table block keeps
    (`report.calibration`) are left out: the next test is judged against
    its own date, never the last one's.
    """
    out = {MARKER: 1, 'title': report.title, 'marking': report.marking,
           'marking_color': report.marking_color,
           'blocks': [{key: value for key, value in block.items()
                       if key not in _TEST_ONLY}
                      for block in report.blocks]}
    if report.features:
        # only when there are any: a template with none is the file it
        # always was, and opens in a version that has no features
        out['features'] = list(report.features)
    from ..report.identity import TEMPLATE_FIELDS

    # the laboratory's own fields only: a number, a revision, a status
    # or an issue record belongs to one report and never to the next
    laboratory = {key: report.identity[key] for key in TEMPLATE_FIELDS
                  if key in report.identity}
    if laboratory:
        out['identity'] = laboratory
    with open(path, 'w', encoding='utf-8') as handle:
        json.dump(out, handle, indent=1)
        handle.write('\n')

templates_folder

templates_folder() -> Path

The folder saved templates are kept in.

It is Visual Dynamics/Report Templates in the user's application data folder for the platform (~/Library/Application Support on macOS, APPDATA on Windows, XDG_DATA_HOME or ~/.local/share elsewhere), or the folder VISUALDYNAMICS_TEMPLATES names when that environment variable is set. The folder is not created here; whatever writes to it creates it.

Source code in src/visualdynamics/io/report_template.py
def templates_folder() -> Path:
    """The folder saved templates are kept in.

    It is `Visual Dynamics/Report Templates` in the user's application
    data folder for the platform (`~/Library/Application Support` on
    macOS, `APPDATA` on Windows, `XDG_DATA_HOME` or `~/.local/share`
    elsewhere), or the folder `VISUALDYNAMICS_TEMPLATES` names when that
    environment variable is set. The folder is not created here; whatever
    writes to it creates it.
    """
    override = os.environ.get('VISUALDYNAMICS_TEMPLATES')
    if override:
        return Path(override)
    if sys.platform == 'darwin':
        base = Path.home() / 'Library' / 'Application Support'
    elif sys.platform.startswith('win'):
        base = Path(os.environ.get('APPDATA', Path.home() / 'AppData' / 'Roaming'))
    else:
        base = Path(os.environ.get('XDG_DATA_HOME', Path.home() / '.local' / 'share'))
    return base / 'Visual Dynamics' / 'Report Templates'

saved_templates

saved_templates() -> list[tuple[str, Path]]

(name, path) for every .vdreport file in templates_folder(), sorted by name; empty when the folder does not exist.

Source code in src/visualdynamics/io/report_template.py
def saved_templates() -> list[tuple[str, Path]]:
    """(name, path) for every `.vdreport` file in `templates_folder()`,
    sorted by name; empty when the folder does not exist."""
    folder = templates_folder()
    if not folder.is_dir():
        return []
    return sorted((path.name[:-len(SUFFIX)], path)
                  for path in folder.iterdir()
                  if path.is_file() and path.name.endswith(SUFFIX))