If anyone knows of ODF(+RDF?), Qt, KDE, C++ jobs floating around I'm headed back into that market. It would be fabulous to continue to hack on FOSS code ;)
In other news, if you are at LCA this week then you might like to drop by to see Martin and my talk on Abiword and RDF stuff.
C++, Linux, libferris and embedded development. Yet another blog from yet another NARG.
Saturday, January 14, 2012
Sunday, January 8, 2012
RDF, Abiword and Relations
Abiword now has growing GUI support for editing RDF in ODF documents. Much of this support compliments what is available in Calligra for RDF handling. There are some areas where Calligra has more features and some areas where Abiword now does. Hopefully both will continue to have a large and growing shared feature base.
As some folks will know, ODF allows one or more RDF/XML files to be shipped in the ODF file, and for that RDF to be linking to the document content from the content.xml file. This means that you can explicitly say that a 1/2 inch bolt is from a particular maker and was procured on the 3rd of January 2012 by going to their office at geolocation ?x. Handy when you are reading the document a year down the line and want to know which office you bought the bolt from and the exact length of its thread.
Looking at the below image, one can see the purple underlined pieces of text. Each of these has some RDF associated with it. The citation to Dan Brickley has both contact and location RDF associated with it. Looking at the toolbar, towards the right side you see an "R" to start a change tracked document, and the "RF" button. Sorry about the images there, I draw at the 3 year old level so my icons are not quite polished shall we say. Anyway, the "RF" button selects this reference to an RDF item. So if you are between the "am" in the purple "James" then the whole word will be selected with this button. The ">" and "<" buttons then allow you to move to the next and previous reference to the selected RDF item. As you notice another purple James later in the document, this is the second and only other reference to him and you can move between them using these buttons.

These purple links I call "RDF links", which is a bit of a play on hyperlinks or bookmarks. Behind the scenes they are implemented using xml:id values and pkg:idrefs to those from RDF.
A feature added in the last days is the ability to capture and navigate by the relation between two RDF links. This is currently done by selecting a "source" link and then clicking another rdf link and setting the relation to the source. So in the below screenshot I am saying that Mark foaf:knows James. You will also notice the "Find by Relation" option which I can then use to see the people that mark foaf:knows. In the spirit of the foaf definition, I have made this a symmetric relation. So there is no stalking, or "following", if James knows Mark then Mark knows James. Asymmetric relationships are also possible, like son, child, or contains. I am hoping to add this feature to Calligra too in the future as the relations between RDF objects is one of the more powerful features that can be offered by using RDF in a document.

Note that the prev/next RDF item buttons work with relations. If I pick mark and navigate to the James he knows then I can "next" from that james to select the second reference to James. This is one recurring theme to RDF in ODF, that RDF objects like contacts can be cited or linked zero or more times in the text content of the document.
As mentioned above, the converse is also true, and the Dan Brickley text has two logical RDF objects linked to it; Dan's contact information and his location. Handling this multi-object for a single site is a little tricky and in this editing will create a window with both the semantic objects in it to let you edit the RDF abiword knows about. Note that this dialog is actually backed by two (or more) SPARQL queries;

If you are not squeamish about your triples then the "Show RDF" option for an RDF link will let you get right at them and edit away as shown below. There are a few technically cool things about this dialog: firstly the "Restrict to RDF Link" combo box lets you select one or more RDF links that the triples will have to be associated with, and secondly abiword makes sure any edits you make are properly linked to the RDF link you right clicked on. What I mean by this last bit is if you right click the RDF link "alice33" add a new triple "uri:alive myvocab:likes uri:bob" then abiword will add the triple "uri:alice pkg:idref alice33" for you. This is sort of having abiword do what you mean in that you want the new triple to be associated with the link but don't necessarily want to have to explicitly say it all the time. By choosing to edit the RDF for the link you have already explicitly said once that you want these things to be linked. This also applies if you change a subject, uri:alice to uri:amanda will update the pkg:idref values for you. Keep it linked, keep it valid.

