Inkscape.org
Creating New Extensions Extension ala commnad Duplicate
  1. #1
    jeruA jeruA @jeruA

    Hello,

    could someone please be so kind as to help me with the script?
    The script will do the same as the Duplicate command, with the difference that only 2 objects will be selected: a square/rectangle and a text (number).
    The script would make a duplicate of the object with all properties preserved, but would increase the value of that number by one.
    I tried to write with the help of ChatGPT, but it didn't work.
    Thank you J.

  2. #2
    inklinea inklinea @inklinea⛰️
    *

    Something like this ? 

    ( I have attached a zip file you can extract in your extensions folder )

    import inkex
    
    def increment_text(self, text_element):
    
        # SVG text elements can be simple <text> Hello </text>
        # Or contain child <tspan> Hello Again </span> elements
        # Or can be a mixture of both.
        # Lets get all child tspans as a list, and add the parent
        # text element to that list.
    
        element_list = text_element.xpath('*')
        element_list.insert(0, text_element)
    
        # Now lets loop through that list and test if the
        # text can be converted to a whole number (Integer)
    
        for element in element_list:
            if element.text:
                try:
                    # If test is positive, convert to int and increment by 1
                    new_int = int(element.text) + 1
                    # convert the new value back to string and update the text
                    element.text = str(new_int)
                except:
                    continue
    
    class DuplicateIncrement(inkex.EffectExtension):
    
        def add_arguments(self, pars):
            pass
        
        def effect(self):
            
            # If nothing is selected exit.
            selection_list = self.svg.selected
            if len(selection_list) < 1:
                inkex.errormsg('Please select at least one object')
                return
    
            # Filter the selection to only include text elements and rectangle elements
            filtered_selection_list = selection_list.filter(inkex.TextElement, inkex.Rectangle)
    
            for selection in filtered_selection_list:
                # inkex.errormsg(f'{selection} id: {selection.get_id()}')
    
                selection_dupe = selection.duplicate()
                if selection_dupe.TAG == 'text':
                    increment_text(self, selection_dupe)
            
    if __name__ == '__main__':
        DuplicateIncrement().run()

     

  3. #3
    jeruA jeruA @jeruA

    Thank you inklinea for your help, it looks nice.

    May I be bold and ask for 2 modifications:
    1/ select all created duplicates (so that I can manipulate them immediately)
    2/ it would be a problem to add a number if there was not the number itself, but a composite text (always with a single number), e.g. "a - 1" -> "a - 2", ... or "1." -> "2." or "1. day" -> "2. day"

     

  4. #4
    jeruA jeruA @jeruA

    ... sorry, I still want to ask, will it be possible to create a keyboard shortcut for the script?

  5. #5
    inklinea inklinea @inklinea⛰️
    *
    .
  6. #6
    inklinea inklinea @inklinea⛰️

    In order to select all duplicates you would have to mark them in some way that can be found later. 

    There are a few ways this can be done. 

    Probably the easiest and most transparent is to add an svg data-* attribute. This is transparent to other programs unless they are looking for it.

    So my_element.set('data-duplicate', 'true') then in the Edit>Find/Replace panel, you can tick search properties and then attribute name data-duplicate and it will find and select.

    If you want to add composite text labels, that is more of a python code problem. All you are really doing in Inkscape is retrieving the text then setting it again after python manipulation.

    If you want to mix styles though, like colours / italtics etc - that is very different as it will split the numbers over multiple tspans (svg uses tspans to break up formatting)

    If you want to add a shortcut key. All extensions appear in the Inkscape action list on the command line and also in the keyboard shortcut settings under Edit>Preferences>Interface>Keyboard.

    You can search for them there. I have attached a screenshot. 

     

     

    Screenshot From 2024 02 17 02 20 02
  7. #7
    jeruA jeruA @jeruA

    I was not clear about point 1/
    ... the Duplicate command duplicates the selected objects (e.g. rectangle1 and text1) and the newly created rectangle2 and text2 are selected after executing the command and I can manipulate them immediately.

    I would like the same after executing the script. I don't want to manipulate all the duplicated objects, but only the last pair just created.

    Regarding point 2/... if I thought a little more, it would have occurred to me that my request could be solved with Find/Replace ;-)

    Thank you.

  8. #8
    inklinea inklinea @inklinea⛰️

    Selection passback from an extension is not supported by the extension system itself.

    There are ways to do it, however it is difficult. I wrote a (dbus) extension to do it for Inkscape 1.2, however it is broken in 1.3 :(