added back some more extensions

This commit is contained in:
2022-10-10 03:43:34 +02:00
parent bc2301079d
commit 3277fba958
42 changed files with 6624 additions and 0 deletions

View File

@ -0,0 +1,22 @@
[
{
"name": "NextGenerator",
"id": "fablabchemnitz.de.nextgenerator",
"path": "nextgenerator",
"dependent_extensions": null,
"original_name": "NextGenerator",
"original_id": "de.vektorrascheln.extension.next_gen",
"license": "GNU GPL v3",
"license_url": "https://gitlab.com/Moini/nextgenerator/-/blob/master/LICENSE",
"comment": "",
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.2/src/branch/master/extensions/fablabchemnitz/nextgenerator",
"fork_url": "https://gitlab.com/Moini/nextgenerator",
"documentation_url": "https://stadtfabrikanten.org/display/IFM/NextGenerator",
"inkscape_gallery_url": null,
"main_authors": [
"Aurélio A. Heckert",
"gitlab.com/Moini",
"github.com/eridur-de"
]
}
]

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>NextGenerator</name>
<id>fablabchemnitz.de.nextgenerator</id>
<param name="tab" type="notebook">
<page name="config" gui-text="Options">
<label appearance="header">Input options</label>
<param gui-text="CSV file:" gui-description="A file with comma-separated values, one line per exported file. The first line contains the column names. Put quotation marks around your variables if they contain a comma." name="csv_file" type="path" mode="file" filetypes="csv">/path/to/file.csv</param>
<spacer />
<label>Non-text values to replace (see Help tab):</label>
<param name="extra-vars" type="string" gui-text="" />
<param gui-text="Number of sets in the template:" gui-description="How many datasets fit into one template file - e.g. if you have an A4 page with 8 visitor badges for 8 different persons which use the same variable names, choose '8'. See 'Help' tab for more info." name="num_sets" type="int" min="1" max="10000">1</param>
<spacer />
<separator />
<spacer />
<label appearance="header">Output options</label>
<param name="format" type="optiongroup" appearance="combo" gui-text="Export file format:">
<option value="png">PNG</option>
<option value="pdf">PDF</option>
<option value="svg">SVG</option>
<option value="ps">PS</option>
<option value="eps">EPS</option>
</param>
<param gui-text="DPI (for PNG and filters):" gui-description="The resolution for your exported raster images" name="dpi" type="int" min="1" max="10000">300</param>
<param gui-text="File name pattern:" gui-description="The pattern for the names of the generated files. If 'Number of sets' is 1, it should contain at least one unique column variable (in the form of '%VAR_my_variable_name%'), or a unique combination of column variables, so new files won't overwrite those that have already been generated. Do not include the file extension, it will be added automatically. If 'Number of sets' is greater than 1, use any name you like. The exported files will be numbered automatically." name="file_pattern" type="string">%VAR_my_variable_name%</param>
<param gui-text="Save in:" gui-description="The name of the folder where the generated images should be saved" name="output_folder" type="path" mode="folders">/tmp</param>
</page>
<page name="help" gui-text="Help">
<param name="helptabs" type="notebook">
<page name="help1" gui-text="Replacing text">
<label xml:space="preserve">In your SVG file, create any texts that you want to replace by clicking (not clicking and dragging) on the canvas. If you want to limit the width of the text, use the diamond-shaped handle at the end of the first line to indicate a maximum width. The text will auto-flow into the next line if it is longer. Make sure there is enough space for your texts.
As (or into) the text, type '%VAR_my_variable_name%' (without the quotes) as a placeholder, where 'my_variable_name' is the title of the corresponding column in your CSV data file.</label>
</page>
<page name="help2" gui-text="Replacing attributes">
<label xml:space="preserve">If you want to replace attribute values in your SVG file (e.g. a color, or the name of a linked image file), you can assign them to columns in the field labeled "Non-text values to replace" in JSON format like this (no linebreaks allowed):
{"background_color":"#ff0000", "photo":"image.png"}
All objects that use the red color (#ff0000) will then be exported using the colors in the column 'background_color'. The linked image 'image.png' will be replaced by the image files listed in the column 'photo' (make sure to replace the complete image path).</label>
</page>
<page name="help3" gui-text="Multiple sets">
<label xml:space="preserve">If you intend to have multiple sets in a single template for example, multiple conference badges on a larger page that will later be cut make sure to group each set together.
Also make sure to use a variable only exactly once per set. If you do not adhere to this, your variables will get out of sync and your generated files will contain incorrect data.</label>
</page>
</param>
</page>
<page name="about" gui-text="About">
<label appearance="header">NextGenerator</label>
<label indent="1">Version 1.1.1</label>
<spacer />
<label xml:space="preserve">An Inkscape extension to automatically replace values (text, attribute values) in an SVG file and to then export the result to various file formats. This is useful e.g. for generating images for name badges and other similar items.
This extension is a Python rewrite of the Generator bash script extension by Aurélio A. Heckert. It is compatible with Inkscape starting from version 1.0 and requires Python 3.</label>
</page>
</param>
<effect needs-live-preview="false">
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Import/Export/Transfer" />
</submenu>
</effects-menu>
<menu-tip>Automatically replace values and export the result.</menu-tip>
</effect>
<script>
<command location="inx" interpreter="python">nextgenerator.py</command>
</script>
</inkscape-extension>

View File

@ -0,0 +1,190 @@
#!/usr/bin/env python3
# coding=utf-8
#
# NextGenerator - an Inkscape extension to export images with automatically replaced values
# Copyright (C) 2008 Aurélio A. Heckert (original Generator extension in Bash)
# 2019-2021 Maren Hachmann (Python rewrite, update for Inkscape 1.0)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
"""
An Inkscape extension to automatically replace values (text, attribute values)
in an SVG file and to then export the result to various file formats.
This is useful e.g. for generating images for name badges and other similar items.
"""
from __future__ import unicode_literals
import os
import csv
import json
import time #for debugging purposes
import inkex
import html
from inkex.command import inkscape
__version__ = '1.2'
class NextGenerator(inkex.base.TempDirMixin, inkex.base.InkscapeExtension):
"""Generate image files by replacing variables in the current file"""
def add_arguments(self, pars):
pars.add_argument("-c", "--csv_file", type=str, dest="csv_file", help="path to a CSV file")
pars.add_argument("-e", "--extra-vars", help="additional variables to replace and the corresponding columns, in JSON format")
pars.add_argument("-n", "--num_sets", type=int, default="1", help="number of sets in the template")
pars.add_argument("-f", "--format", help="file format to export to: png, pdf, svg, ps, eps")
pars.add_argument("-d", "--dpi", type=int, default="300", help="dpi value for exported raster images")
pars.add_argument("-o", "--output_folder", help="path to output folder")
pars.add_argument("-p", "--file_pattern", help="pattern for the output file")
pars.add_argument("-t", "--tab", default="", help="not needed at all")
pars.add_argument("-l", "--helptabs", default="", help="not needed at all")
pars.add_argument("-i", "--id", default="", help="not needed at all")
def effect(self):
# load the attributes that should be replaced in addition to textual values
if self.options.extra_vars == None:
self.options.extra_vars = '{}'
extra_vars = json.loads(self.options.extra_vars)
# load the CSV file
# spaces around commas will be stripped
csv.register_dialect('generator', 'excel', skipinitialspace=True)
with open(self.options.csv_file, newline='', encoding='utf-8-sig') as csvfile:
data = csv.DictReader(csvfile, dialect='generator')
if self.options.num_sets == 1:
for row in data:
export_base_name = self.options.file_pattern
self.new_doc = self.document
for i, (key, value) in enumerate(row.items()):
search_string = "%VAR_" + key + "%"
# replace any occurrances of %VAR_my_variable_name% in the SVG file source code
self.new_doc = self.new_doc.replace(search_string, html.escape(value))
# build the file name, still without file extension
export_base_name = export_base_name.replace(search_string, value)
for key, svg_cont in extra_vars.items():
if key in row.keys():
# replace any attributes and other SVG content by the values from the CSV file
self.new_doc = self.new_doc.replace(svg_cont, row[key])
else:
inkex.errormsg("The replacements in the generated images may be incomplete. Please check your entry '{key}' in the field for the non-text values.").format(key=key)
if self.export(export_base_name) != True:
return
elif self.options.num_sets > 1:
# we need a list to access specific rows and to be able to count it
data = list(data)
# check if user's indication of num_sets is compatible with file
for key in data[0].keys():
num_occurr = self.document.count("%VAR_" + key + "%")
# We ignore keys that don't appear in the document
if num_occurr != 0 and num_occurr != self.options.num_sets:
return inkex.errormsg("There are {0} occurrances of the variable '{1}' in the document, but the number of sets you indicated is {2}. Please make sure that each set contains all variables and that there are just as many sets in your document as you indicate.".format(num_occurr, key, self.options.num_sets))
# abusing negative floor division which rounds to the next lowest number to figure out how many pages we will get
num_exports = -((-len(data))//self.options.num_sets)
# now we hope that the document is properly prepared and the stacking order cycles through datasets - if not, the result will be nonsensical, but we can't know.
for export_file_num in range(num_exports):
# we only number the export files if there are sets
export_base_name = "".join([x if x.isalnum() else "_" for x in self.options.file_pattern]) + '_{}'.format(str(export_file_num))
self.new_doc = self.document
for set_num in range(self.options.num_sets):
# number of the data row in the CSV file
n = export_file_num * self.options.num_sets + set_num
if n < len(data):
dataset = data[n]
else:
# no more values available, stop trying to replace them
break
for i, (key, value) in enumerate(dataset.items()):
search_string = "%VAR_" + key + "%"
# replace the next occurrance of %VAR_my_variable_name% in the SVG file source code
self.new_doc = self.new_doc.replace(search_string, html.escape(value), 1)
for key, svg_cont in extra_vars.items():
if key in dataset.keys():
# replace any attributes and other SVG content by the values from the CSV file
self.new_doc = self.new_doc.replace(svg_cont, dataset[key], 1)
else:
inkex.errormsg(_("The replacements in the generated images may be incomplete. Please check your entry '{key}' in the field for the non-text values.").format(key=key))
self.export(export_base_name)
def export(self, export_base_name):
export_file_name = '{0}.{1}'.format(export_base_name, self.options.format)
if os.path.exists(self.options.output_folder):
export_file_path = os.path.join(self.options.output_folder, export_file_name)
else:
inkex.errormsg("The selected output folder does not exist.")
return False
if self.options.format == 'svg':
# would use this, but it cannot overwrite, nor handle strings for writing...:
# write_svg(self.new_doc, export_file_path)
with open(export_file_path, 'w') as f:
f.write(self.new_doc)
else:
actions = {
'png' : 'export-dpi:{dpi};export-filename:{file_name};export-do;FileClose'.\
format(dpi=self.options.dpi, file_name=export_file_path),
'pdf' : 'export-dpi:{dpi};export-pdf-version:1.5;export-text-to-path;export-filename:{file_name};export-do;FileClose'.\
format(dpi=self.options.dpi, file_name=export_file_path),
'ps' : 'export-dpi:{dpi};export-text-to-path;export-filename:{file_name};export-do;FileClose'.\
format(dpi=self.options.dpi, file_name=export_file_path),
'eps' : 'export-dpi:{dpi};export-text-to-path;export-filename:{file_name};export-do;FileClose'.\
format(dpi=self.options.dpi, file_name=export_file_path),
}
# create a temporary svg file from our string
temp_svg_name = '{0}.{1}'.format(export_base_name, 'svg')
temp_svg_path = os.path.join(self.tempdir, temp_svg_name)
#inkex.utils.debug("temp_svg_path=" + temp_svg_path)
with open(temp_svg_path, 'w') as f:
f.write(self.new_doc)
#inkex.utils.debug("self.new_doc=" + self.new_doc)
# let Inkscape do the exporting
# self.debug(actions[self.options.format])
cli_output = inkscape(temp_svg_path, actions=actions[self.options.format])
if len(cli_output) > 0:
self.debug(_("Inkscape returned the following output when trying to run the file export; the file export may still have worked:"))
self.debug(cli_output)
return False
return True
def load(self, stream):
return str(stream.read(), 'utf-8')
def save(self, stream):
# must be implemented, but isn't needed.
pass
if __name__ == '__main__':
NextGenerator().run()