Going one level deeper, the above dialog is actually a subclass of a restricted RDF model created using SPARQL. The SPARQL model is read only, and the subclass, RDFModel_XMLIDLimited handles mutations by creating a wrapper object which takes care of the automatic triple relinking mentioned above. Those still awake might like to see the abiword trunk code for src/text/ptbl/xp/pd_DocumentRDF.cpp.
This is part of an ongoing mad hacking sprint that is leading up to a talk at LCA 2012 which starts in a week. Many of the things I mention here are not in trunk yet, and only tested on Linux/GTK+3. Those in Ballarat in a week might like to pop in to the talk given my Martin and myself on Friday the 20th.
As some folks will know, ODF allows one or more RDF/XML files to be shipped in the ODF file, and for that RDF to be linking to the document content from the content.xml file. This means that you can explicitly say that a 1/2 inch bolt is from a particular maker and was procured on the 3rd of January 2012 by going to their office at geolocation ?x. Handy when you are reading the document a year down the line and want to know which office you bought the bolt from and the exact length of its thread.
Looking at the below image, one can see the purple underlined pieces of text. Each of these has some RDF associated with it. The citation to Dan Brickley has both contact and location RDF associated with it. Looking at the toolbar, towards the right side you see an "R" to start a change tracked document, and the "RF" button. Sorry about the images there, I draw at the 3 year old level so my icons are not quite polished shall we say. Anyway, the "RF" button selects this reference to an RDF item. So if you are between the "am" in the purple "James" then the whole word will be selected with this button. The ">" and "<" buttons then allow you to move to the next and previous reference to the selected RDF item. As you notice another purple James later in the document, this is the second and only other reference to him and you can move between them using these buttons.

These purple links I call "RDF links", which is a bit of a play on hyperlinks or bookmarks. Behind the scenes they are implemented using xml:id values and pkg:idrefs to those from RDF.
A feature added in the last days is the ability to capture and navigate by the relation between two RDF links. This is currently done by selecting a "source" link and then clicking another rdf link and setting the relation to the source. So in the below screenshot I am saying that Mark foaf:knows James. You will also notice the "Find by Relation" option which I can then use to see the people that mark foaf:knows. In the spirit of the foaf definition, I have made this a symmetric relation. So there is no stalking, or "following", if James knows Mark then Mark knows James. Asymmetric relationships are also possible, like son, child, or contains. I am hoping to add this feature to Calligra too in the future as the relations between RDF objects is one of the more powerful features that can be offered by using RDF in a document.

Note that the prev/next RDF item buttons work with relations. If I pick mark and navigate to the James he knows then I can "next" from that james to select the second reference to James. This is one recurring theme to RDF in ODF, that RDF objects like contacts can be cited or linked zero or more times in the text content of the document.
As mentioned above, the converse is also true, and the Dan Brickley text has two logical RDF objects linked to it; Dan's contact information and his location. Handling this multi-object for a single site is a little tricky and in this editing will create a window with both the semantic objects in it to let you edit the RDF abiword knows about. Note that this dialog is actually backed by two (or more) SPARQL queries;

If you are not squeamish about your triples then the "Show RDF" option for an RDF link will let you get right at them and edit away as shown below. There are a few technically cool things about this dialog: firstly the "Restrict to RDF Link" combo box lets you select one or more RDF links that the triples will have to be associated with, and secondly abiword makes sure any edits you make are properly linked to the RDF link you right clicked on. What I mean by this last bit is if you right click the RDF link "alice33" add a new triple "uri:alive myvocab:likes uri:bob" then abiword will add the triple "uri:alice pkg:idref alice33" for you. This is sort of having abiword do what you mean in that you want the new triple to be associated with the link but don't necessarily want to have to explicitly say it all the time. By choosing to edit the RDF for the link you have already explicitly said once that you want these things to be linked. This also applies if you change a subject, uri:alice to uri:amanda will update the pkg:idref values for you. Keep it linked, keep it valid.

