Changeset - 2d294fb4b6d4
[Not reviewed]
0 1 0
Branko Majic (branko) - 9 months ago 2025-03-05 23:50:38
branko@majic.rs
[mapping_generator.py] Implemented command for applying parameters against the template.
1 file changed with 45 insertions and 0 deletions:
0 comments (0 inline, 0 general)
utils/mapping_generator.py
Show inline comments
 
@@ -14,12 +14,13 @@
 
# You should have received a copy of the GNU General Public License along with this program. If not, see
 
# <https://www.gnu.org/licenses/>.
 

	
 

	
 
import shutil
 
import math
 
import os
 

	
 
import click
 
import yaml
 

	
 
from defusedxml import ElementTree
 

	
 
@@ -85,12 +86,19 @@ def cli():
 
    """
 
    Generate input mapping cheatsheets for input devices using specially-crafted scalable vector graphics (SVG)
 
    templates.
 

	
 
    To prepare a template, create an SVG using Inkscape, and assign custom IDs to text elements that should be managed
 
    by the mapping generator.
 

	
 
    These elements can be populated by applying user-provided parameters against the template. Parameters are provided
 
    in the form of YAML file. The YAML file should have the 'mappables' key at the top level of the document, which then
 
    contains key-to-value mappings for custom text element IDs.
 

	
 
    The easiest way to generate the initial (blank) parameters file is by using the 'info' command alongside the output
 
    format option.
 
    """
 
    pass
 

	
 

	
 
@cli.command()
 
@click.argument('template', type=click.File('r'))
 
@@ -134,8 +142,45 @@ def info(template, search, output_format):
 
        display_mappables_as_text(matched_mappables)
 

	
 
    elif output_format == 'yaml':
 
        display_mappables_as_yaml(matched_mappables)
 

	
 

	
 
@cli.command()
 
@click.argument('template', type=click.File('r'))
 
@click.argument('parameters', type=click.File('r'))
 
@click.argument('output', type=click.Path(dir_okay=False, writable=True, allow_dash=True))
 
@click.option('--force-overwrite', '-f', is_flag=True, help='force overwriting output file')
 
def apply(template, parameters, output, force_overwrite):
 
    """
 
    Applies user-provided parameters against the template, and outputs the result.
 
    """
 

	
 
    template_tree = ElementTree.fromstring(template.read())
 
    namespaces = {
 
        'svg': 'http://www.w3.org/2000/svg',
 
    }
 

	
 
    # Inkscape default ID starts with string 'text' unless user assigns custom ID.
 
    mappable_elements = [
 
        e for e in template_tree.findall('.//svg:text', namespaces) if not e.get('id').startswith('text')
 
    ]
 

	
 
    parameters = yaml.safe_load(parameters.read())
 

	
 
    for element in mappable_elements:
 
        element_id = element.get('id')
 
        replacement = parameters['mappables'].get(element_id, '')
 
        element.find('svg:tspan', namespaces).text = replacement
 

	
 
    if os.path.exists(output) and not force_overwrite:
 
        raise click.FileError(output, 'file already exists')
 

	
 
    if os.path.isdir(output):
 
        raise click.FileError(output, 'output must be a file path')
 

	
 
    with click.open_file(output, 'wb') as output_file:
 
        output_file.write(ElementTree.tostring(template_tree))
 

	
 

	
 
if __name__ == '__main__':
 
    cli()
0 comments (0 inline, 0 general)