Inkscape.org
Creating New Extensions Simple Stroke to Path extension example
  1. #1
    inklinea inklinea @inklinea⛰️

    Simple Stroke to Path extension example
    -----------------------------------------------------
    .inx and .py
    -----------------------------------------------------

    <?xml version="1.0" encoding="UTF-8"?>
    <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
        <name>Stroke To Path</name>
        <id>inklinea.stroke_to_path</id>

        <!--  Parameters Here -->

        <effect>
            <object-type>all</object-type>
            <effects-menu>
        <!--            <submenu name="Submenu Name"/>-->
            </effects-menu>
        </effect>
        <script>
            <command location="inx" interpreter="python">stroke_to_path.py</command>
        </script>
    </inkscape-extension>

    ----------------------------------------

    import inkex

    import tempfile, os, shutil
    from uuid import uuid4


    def process_svg(svg, action_string):

        temp_folder = tempfile.mkdtemp()

        # Create a random filename for svg
        svg_temp_filepath = os.path.join(temp_folder, f'original_{str(uuid4())}.svg')

        with open(svg_temp_filepath, 'w') as output_file:
            svg_string = svg.tostring().decode('utf-8')
            output_file.write(svg_string)

        processed_svg_temp_filepath = os.path.join(temp_folder, f'processed_{str(uuid4())}.svg')

        my_actions = '--actions='

        export_action_string = my_actions + f'export-filename:{processed_svg_temp_filepath};{action_string}export-do;'

        # Run the command line
        cmd_selection_list = inkex.command.inkscape(svg_temp_filepath, export_action_string)

        # Replace the current document with the processed document
        with open(processed_svg_temp_filepath, 'rb') as processed_svg:
            loaded_svg = inkex.elements.load_svg(processed_svg).getroot()

        shutil.rmtree(temp_folder)
        return loaded_svg

    def element_list_stroke_to_path(svg, element_list):

        action_string = ''
        for element in element_list:
            action_string = action_string + f'select-by-id:{element.get_id()};object-stroke-to-path;select-clear;'
        processed_svg = process_svg(svg, action_string)

        for element in element_list:
            element.replace_with(processed_svg.getElementById(element.get_id()))

    class StrokeToPath(inkex.EffectExtension):

        def add_arguments(self, pars):
            pass
        
        def effect(self):
            pass
            
            selection_list = self.svg.selected
            if len(selection_list) < 1:
                inkex.errormsg('Please select at least one object')
                return
                
            for selection in selection_list:
                inkex.errormsg(f'{selection} {selection.get_id()}')

            element_list_stroke_to_path(self.svg, selection_list)
            
    if __name__ == '__main__':
        StrokeToPath().run()

     

  2. #2
    inklinea inklinea @inklinea⛰️

    I should note that this script processes each element id separately in the action list.

    For stroke to path, that is not really necessary. 

    A better way would be to deepcopy(svg) and tag each path with a data-tag, then use a single css selector on the command call.

    The data-tag can be removed with a loop later.

    Windows has a 8191 character limit for the command line. 

    I think the Inkscape developers have overcome this in the inkex command call code, but I usually err on the side of caution. 

Inkscape Inkscape.org Inkscape Forum Creating New Extensions Simple Stroke to Path extension example