My first text extension
=======================
This article will teach you the basics of writing a Text Extension for
Inkscape using the ``inkex`` Extensions API.
Introduction
------------
Any extension that manipulates text in any way is a Text Extension. Text
Extensions can broadly be categorized in two types based on the type of
manipulation they do to text:
1. **Manipulating the text itself** - like changing case.
2. **Changing attributes of the text** like font, color, size, etc.
There can also be extensions which are a hybrid of both the above
types.
In this article we will create an extension named ``Stronger Text``. It
is a *Type 2* Text Extension and it will make the selected text bold and
it will also italicize it. We will also see an example of creating a
*Type 1* Text Extension.
.. hint::
This article assumes you create all files in the User Extensions
directory which is listed at
``Edit``>\ ``Preferences``>\ ``System`` - ``User Extensions:`` in
Inkscape.
Step 0 : The Boilerplate
------------------------
Like any other Inkscape extension, this extension will also have two files.
So, create a ``stronger_text.inx`` file and a ``stronger_text.py`` file.
- ``stronger_text.inx``: It will have the necessary information
for Inkscape to be able to recognize your extension as a valid
Inkscape extension. It will also have the declaration of any
interface for your extension.
- ``stronger_text.py``: It will have
the actual Python code your extension will execute.
.. hint::
There is another file that is worth mentioning here - the **test**
file which in our case will be ``test_stronger_text.py``. It is not
required to be present for an extension per se, but as a best
practice, the extension code should always be accompanied by test
code.
Step 1 : Populate the ``*.inx`` file
------------------------------------
Our extension **Stronger Text** will have a very basic ``.inx`` file.
.. code:: xml
Stronger Text
org.inkscape.text.strongertext
all
Explanation
~~~~~~~~~~~
The lines below help Inkscape uniquely identify our extension so that it
can be displayed under the **Extensions** menu. You should modify these
two lines for your own extension:
.. code:: xml
[...]
Stronger Text
org.inkscape.text.strongertext
[...]
Towards the end of the ``.inx`` file, we change the submenu to ``Text``.
It specifies that this extension should be listed in the **Text**
submenu under the **Extensions** menu in Inkscape UI:
.. code:: xml
[...]
all
[...]
Now - Save the file - Close any open Inkscape windows - Relaunch
Inkscape
After successfuly completing these steps, you should see the Stronger
Text extension in Inkscape UI.
.. figure:: resources/Inkscape_Recognizes_Our_Extension.gif
:alt: Inkscape Recognizes Our Extension
Inkscape Recognizes Our Extension
Currently it doesn’t do anything as we haven’t written anything in the
``stronger_text.py`` file.
Step 2 : Write the code in ``*.py`` file
----------------------------------------
First Things First
^^^^^^^^^^^^^^^^^^
To be able to use any extension functionality, you need to import the
``inkex`` module.
.. code:: py
import inkex
Every Text Extension inherits from the :class:`~inkex.extensions.TextExtension` class provided
by the ``inkex`` API. Let’s name our class ``StrongerText`` (an
arbitrary name) and inherit the :class:`~inkex.extensions.TextExtension` class.
.. code:: py
import inkex
class StrongerText(inkex.TextExtension):
#implement functionality here
pass
The ``TextExtension`` class provides us with methods to manipulate the
text.
Our extension ``Stronger Text`` is a *Type 2* extension as it needs to
change the attributes of text. To get access to the attributes of the
text, we need to override the :func:`~inkex.extensions.TextExtension.process_element` method.
.. code:: py
import inkex
class StrongerText(inkex.TextExtension):
def process_element(self, text_node):
text_node.style["font-weight"] = "bold"
text_node.style["font-style"] = "italic"
#text_node.style["attribute-name"] = "value"
StrongerText().run()
.. _explanation-1:
Explanation
~~~~~~~~~~~
| ``text_node.style`` provides us with a dictionary (technically it’s an
``OrderedDict``) which we can use to change the attributes of the text
by using the attribute name as a key.
| When a standard inkex-based Text Extension is run, it will call a
method called :func:`~inkex.extensions.TextExtension.effect` on the ``TextExtension`` class which then
eventually calls our(``StrongerText``\ ’s) ``process_element``
function. \**\* If your extension is a *Type 1* Text Extension, i.e,
it’s purpose is to take text from Inkscape, transform/manipulate it,
and return it to Inkscape, you just need to override the
:func:`~inkex.extensions.TextExtension.process_chardata` function like so:
.. code:: py
import inkex
class UpperCase(inkex.TextExtension):
def process_chardata(self, text):
# do some more manipulations here if you want
return text.upper()
UpperCase().run()
.. _explanation-2:
Explanation
~~~~~~~~~~~
The ``text`` parameter in the :func:`~inkex.extensions.TextExtension.process_chardata` function receives
the text from Inkscape as a Python string. In the :func:`~inkex.extensions.TextExtension.process_chardata`
function itself, we can manipulate the string in any way to our
liking. We then return the manipulated string.
Infact, if you’ve used the ``UPPERCASE`` extension in Inkscape from
the ``Extensions``>\ ``Text``>\ ``Change Case`` submenu, it is
identical to the Extension we just wrote!
.. hint::
This *Type 1* Extension
will have an almost identical ``.inx`` file with changes in places
like the ```` and ```` tags and a separate ``.py`` file with
the above code in it.
Moment of Truth
---------------
Now, we should test our extension to see it in action. - Select some
Text (preferably a font that has bold and italics styles available) -
Click on the **Stronger Text** extension
The result should appear like this:
.. figure:: resources/Text_Ext_Moment_of_truth.gif
:alt: A gif showing that the extension works.
Did It Work? (yes, indeed)