Criação de Extensões para o Inkscape

18 Dec 2011 . category: article . Comments
#svg #inkscape #python #howto #linux

Estrutura da Extensão

Para a criação de uma extensão do Inkscape pelo menos dois arquivos são necessários, um arquivo do tipo INX, que basicamente é um xml contendo algumas descrições, como por exemplo, nome da extensão, descrição dos parâmetros que o aplicação pode receber, localização no menu do Inkscape entre outros. Abaixo encontra-se um exemplo deste arquivo.

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
  <_name>Cartão de Natal</_name>
  <id>com.diegorubin.extensao.natal</id>
  <dependency type="executable" location="extensions">natal.py</dependency>
  <param name="de" type="string" _gui-text="De">Fulano</param>
  <param name="para" type="string" _gui-text="Para">Ciclano</param>
  <param name="mensagem" type="string" _gui-text="Mensagem">esses são os votos de</param>
  <effect>
    <object-type>all</object-type>
      <effects-menu>
        <submenu _name="Cartões"/>
      </effects-menu>
  </effect>
  <script>
    <command reldir="extensions" interpreter="python">natal.py</command>
  </script>
</inkscape-extension>

O segundo arquivo é onde implementaremos a ação da extensão. Basicamente, o que devemos fazer na implementação é manipular os elementos do documento SVG, que como explicado anteriormente, não passa de um XML.

No caso da implementação em Python, devemos criar uma classe que tenha um método publico chamado effect. Após a implementação da classe devemos instanciá-la e executar o método affect() da instancia.

Há algumas superclasses que podem ser utilizadas na implementação da extensão. O exemplo abaixo utiliza a class inkex.Effect e sua implementação encontra-se no diretório de extensões do Inkscape.

# -*- coding: utf-8 -*-

import os
import sys

# Esse é o diretório padrão de extensions
# do inkscape no linux.
# Se estiver em outro sistema, como mac
# ou windows, eese diretorio deve ser
# trocado.
sys.path.append('/usr/share/inkscape/extensions')
import inkex
from simplestyle import *


class C(inkex.Effect):
    def __init__(self):

        inkex.Effect.__init__(self)

        self.OptionParser.add_option("-d", "--de", action="store", 
                type="string", dest="de", 
                default="Fulano", help="Remetente da Mensagem")

        self.OptionParser.add_option("-p", "--para", action="store", 
                type="string", dest="para", 
                default="Destinatário", help="Destinatário da Mensagem")

        self.OptionParser.add_option("-m", "--mensagem", action="store", 
                type="string", dest="mensagem", 
                default="São os votos de", help="Mensagem personalizada")

    def effect(self):

        # Carregar elemento raiz do svg
        self.svg = self.document.getroot()

        # Criação de uma novo grupo que servirá de camada	
        self.layer = inkex.etree.SubElement(self.svg, 'g')
        self.layer.set(inkex.addNS('label', 'inkscape'), 'Mensagem')

        # Esse é o atributo que define o grupo como uma camada
        self.layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        self.create_message()


    def create_message(self):
        text_element = inkex.etree.Element(inkex.addNS('text', 'svg'))  
        
        # Cria um id unico para ser utilizado no elemento text
        textId = self.uniqueId('text')
        text_element.set('id', textId)

        # O texto fica em um element tspan, que fica dentro do element text
        tspan = inkex.etree.SubElement(text_element, 'tspan')
        tspanId = self.uniqueId('tspan')

        tspan.text = unicode(self.options.para) + ","
        # Indica que o span será uma nova linha
        tspan.set(inkex.addNS('role', 'sodipodi'), 'line')

        tspan = inkex.etree.SubElement(text_element, 'tspan')
        tspanId = self.uniqueId('tspan')

        tspan.text = unicode(self.options.mensagem, 'utf-8')
        tspan.set(inkex.addNS('role', 'sodipodi'), 'line')

        tspan = inkex.etree.SubElement(text_element, 'tspan')
        tspanId = self.uniqueId('tspan')

        tspan.text = unicode(self.options.de)
        tspan.set(inkex.addNS('role', 'sodipodi'), 'line')

        # Estido do texto
        style = {'font-size' : '58px', 'font-family' :'URW Chancery L',
                 '-inkscape-font-specification' : 'URW Chancery L Bold Italic',
                 'fill' : '#ff0000'}
        # Transformando o dict em uma string
        text_element.set('style', formatStyle(style))
        text_element.set('x', '362')
        text_element.set('y', '340')

        self.svg.append(text_element)

c = C()
c.affect()

Instalação

A instalação da extensão no Inkscape é algo realmente simples, basta copiar os arquivos criados dentro de um dos diretório de extensões, no caso do Linux, eles pode ser copiados em /usr/share/inkscape/extensions ou ~/.config/inkscape/extensions.

Um coisa bem bacana também é que se houver erros no script, ao ser executado, o Inkscape exibirá em uma janela de dialogo o stacktrace.

Utilização

O exemplo que criei para escrever o post é bem simples, porém serve de base para criação de um extensão mais complexa. O que o exemplo faz é pegar os parâmetros e criar um texto com três linhas contendo as informações obtidas.

Podemos utilizar a extensão de duas formas, pelo menu “Extensões” > “Cartões” > “Cartão de Natal…” no Inkscape ou por linha de comando da seguinte forma python natal.py --de "Diego Rubin" --para "Carla Viviana" --mensagem "são os votos" natal.svg > teste.svg. Os parâmetros --de, --para e --mensagem foram os parâmetros criados no __init__ da nossa classe. O argumento natal.svg é a base do cartão criado para o exemplo, este arquivo e todos os outros podem ser encontrado no repositório do blog no github.com. Este modo é muito útil se precisarmos criar vários arquivos em lote.


Me

Tenho estudado esse mundo mágico da programação desde 2005. Já consegui sustentar minha família usando Ruby, Java, Python, C++ e Javascript. O resto tenho usado para diversão ou aprendizado.