INKMACS - Inkscape Emacs fusion
What is Inkmacs?
Inkmacs is a fusion between Inkscape and Emacs. Well, in the far future at least. But its kind of cool right now also.
Inkscape is a very capable free software vector drawing tool. Emacs is the One True Editor.
With Inkmacs you can use Emacs to do interesting things with Inkscape using DBUS IPC.
Inkmacs lives here:https://github.com/jave/inkmacs
Real world usability
Currently I use Inkmacs for a very large technical poster at a Client. It has lots of text so Inkmacs is a very suitable tool.
The Emacs/Inkscape combo is actually surprisingly robust. I experience few crashes now.
I have some issues but they are in unexpected areas such as Inkscape generated PDF isn’t well handled at the printshop. The free PDF renderers such as Poppler used by Evince are in fact more robust than Adobes so I hadn’t noticed any issues at home.
Synchronize Inkscape text nodes with Org mode text nodes.
Edit an Org mode file as usual.
‘m-x inkmacs-edit’ starts a linked inkscape instance. The svg file name is derived from the root node. inkorg-minor-mode is enabled, which in turn enables the inkorg mode map detailed below.
Each root node can have its own inkscape document.
‘c-m-x’ creates or syncs the text of the current org node with an inkscape node.
‘c-u c-m-x’ creates or syncs the whole tree.
You can move the nodes and format the text in inkscape. only the text is kept in the org tree.
Since Inkscape is a drawing tool it has different notions of text somewhat alien to an Emacs user. Text objects can be bound to ‘flow frames’ which are graphic shapes that bounds the flow of text. By default Inkmacs creates rectangles, but its possible to use any shape.
The Inkscape representation of an Org node is thus two objects. One flow frame and one text object.
It can be a little tricky to select the object you want to work with. inkorg-mode has (embryonic) support:
‘m-x inkorg-select-tree’ selects all corresponding inkscape nodes. With argument, define a filter: ‘keep-siblings ‘keep-sibling-subtrees ‘keep-subtree
Image mode support
Create Elisp macros that perform Inkscape edit operations
‘m-x inkmacs-edit’ opens the svg file in the current emacs buffer in inkscape. A dbus link is established.
dbus linked inkscape control
When a dbus link is established from an emacs buffer to an Inkscape desktop, it is then possible to call inkdoc or inkverb methods on Inkscape.
The inkverb-* methods are interactive and theres a lot of them. So ‘m-x inkverb-calligraphic-prefs’ in a buffer using inkorg-minor-mode for example, will bring up the calligraphy preference ui.
The inkverb-* methods are mostly ui related and take no arguments.
The inkdoc-* methods are related to object creation and manipulation and are not (yet) declared interactive.
Finding the right Inkscape operation in Emacs can actualy be much more efficient than using the menus in Inkscape. Especialy if you use some M-x booster such as Anything or Icicles.
Currently needs bleeding edge versions of a number of components.
- trunk version of inkscape with dbus enabled
- trunk version of Eieio(needs a change which hasnt been merged downstream)
- trunk version of Jan Moringen dbus-proxy
- Emacs 23. I use Emacs 24 from trunk, but 23 should be ok. but since everything else is bleeding edge you might as well use a bleeding edge Emacs also. You know you want to.
get Inkmacs bugfixes merged
please note that there is an Inkscape branch where I have some bugfixes for the dbus support: lp:~joakim-verona/inkscape/dbus-fixes In particular the ink-org integration wont work at all without the fixes
the long term goal is to make an Emacs that does things quickly that currently inhibits creative flow with inkscape. In particular I want to make a framework that supports specialized workflows, such as producing sketches for blog entries and web comics. so, when inspiration hits you: m-x inkscape-blog-sketch, rather than fiddling about in menus etc until you loose inspiration.
I am also interested in building a presentation tool on top of the inkmacs org integration. This is currently based on org-mode and is called inkorg minor mode in inkmacs. Inkorg seems to be pretty good for the purposes mentioned and is currently the flagsdip UI of Inkmacs.
For this we want to:
make the xwidget Emacs branch usable, so inkscape can be embedded
in Emacs(this is very far future)
make inkscape support xembed, so it can be embedded in Emacs.
I have a branch on launchpad for this but it has issues and is long term
make an inkscape mode that shows just the canvas.
maybe using inkview.
make an Emacs inkscape control mode that implements a proper Emacs
ui on top of inkscape. the foundation for this is done. Whats lacking is good bindings.
somehow implement the Emacs buffer model with inkscape
implement a form of OLE.
display svg images inline muse-mode org org mode for example. this is already mostly possible.
edit the svg inside inkscape when desired
very important is to support text editing in Emacs.
nodes in an outline-mode document should preferably be bound to nodes in the inkscape document.
an annoying extra inkscape window appears
happens when the proxies are registered. theres seemingly no straightforward way around it.
some test code snippets
check alive (dbus-ping :session “org.inkscape” 100)
(dbus-introspect-xml :session “org.inkscape” “/”)
(dbus-introspect-get-all-nodes :session “org.inkscape” “/org/inkscape”)
(dbus-introspect-get-interface :session “org.inkscape” “/org/inkscape/application” “org.inkscape.application”) (dbus-introspect-get-method-names :session “org.inkscape” “/org/inkscape/application” “org.inkscape.application”) (dbus-introspect-get-method-names :session “org.inkscape” “/org/inkscape/desktop_24” “org.inkscape.document”) (dbus-introspect-get-method :session “org.inkscape” “/org/inkscape/desktop_24” “org.inkscape.document” “rectangle”)
(dbus-introspect :session “org.inkscape” “/org/inkscape”)
the verb proxies
inkscape doesnt export all functionality through proper dbus interfaces atm. there is an older “verb” interface, and a dbus bridge. here is some code that tries to aproximate the dbus-proxy api for the verb api
the dbus proxies
creating the dbus proxies, using Jan Moringen fantastic dbus-proxy library. The way emacs dbus integration was meant to be
inkdoc load issue
BUG funnily crashes if called twice on the same desktop object(not reproducible) inkdoc-load is awkward:
- 1st open happens inside “virgin” desktop
- subsequent opens happen in new desktops
- the resulting desktop name isnt returned
inkscape org integration
inkscape org integration - the pride of inkmacs
- tree level 1 represents the file
- tree level 2 is a column heading
- tree level 3 and lower are placed in the column
inkscape text is a little bit unintuitive: text objects are realy a set of text span objects with separate prperties but tde api doesnt ouite reflect that because its inconvenient anyway furthermore the spans dont change after you create them
for the purpose of inkorg, its nicer if we handle formating and wordwrap inside inkscape. to get that we need a text object and another linked object which determines the shape. they are both handled separately.
Also note that svg 1.2 isn’t finalized: http://wiki.inkscape.org/wiki/index.php/FAQ#What_about_flowed_text.3F
In practice this means that early 2011 the flow text nodes won’t show up if you try to render the image in Firefox or Webkit based browsers. librsvg2 which is used in Emacs won’t work either. This is hardly convenient. I’m investigating two non-mutex ways forward:
- rendering the svg image to another image format on demand
- optionaly use the textspan object rather than the flowroot. Then you would have to handle text line break in Emacs which might be okay for some cases.
tip: create a special text layer before inkorg-create-text-group
strategy for orphaned nodes
if a node has been removed from the org doc it should also be
removed from the ink doc. this is however a bit tricky. naive method to find orphan nodes:
- build a list A of all inkscape objects using select-all
- build a list B of all inkorg nodes by iterating the org tree and extracting the id
oh wait - I dont know which A:s used to be inkorg nodes. aargh! inkscape groups cant really be used because it changes behaviourp the only reasonable alternative seems to be to use a naming convention: inkmacs-<type>-<orgid>
subtree export support
inkorg mode works sort of like org export but its not always entirely the same. Nevertheless inkorg should reuse org export code when possible. A big difference is that the svg file is used in tandem with org. it is not generated from org like other org exports.
doesnt really work because the name is used to link to the svg file. a property can be added to override the file name. a better error is needed to show the error is unlinked file. changing name of root inkorg node.
could be used to override the default file name.
org mode does this already. CANCELLED [#B] some form ov planner/outline integration that works with ecb
look at org-ascii
to replace my text extractor
support formatted text
For this we need:
- support to apply styles to text via ibus in inkscape.
My dbusfixes branch has this and the prospect of inclusion are good.
- inkorg support for extracting the org formatting.
The way things work atm this will be a 2 step process. create text, then apply styles.
better file import wrapper
Emacs is a great file selecor I’d like to use in order to import clip art into a technical drawing for instance.
inkverb-file-import triggers the inkscape import dialogue. I need to figure out a way to send the file name as a parameter instead. It might turn out I need another dbus interface function.
An interface to openclipart.organisation on top of this would be useful. Inkscape has support for openclipart which is good but in think Nkmacs can do better:)
- fetch the query result to a buffer with url-get
- parse the xml using the emacs 24 xml parser
- fetch thumbnails and display asynchronously
- each thumbnail is a button with an interface to inkmacs-file-import
- download the svg and imort it when button clicked
it happens that flowtext can get a tranform because it was dragged around outside its flowframe. sometimes it would be nice to reflow.
resize flowframe from text size
the frame holding a flowed text is often too small. currently it needs to be resized by hand. it appears possible to find the height of the flowtext and set the height of the flowframe accordingly.
note that the ontire point of flowframes is that the frame sets the size of the text. so its not meaningful to set more than either height or width from the text.
help to export clean interchange formats like svg 1.1 and PDF that actually works in acroread.
inkscape has pdf export but it sometimes creates pdf:s which arent readable by acroread.
batix also has issues with the corresponding svg.
- filter:url(#filter2573-3). the filter was undefined. It had gotten removed during editing
- svg version 1.2
one workaround was using evince to filter the inkscape pdf.
another way is checking the SVG with Batik and edit the XML in Emacs. it would work by parsing objoct references of type url and report.
batik pdf transcode: java -jar /home/joakim/batik-1.7/batik-rasterizer.jar -m application/pdf tst.svg
Emacs suffer from regexp overflow atm.
https://bugs.launchpad.net/inkscape/+bug/780335 contains good inforrmation:
one particular gradient type causes problems. “reflected”. identify and remove.
iterate all flowtext and convert to text
flowtext is good when you work with your document. text flows nicely in your shapes. OTOH flowtext sucks when publishing your SVG because only SVG 1.1 is finalized flowtext requires 1.2.
So it would be nice to convert back and forth.
faster SVG renderer in Emacs
THe SVG renderer in Emacs is librsvg. It’s robust but not fast because it renders to a deep bitmap and doesn’t seem to clip. Anyway, its not fast enough to pan around and zoom in and out of a SVG. Things to investigate:
- make the librsvg usage faster by cleverer clipping and less bitmap copying
- try anether svg renderer like Cairo thats new and shiny
the end result would be a dual screen displof which lets you select a region inside an SVG in one window and voom into that region in another window, on a separate projector for instance.
recover if the first inkscape dies
if you try to redo proxies then it crashes.
jessyink is an inkscape extension that creates portable presentations in svg. I want inkmacs to be compatile. I think it should be mostly already.
focus on particular area during presentations
works like this:
- make a special layer with named rectangles. these are your focus areas
- make layer invisible during presentation
- bind “inkmacs-zoom-id” to something convenient during your presentation
the last part is the only tricky thing since Inkscape will be in focus and Emacs won’t have kbd focus. you will need a bridge at the WM level. dbus or emacsclient.
also you will need to know the ids of your focus objects.