Going one level deeper, the above dialog is actually a subclass of a restricted RDF model created using SPARQL. The SPARQL model is read only, and the subclass, RDFModel_XMLIDLimited handles mutations by creating a wrapper object which takes care of the automatic triple relinking mentioned above. Those still awake might like to see the abiword trunk code for src/text/ptbl/xp/pd_DocumentRDF.cpp.
This is part of an ongoing mad hacking sprint that is leading up to a talk at LCA 2012 which starts in a week. Many of the things I mention here are not in trunk yet, and only tested on Linux/GTK+3. Those in Ballarat in a week might like to pop in to the talk given my Martin and myself on Friday the 20th.
Tuesday, November 22, 2011
das wiki == de filesystem
The libferris virtual filesystem gains another tentacle, this time being able to mount mediawiki sites. Some cool use cases right off the cuff:
To read a wiki page
$ fcat wiki://$server/mediawiki/index.php/SamplePage
To write to a wiki page:
$ date | ferris-redirect -T wiki://$server/mediawiki/index.php/Sampler22
For those who are unfamiliar, ferris-redirect takes its stdin and writes it to the file you name. The -T truncates the file first. So the above is sort of like " >| " from bash but you get to write from any application to any libferris filesystem without using FUSE.
To plomp an image up on mediawiki:
ferriscp -av /tmp/Apple.png wiki://$server/mediawiki/index.php/
Which is then available as:
http://$server/mediawiki/index.php/File:Apple.png
And perhaps the coolest little trick so far, which doesn't rely on FUSE or mounting and uses an unmodified vi binary:
$ fedit wiki://alkid/mediawiki/index.php/Sampler22
... modify the "file" ...
ZZ to write it back to the web.
Also, I have tramp hacks to allow this to work from emacs.
Of course, this all interacts with other things libferris can mount, so you can "cp" from your scanner or webcam right to a wiki page or grab text from a wiki and create a pdf or print it out directly.
Oh, and there are Fedora 16 packages now too on openSUSE build service. Just run the following to get it all onto your system.
# yum install libferris-suite
To read a wiki page
$ fcat wiki://$server/mediawiki/index.php/SamplePage
To write to a wiki page:
$ date | ferris-redirect -T wiki://$server/mediawiki/index.php/Sampler22
For those who are unfamiliar, ferris-redirect takes its stdin and writes it to the file you name. The -T truncates the file first. So the above is sort of like " >| " from bash but you get to write from any application to any libferris filesystem without using FUSE.
To plomp an image up on mediawiki:
ferriscp -av /tmp/Apple.png wiki://$server/mediawiki/index.php/
Which is then available as:
http://$server/mediawiki/index.php/File:Apple.png
And perhaps the coolest little trick so far, which doesn't rely on FUSE or mounting and uses an unmodified vi binary:
$ fedit wiki://alkid/mediawiki/index.php/Sampler22
... modify the "file" ...
ZZ to write it back to the web.
Also, I have tramp hacks to allow this to work from emacs.
Of course, this all interacts with other things libferris can mount, so you can "cp" from your scanner or webcam right to a wiki page or grab text from a wiki and create a pdf or print it out directly.
Oh, and there are Fedora 16 packages now too on openSUSE build service. Just run the following to get it all onto your system.
# yum install libferris-suite
Wednesday, October 12, 2011
Semantic Revolutions
I thought a fun little scenario for RDF in ODF would be to bounce information from Evolution, through abiword, to calligra, and then drag it back into evolution again. So information goes from ical to RDF, crosses the clipboard as RDF inside of an ODF file with linked text, and then is dragged back into ical format again. I notice a little timezone bug in there, but on the whole things work as one would expect.
Tuesday, September 20, 2011
Copy and Paste with Semantics...
Copy and Paste now preserves RDF between both Calligra and abiword in both directions. This lets you select some text in a document in either application, copy it, and paste it into the other application and have the RDF that is associated with that part of the document go along with the text you selected.
In the below screencast, the document that Calligra is editing has some contact and event information stored in RDF. The three people in the first sentence all have contact information associated. As you can see, the RDF sidepanel in Calligra lets you know about this as the cursor moves around. James has his phone number captured in RDF which the edit dialog shows. If I select one or more of these contacts and "Copy" them to the clipboard, Calligra creates an ODF file with embedded RDF in it and offers that on the clipboard.
Abiword is happy to accept that ODF content and when you paste it into a document you can see that the RDF links are preserved, and that there are 7 RDF triples associated with James. Of course, you want full disclosure of this information, so clicking show RDF lets you examine and edit those RDF triples.
I put a little trick in going the other way just to spice things up a little bit. The multi.odt file that I have open in abiword has two RDF links in scope at the Wing-B link. RDF is associated with the whole paragraph and explicitly with the link itself. In particular, the uri:widetime is associated with the paragraph while the uri:wingb is associated with the RDF link itself. Once I grab that RDF link and copy it to the clipboard, again an ODF file is offered (as well as text and rtf), and again Calligra is more than happy to accept an ODF file on the clipboard. Notice that when I show all the RDF in Calligra both the widetime and wingb RDF triples have now become part of the document.
I made some changes in both calligra and abiword to get this to happen. Changes to the former were quite small. You'll have to grab trunk from both applications if you want to play along at home. The code is committed in both trees.
In the below screencast, the document that Calligra is editing has some contact and event information stored in RDF. The three people in the first sentence all have contact information associated. As you can see, the RDF sidepanel in Calligra lets you know about this as the cursor moves around. James has his phone number captured in RDF which the edit dialog shows. If I select one or more of these contacts and "Copy" them to the clipboard, Calligra creates an ODF file with embedded RDF in it and offers that on the clipboard.
Abiword is happy to accept that ODF content and when you paste it into a document you can see that the RDF links are preserved, and that there are 7 RDF triples associated with James. Of course, you want full disclosure of this information, so clicking show RDF lets you examine and edit those RDF triples.
Copy and Paste of RDF from Calligra to Abiword from Ben Martin on Vimeo.
I put a little trick in going the other way just to spice things up a little bit. The multi.odt file that I have open in abiword has two RDF links in scope at the Wing-B link. RDF is associated with the whole paragraph and explicitly with the link itself. In particular, the uri:widetime is associated with the paragraph while the uri:wingb is associated with the RDF link itself. Once I grab that RDF link and copy it to the clipboard, again an ODF file is offered (as well as text and rtf), and again Calligra is more than happy to accept an ODF file on the clipboard. Notice that when I show all the RDF in Calligra both the widetime and wingb RDF triples have now become part of the document.
Copy and Paste from Abiword to Calligra from Ben Martin on Vimeo.
I made some changes in both calligra and abiword to get this to happen. Changes to the former were quite small. You'll have to grab trunk from both applications if you want to play along at home. The code is committed in both trees.
Tuesday, September 13, 2011
Bringing back /dev/pcm
Taking a peek in /dev/snd one might find device files for their sound card(s). Sequencers, Timers, midi, and pcm device files. I thought it might be interesting to apply a modern face lift to these devices; so now libferrris can mount pulseaudio and has write support for gstreamer.
What this means is you can write "audio" data to a virtual filesystem and have it play that back for you:
$ cat /tmp/sample.flac | ferris-redirect -T gstreamer://output/audio
ferris-redirect is like the shell pipe character but allows direct access to libferris filesystems without mount commands. The -T truncates, so it is like a ">|" bash redirection.
I also plan to make these output directories special. If you write to them like they are a file as in the above then it puts your data there. If you create a subfile and write to it you will be essentially writing to the output file itself. With that you could "cp" a directory of audio files to gstreamer://output/audio and they will play one at a time until you have copied them all to your speakers ;)
$ ferriscp -av /tmp/bongos-dir gstreamer://output/audio
Pulseaudio is available at pulseaudio:// or the shortcut pa://. The tree currently allows you to mute and alter the volume for playing streams and whole output devices. Reading a volume file will tell you the percentage that channel outputs at (or the average for volume-all). Writing a float to the volume files changes the volume to suit your request. The mute files similarly show if the audio is muted and allow you to set that by writing 1 or 0 to the file.
$ fls -0 pa://output/default
mute 0
volume-0 0.729996
volume-1 0.729996
volume-2 0.729996
volume-3 0.729996
volume-4 0.729996
volume-5 0.729996
volume-all 0.729996
$ echo 0.7 | ferris-redirect -T \
"pulseaudio://streams/amarok/Audio Stream/volume-all"
All this ferris-redirect stuff can have it's additional typing mitigated using a suitable inputrc.
For example:
$ cat ~/.inputrc
$include /etc/inputrc
">>>": "| ferris-redirect "
">>|": "| ferris-redirect -T "
This will be in the next libferris release tarball. Things slowly get closer for the libferris QML mobile audio app. You can already do index and search with libferris and get at the results as a QModel for use in QML, now you can also set volumes and "copy" sound to the earphones.
What this means is you can write "audio" data to a virtual filesystem and have it play that back for you:
$ cat /tmp/sample.flac | ferris-redirect -T gstreamer://output/audio
ferris-redirect is like the shell pipe character but allows direct access to libferris filesystems without mount commands. The -T truncates, so it is like a ">|" bash redirection.
I also plan to make these output directories special. If you write to them like they are a file as in the above then it puts your data there. If you create a subfile and write to it you will be essentially writing to the output file itself. With that you could "cp" a directory of audio files to gstreamer://output/audio and they will play one at a time until you have copied them all to your speakers ;)
$ ferriscp -av /tmp/bongos-dir gstreamer://output/audio
Pulseaudio is available at pulseaudio:// or the shortcut pa://. The tree currently allows you to mute and alter the volume for playing streams and whole output devices. Reading a volume file will tell you the percentage that channel outputs at (or the average for volume-all). Writing a float to the volume files changes the volume to suit your request. The mute files similarly show if the audio is muted and allow you to set that by writing 1 or 0 to the file.
$ fls -0 pa://output/default
mute 0
volume-0 0.729996
volume-1 0.729996
volume-2 0.729996
volume-3 0.729996
volume-4 0.729996
volume-5 0.729996
volume-all 0.729996
$ echo 0.7 | ferris-redirect -T \
"pulseaudio://streams/amarok/Audio Stream/volume-all"
All this ferris-redirect stuff can have it's additional typing mitigated using a suitable inputrc.
For example:
$ cat ~/.inputrc
$include /etc/inputrc
">>>": "| ferris-redirect "
">>|": "| ferris-redirect -T "
This will be in the next libferris release tarball. Things slowly get closer for the libferris QML mobile audio app. You can already do index and search with libferris and get at the results as a QModel for use in QML, now you can also set volumes and "copy" sound to the earphones.
Labels:
filesystem,
gstreamer,
kde,
libferris,
pulseaudio
Thursday, September 1, 2011
Abiword RDF Drag and Drop
Now that abiword has low level RDF support I thought I'd make it simpler to get some data into the document's RDF. The initial support lets you drag contact and calendar entries from Evolution into your document as shown below. Notice that a new RDF Link is created for you and when you choose to right click that link and "Show RDF" there are many RDF triples that have been created by the D&D action.
I think these sort of user interface additions help to make using RDF quick and easy, even for those who don't know or care what it is and where it gets stored in the document. Abiword can load and save RDF in both it's native abw files and ODF formats. You can of course convert between both without loosing the RDF ;)
I plan to add D&D in the other direction later on, so you can pickup a person from a document or an event. Similar to how many email clients let you import ics calendar files into your local Calendar. Having RDF in ODF lets you share content, style, and semantics, all in a truly open format single file.
Oh, and the code should hit svn trunk real soon now.
Abiword RDF Drag and Drop from Ben Martin on Vimeo.
I think these sort of user interface additions help to make using RDF quick and easy, even for those who don't know or care what it is and where it gets stored in the document. Abiword can load and save RDF in both it's native abw files and ODF formats. You can of course convert between both without loosing the RDF ;)
I plan to add D&D in the other direction later on, so you can pickup a person from a document or an event. Similar to how many email clients let you import ics calendar files into your local Calendar. Having RDF in ODF lets you share content, style, and semantics, all in a truly open format single file.
Oh, and the code should hit svn trunk real soon now.
Subscribe to:
Posts (Atom)