spakin / SimpInkScr

Simple Inkscape Scripting
https://inkscape.org/~pakin/%E2%98%85simple-inkscape-scripting
GNU General Public License v3.0
320 stars 31 forks source link

Feature pass remaining command line args to python code #69

Closed kantas-spike closed 1 year ago

kantas-spike commented 1 year ago

Purpose

This pull request proposes a change to allow for passing extra arguments to the Python code in the 'Simple Inkscape Scripting' command line usage. (See https://github.com/spakin/SimpInkScr/issues/4 for more information.)

Proposed Change

The proposed change is to add a new command line argument, rest_args, which would be exposed as a global variable in the Python code. This would allow users to pass additional arguments to the Python code, such as positional arguments or arguments beginning with "-".

pars.add_argument('rest_args', nargs="*", help='Rest Arguments for passing Python code')

# ...snip...

sis_globals['rest_args'] = self.options.rest_args

Usage example

# add positional args
% simple_inkscape_scripting.py --program "print('rest_args: ', rest_args)" --output output.svg input.svg data.json
rest_args: ['data.json']

# add positional arguments that begining with -
% simple_inkscape_scripting.py  --program "print('rest_args: ', rest_args)" --output output.svg input.svg -- --option1 --option2 data.json
rest_args: ['--option1', '--option2', 'data.json']

Potential issues

This change misidentifies INPUT_FILE as the first element of rest_args when the argument INPUT_FILE is omitted.

Workaround

As a remedy, when using the standard input, make it possible to specify - for the argument INPUT_FILE.

    def filename_arg(self, name):
        """Existing file to read or option used in script arguments"""
        if name == "-":
            return None  # filename is set to None to read stdin
        return inkex.utils.filename_arg(name)

    def reconfigure_input_file_argument(self, pars):
        target_action = None
        for action in pars._actions:
            if 'input_file' == action.dest:
                target_action = action
                break

        target_action.container._remove_action(target_action)
        pars.add_argument(
            "input_file",
            nargs="?",
            metavar="INPUT_FILE",
            type=self.filename_arg,
            help="Filename of the input file (default is stdin). Filename can be `-` for stdin",
            default=None,

Simple Inkscape Scripting is incredibly helpful, thank you for creating it!

spakin commented 1 year ago

Merged; thanks for the pull request.

I'm not sure I like the name rest_args so I might rename that.

spakin commented 1 year ago

I ended up going with user_args to indicate that these are arguments that are meaningful only to the user, not to Simple Inkscape Scripting itself. See c62fa9e22a72d66a3b306a6ff80e46b728911970.

kantas-spike commented 1 year ago

Thank you @spakin for reviewing and merging my pull request. I really appreciate the time and care you took in reviewing my code and providing feedback. I am glad that this change will make it easier for others to use 'Simple Inkscape Scripting' and improve their workflows. Thank you for creating and maintaining such a useful tool, it has helped me a lot.

spakin commented 1 year ago

P.S. I documented your modifications in the Simple Inkscape Scripting wiki under RunningCommand-line execution. Please let me know if anything I wrote is incorrect or misleading or if I missed documenting any important features.

kantas-spike commented 1 year ago

Thank you for creating the documentation. I have reviewed it and it is very helpful and informative. I have not found any issues with it. It is clear and easy to understand.

I believe that this documentation will increase the number of authors of tools that wrap simple_inkscape_scripting.py, as it makes it easier for others to understand and use the tool.