Skip to main content

Sysadmin, interested in new technologies, communications, multimedia, accessibility, better Linux than Windows, better Android than IOS and similar.

twitter.com/pvagner

www.facebook.com/pvdeejay

plus.google.com/112635519863097306017

Peter Vágner

Likes and Reposts handled by the @WithKnown Bookmarks plugin (part 2)

2 min read

Two days ago I have posted an article describing how I started using @WithKnown built-in Bookmarks plugin to handle Likes and Reposts uninstalling Reactions plugin I was using before.
Some people (including andrea and Chris Aldrichreacted on it that prompted me to look at it again and try to clear a few more points.
I did a mistake in my original article and I had to edit it. The bookmarks plugin handles all three classes within a single entity_subtype and I have recommended to create two entity subtypes IdnoPlugins\Like\Like and IdnoPlugins\Like\Repost where i should have only recommended the former.
The Reactions plugin handles the body property of the contents database column differently for Likes and for Reposts so I have added some notes explaining the situation.
And I have completelly missed the look and feel of resulting pages.
As andrea points out, all the Likes and Reposts and Bookmarks now look identical on my site. Unfortunatelly there are only two small differences. The correct classes are used and each type has its own icon. I don't care for the visual appearance that much my-self, however the fact correct indieweb classes are there make me happy I have chosen this route. If someone skilled enough can step up to provide additions to the Bookmark plugin template handling these post types differently, I am happy to see it  on the web and on my site.

There are some more serious issues with this and I hope either I or someone else will be able to suggest and / or add improvements. When posting via micropub e.g. from woodwind all is working well. When posting via bookmarklet or from the Known UI, all the entries are stored as bookmarks. This is the most serious issue.
I have chosen some of my posts so you can see these are valid: Like, Repost, Bookmark.
So I think we are slowly approaching what Chris Aldrich suggests i.e. unifying it all working in the core of Known.

Peter Vágner

Untangling @WithKnown plugin conflicts on the #IndieWeb (Reactions vs Bookmarks)

18 min read

Regarding various Known post types there is a story I would say I think so because at least for me it took so long to sort it out on my instance.
After I've installed Known on my domain some time in july 2016 I have realized the Repost and Like post types don't appear to be available right on the main page so I've installed Reactions plugin.
Everything worked smoothly for me at that time I was posting a lot of likes to my site, I have even reposted a few things. So given the fact it was all perfectly pieced together and worked fine I was not following the Known development and I missed all its updates. In particular one significant change was that since version 0.9.2built in Bookmarks plugin deployed inside the IdnoPlugins/Like folder received an ability to handle likes, reposts and bookmarks. I have only acknowledged this issue about a year later in june 2017.
Looking through both issues there was no easy solution to this seemingly misterious incompatibility and that got me thinking in somewhat different direction.

  • Built-in Bookmarks plugin can now handle likes and reposts.
  • Do I need seperate Bookmark, Like and Repost buttons on the main page if I am either using corresponding bookmarklet or posting from the phone using an android app?
  • Is there something else I might miss in the future Reactions plugins provides?


I was unable to answer the last question however first two points indicate I no longer need Reactions plugin because Bookmarks plugin which lives in the core can do what I need it to do.
Okay so I then went to examine how the data are stored in the database trying to work out if I can turn Likes and Reposts created with Reactions plugin into Likes and Reposts built-in Bookmark plugin can now handle. I'm using MariaDB and first I wanted to see how many entries there are in my database I have created using Reactions plugin.

SELECT COUNT(*) FROM entities WHERE entity_subtype LIKE "IdnoPlugins%Reactions%";

Now how many of them are Likes

SELECT COUNT(*) FROM entities WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Like";

And finally how many of them are Reposts

SELECT COUNT(*) FROM entities WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Repost";

While examining these data I have noticed that the entity_subtype is a dedicated database table column, however the same thing is also stored in the contents column holding all the entity content as a json string. So I have just double checked if these two places agree with each other.

SELECT COUNT(*) FROM entities WHERE contents LIKE "%\"entity_subtype\":\"IdnoPlugins%Reactions%\"%";

And now a different check of the same thing:

SELECT COUNT(*) FROM entities WHERE INSTR(contents, "\"entity_subtype\":\"IdnoPlugins\\\\Reactions") > 0;

Now I think I can use these building blocks to conditionally select entities I will be changing. However I don't yet know what changes to do.

This is how the Like created with the Reactions plugin is stored in the database:

MariaDB [mydatabase]> SELECT * FROM entities WHERE (entity_subtype LIKE "%like" ) ORDER BY created LIMIT 1;
+----------------------------------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------+
| uuid                                                                             | _id                              | owner                              | entity_subtype        | created             | contents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | search                                    | publish_status |
+----------------------------------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------+
| https://pvagner.tk/2016/liked-ryan-rixs-catastrophic-data-loss-and-me-0647a70c63 | 58debaa17faedc195f6ca78ca23249f5 | https://pvagner.tk/profile/pvagner | IdnoPlugins\Reactions\Like | 2016-07-10 12:36:42 | {"access":"PUBLIC","owner":"https:\/\/pvagner.tk\/profile\/pvagner","likeof":"http:\/\/notes.whatthefuck.computer\/1467388500.0-note.html","syndicatedto":["https:\/\/twitter.com\/rrrrrrrix\/status\/748993485538111488","https:\/\/www.facebook.com\/10153834879468856\/posts\/10154372324658856"],"description":"Ryan Rix's Catastrophic Data Loss and Me","_id":"58debaa17faedc195f6ca78ca23249f5","slug":"liked-ryan-rixs-catastrophic-data-loss-and-me-0647a70c63","created":1468154202,"updated":1468154202,"uuid":"https:\/\/pvagner.tk\/2016\/liked-ryan-rixs-catastrophic-data-loss-and-me-0647a70c63","entity_subtype":"IdnoPlugins\\Reactions\\Like"} | ryan rix's catastrophic data loss and me  | published      |
+----------------------------------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------+

And this is how a different like created with Bookmarks plugin is stored:

MariaDB [mydatabase]> SELECT * FROM entities WHERE (entity_subtype LIKE "%like" ) ORDER BY created DESC LIMIT 1;
+----------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+----------------+
| uuid                                                     | _id                              | owner                              | entity_subtype        | created             | contents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | search                                                                                    | publish_status |
+----------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+----------------+
| https://pvagner.tk/view/9251ea447da9ae82fdc29af9cac2ee56 | 9251ea447da9ae82fdc29af9cac2ee56 | https://pvagner.tk/profile/pvagner | IdnoPlugins\Like\Like | 2018-01-23 12:48:38 | {"access":"PUBLIC","owner":"https:\/\/pvagner.tk\/profile\/pvagner","body":"https:\/\/torrentfreak.com\/denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto-180123\/","likeof":"https:\/\/torrentfreak.com\/denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto-180123\/","description":null,"tags":null,"pageTitle":"Denuvo Has Been Sold to Global Anti-Piracy Outfit Irdeto - TorrentFreak","slug":"denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto","created":1516711718,"updated":1516711719,"publish_status":"published","_id":"9251ea447da9ae82fdc29af9cac2ee56","uuid":"https:\/\/pvagner.tk\/view\/9251ea447da9ae82fdc29af9cac2ee56","shorturl":"1hJTnB","posse":{"twitter":[{"url":"https:\/\/twitter.com\/pvagner\/status\/955784340310581248","identifier":"@pvagner","item_id":"955784340310581248","account_id":"pvagner"}],"mastodon":[{"url":"https:\/\/mastodon.sk\/@pvagner\/99399219252030242","identifier":"pvagner@mastodon.sk","item_id":"pvagner@mastodon.sk","account_id":""}]},"entity_subtype":"IdnoPlugins\\Like\\Like"} | https://torrentfreak.com/denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto-180123/ | published      |
+----------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+----------------+

Based off all the stuff I have gathered so far I compiled this short list of steps:

  • Create a backup of your running database so you can go back and retry if something is not working the way you are expecting.
  • Disable reactions plugin. This will stop displaying the broken Likes and Reposts for a while.
  • Tweak the search database table column to contain the same URL  the same thing as body, likeof or repost inside the contents json.
  • Tweak the contents column for all these Likes and reposts which were created by the Reactions plugin
    1. to have "entity_subtype":"IdnoPlugins\\Like\\Like" or "entity_subtype":"IdnoPlugins\\Like\\Repost" respectively. Basically replacing IdnoPlugins\\Reactions with IdnoPlugins\\Like.
    2. to have the same body than the respective "likeof" or "repost". Note that entries created with Reactions plugin are lacking the body property.
    3. To repurpose description into a pageTitle as Reactions plugin does not allow entering a description and makes no use of pageTitle.
  • Change the database table column entity_subtype the same way we have changed entity_subtype within the contents column. This will make all the entries visible again.


Now I need to be able to retrieve the likeof url from the contents discarding all the rest. I know there is a json specific extension for current development version of MariaDB, however I am still running version 10.1, so I'll have to resort to string manipulation and regular expressions. If you are running other database flavour or an older version you will have to tweak this I guess.
I will be only showing queries tweaking Likes, if you are interested you can easily run them again for Reposts as well.

SELECT REPLACE(SUBSTR(REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), 11), '\\/', '/') FROM entities WHERE (entity_subtype LIKE "%Like" AND INSTR(contents, "\"body\":") <= 0) ORDER BY created DESC LIMIT 10;

At this point we are finally ready to run some UPDATE statements doing what I have just suggested.

Changing the search database table column for all the Likes created by the Reactions plugin (needs adjusting in order to work with Reposts):

UPDATE entities SET search = REPLACE(SUBSTR(REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), 11), '\\/', '/') WHERE (entity_subtype LIKE "IdnoPlugins%Reactions%Like");

Tweaking the entity_subtype within the contents column (handles both Likes and Reposts at the same time):

UPDATE entities SET contents = REPLACE(contents, "\"entity_subtype\":\"IdnoPlugins\\\\Reactions", "\"entity_subtype\":\"IdnoPlugins\\\\Like") WHERE INSTR(contents, "\"entity_subtype\":\"IdnoPlugins\\\\Reactions") > 0;

Creating a missing body property inside the contents column (you need to adjust it to work with Reposts):

UPDATE entities SET contents = REPLACE(contents, REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), CONCAT("\"body\":\"", SUBSTR(REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), 11), "\",", REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'))) WHERE (entity_subtype LIKE "%Like" AND INSTR(contents, "\"body\":") <= 0);

Repurposing descriptions to pageTitles within the contents column for all Likes where there is no pageTitle (you need to also adjust this to work on Reposts):

UPDATE entities SET contents = REPLACE(contents, "\"description\"", "\"pageTitle\"") WHERE (entity_subtype LIKE "%Like" AND INSTR(contents, "\"pageTitle\":") <= 0);

And a final step changing entity_subtype column to be handled by the built-in Bookmarks plugin:

UPDATE entities SET entity_subtype="IdnoPlugins\\Like\\Like" WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Like";
UPDATE entities SET entity_subtype="IdnoPlugins\\Like\\Repost" WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Repost";

Definatelly there might be a more straightforward way on how to accomplish this. Tweaking the data may even not be the right solution, however I think it worked fine for me.

Edit: It turned out I was wrong on some points. So I have edited this article correcting incorrect stuf and I have also posted a follow up article explaining what I have done wrong here.

Peter Vágner

Obrovské rozmery projektov okolo Biblie

4 min read

Ako som si tak jeden nedeľný podvečer pozeral novinky v katalógu open-source aplikácií pre Android F-Droid, cez aplikáciu RadioDroid som si v databáze rádio staníc z celého sveta radio-browser.info všimol stanicu bible.is, ktorá vysiela čítané aj dramatizované texty z biblie v množstve jazykov.
Viem, silnejšie veriaci a ostatní, ktorí máte bibliu podrobnejšie naštudovanú určite toto poznáte, no mňa ohromilo takéto hnutie. Otvoril som si teda stránku bible.is a nestačil som sa čudovať. Majú texty a nahrávky biblie v nespočetnom množstve jazykov, perličkou je napr. biblia vo východoslovenskom - karpatskom dialekte rómštiny, kde dramatizovaná biblia bola nahrávaná v čechách a zverejnená v roku 2014. Slovenský preklad biblie z roku 1997, dramatizovaný ešte o niekoľko rokov neskôr je žiaľ len audio, teda nie je tak pri počúvaní tejto slovenskej dramatizovanej biblie možné zároveň to isté aj čítať očami, príp si kontrolovať verše podobne ako by sme listovali skutočnou tlačenou knihou ako je možné robiť s anglickým, českým alebo už spomínaným rómskym prekladom.
Nie je to teda len rádio v tradičnom zmysle slova s mobilnými aplikáciami, satelitným vysielaním, ale je to aj online knižnica textov a nahrávok.
Trošičku ma absencia slovenského prekladu v textovej podobe zamrzela, tak som si povedal, že si aspoň pozriem, čo všetko dokážem o tomto zistiť a odhadnem si len tak pre seba ako veľmi je pravdepodobné, že sa to časom zmení. Pochopil som to tak, že stránku bible.is prevádzkuje spoločenstvo viera počúvaní, ktoré zastrešuje nahrávky už preložených textov biblie v rôznych jazykoch.
Čo vedia robia sami, no bez spolupráce s lokálnymi organizáciami by to nešlo. U nás je takouto organizáciou slovenská biblická spoločnosť. Na stránke biblia.sk ponúkajú 6 rôznych prekladou biblie v textovej podobe a podľa tohoto článku zapadajú tiež do celkového kontextu projektu s nepredstaviteľnými rozmermi. Okrem nahrávok nového zákona z roku 1997 resp. 2001, ktorý môžeme počúvať aj na bible.is niekedy približne v roku 2014 dokončili nahrávanie starého zákona, vydávajú rôzne publikácie napr. bibliu vo zväčšenom písme pre ľudí s poruchami zraku, nedávno zverejnili video nahrávky pre sluchovo postihnutých v slovenskej posunkovej reči na adrese nepocujuci.biblia.sk.
 a tak som sa dopátral až k obsahovému mozgu nad týmto biblickým projektom, ktorý poháňa tzv. digital bible platform. Myslím si, že skôr či neskôr sa tam dostanú aj materiály, ktoré publikuje slovenská biblická spoločnosť.

No povedzte, nemá spolupráca na takto rozsiahlych projektoch súvisiacich s bibliou okrem duchovného rozmeru ešte aj spoločenský, filozofický a technický rozmer? Myslím si, že toto je dobrá myšlienka pre všetkých, ktorí podporujú dobrovoľnícke open-source, charitatívne alebo iné projekty, kde výsledkom je niečo, čo môžu všetci získať bezplatne a nezištne.

Peter Vágner

How to apply different paragraph styles in Libreoffice Writer

2 min read

Today I have spent some 20 minutes looking for a way how can I apply different paragraph styles in Libreoffice Writer by using keyboard exclusively.

 

Initially I was afraid It can’t be done however finally I have learned how to do it and here are the steps working for me:

 

  • Select text you want to style differently

  • Press ctrl+F11 to focus formatting toolbar

  • Use up and down arrows to choose your style. If you have found your choice press the enter key. If you haven’t found the suitable style choose the last option more styles...

  • Now the fun begins since this option ends with three dots I was expecting I can activate the selection somehow which should bring up a dialog of some sort. Pressing enter on this even in combination with other keys did nothing usefull. So to browse for more styles I have ditched looking at formatting toolbar, pressed F6 several times to jump to the sidebar. It is possible to use up and down arrow keys to move between parts of the UI here on the sidebar. Properties is the first item and Styles is the second one. So when you hear properties pannel, you should press down arrow key to change to styles. You can then press the tab key and become overwhelmed with loads of styles Libreoffice has to offer. I’m sure you can even write a book using these.

 

Peter Vágner

How to hack #Kodi screen reader addon into #LibreElec image

4 min read

In order to make this really work I had to do a few edits to this article. Last change has been made at 29th of december 2016.
Today I was asked by one of the online friends how to make LibreElec htpc software include Kodi screen reader addon.
First we had some disscussion in the IRC channel on freenode. We have found out adding Kodi screen reader into the official image is not likely to happen. We are still free to make our blindness specific spin though.
There are several things to overcome.
Rebuilding the whole LibreELEC image is an overkill we just would like to inject our addon.
The addon has a feature that will not start when it's preinstalled into system wide kodi addons directory so we have to patch the addon with a dirty change until a better solution is found.
And this is updated proof of concept tweak how we can hack Kodi screen reader into image of Raspberry pi 2 / Raspberry pi 3 build of Libre Elec.


# Create an empty directory where we will do our job
mkdir /tmp/libreelec
cd /tmp/libreelec/
# download libreelec image. You can get the Kripton or more up to date version but pay extra attention in that case
wget "http://ftp.belnet.be/libreelec.tv/LibreELEC-RPi2.arm-7.0.2.img.gz"
# unpack the downloaded archive
gunzip LibreELEC-RPi2.arm-7.0.2.img.gz
# inspect what partitions the unpacked image has
fdisk -lu LibreELEC-RPi2.arm-7.0.2.img
# Note the sector size of the image is 512 bytes, first partition starts at sector 2048 thus we need to setup a loop device starting at offset 2048*512
sudo losetup -o 1048576 /dev/loop0 LibreELEC-RPi2.arm-7.0.2.img
# create a temporary folder where we'll mount the unpacked image
mkdir image
sudo mount /dev/loop0 image
# unpack squashfs image to a current directory (has to be executed as root to preserve file permissions and ownership)
sudo unsquashfs image/SYSTEM
# Download current Kodi screen reader addon from one of the kodi.tv addon repository mirrors
wget "http://ftp.halifax.rwth-aachen.de/xbmc/addons/krypton/service.xbmc.tts/service.xbmc.tts-1.0.6.zip"
# Change to the directory where you can unpack Kodi screen reader addon
cd squashfs-root/usr/share/kodi/addons/
# unzip the Kodi screen reader addon (do it as root to fit within the rest of the target system image)
sudo unzip ../../../../../service.xbmc.tts-1.0.6.zip
# Patch the addon not to disable it-self on first run when it detects it's preinstalled
sudo sed 's/return os\.path\.exists(preInstalledPath)/return False \.path\.exists(preInstalledPath)/g' service.xbmc.tts/lib/util.py 1<> service.xbmc.tts/lib/util.py
# change back to the original working directory
cd ../../../../..
# If you have image including Kodi Kripton or possibly newer version, uncomment the next line to add our addon into the addon-manifest.xml
sudo xmlstarlet ed -L --subnode "/addons" -t elem -n "addon" -v "service.xbmc.tts" squashfs-root/usr/share/kodi/system/addon-manifest.xml || : # ignore error
# Recreate the squashfs SYSTEM image (again it's important to do that as root)
sudo mksquashfs squashfs-root SYSTEM -b 131072 -comp lzo -no-xattrs
# Create a md5 sum for your new squashfs image
md5sum SYSTEM > SYSTEM.md5
# now if you like you can compare size and features of both the images.
ls -l SYSTEM
ls -l image/SYSTEM
unsquashfs -s SYSTEM
unsquashfs -s image/SYSTEM
# Finally move your newly created SYSTEM and SYSTEM.md5 files into the proper place
sudo mv SYSTEM* image/
# unmount the image as we are done tampering with it
sudo umount image
# If you like just check the image if it has been really modified recently
ls -l LibreELEC-RPi2.arm-7.0.2.img
# Compress the image inplace as much as gzip allows
gzip -9 LibreELEC-RPi2.arm-7.0.2.img
# Flash / upload file for a friend and clean up your self please

Peter Vágner

Emacs A11y Tip #2: graphical or pure text console setup

4 min read

In my Emacs A11y Tip #1 I've already touched the topic of this #2 from slightly. I did not explore all the details at the time so I feel I should try to correct this now.
When installing Emacs there are various possible build configurations and some of them have been adopted as a defacto standards meaning analogous packages are available in the multiple linux distributions package repositories. These are emacs, emacs-nox and emacs-gtk2.

Guessing from the package names it's obvious -nox variant has all the graphical dependencies stripped out. That means we will only see text UI when running no matter if we are in a graphical X session or on a text only console. I was expecting full package would therefore be unnecessary for me because it brings in a few more dependencies and the window it presents is inaccessible to orca anyway. So given this reasoning I assumed it might have minimal impact and I won't need X support in my install of Emacs.

My complicated reasoning has proven not to be quite right and X support within emacs might really be usefull. I have found out a few differences between X and no X variants and some of them are serious enough for me to install X support.

  • When X support is installed, emacs kill and copy commands insert the text into the clipboard so it's possible to copy and paste from emacs into other applications and the other way round.
  • No X variant can be also running within a terminal emulator like gnome-terminal. It means you can use orca's flat review to examine its output.
  • When X support is installed Emacs creates its own window seperated from a terminal if emacs is started from a terminal emulator. It is completelly inaccessible to orca and it consumes all the keyboard input so orca even can't receive the insert / capslock key presses. It is possible to decide during runtime when X aware version of emacs is installed if we want / don't want X support. Run
    emacs -nw
    to start emacs with no X support.
  • Installation which also features X support can also be started in pure text only console. In such a case X support won't be used obviously. Emacs should otherwise be as functional as intended. I've found askubuntu answer supporting this argument. Some parts of Emacs appear to inherit native accessibility and I am not sure where this is coming from. For example pressing C-x C-f brings up find interface accessible with Speechd-el but pressing F10 shows up GTK2 based menu bar and activating Open... from the File menu pops up GTK2 native file chooser dialog.
  • emacs-gtk2 has X support and as an addition it also features mixture of its natural UI with some GTK2 based widgets. I don't know if there is something usefull for us here.

Given the fact there is no complete full browser inside Emacs, copy and paste is really essential. Additionally it is possible to configure Emacs to open web links in 3rd party apps so depending if you are in X or not you can configure to open these in Firefox or elinks directly.

There might be other notable differences when running emacs within X session or pure text console for example gpg agent setup or integration with other 3rd party tools. If I find it to be significant enough I will post a new tip.
I don't consider emacs with gtk+2 support particularly appealing just yet because it does not appear to be practical switching between operating system native and emacs specific screen reading app.

Update: Originally I have assumed graphical ATK accessible menu is only within emacs-gtk2, however it's also present in the original emacs with no GTK support. It sounds a bit dissapointing that we have no speechd-el accessible menu in this mode. But using keyboard shortcuts and other things is worth the trade I think.

Update2: Run

emacs -nw

if you would like to decide at runtime whether you do want an X support or not.

Peter Vágner

Emacs A11y Tip #1: Introduction and how to install

5 min read

Emacs is a powerfull software. There are a few access solutions that enable blind or visually disabled people to make some good use of it.
Unfortunatelly getting used to it requires a bit more than launching, testing and using it.

I don't think I can write better documentation than Emacs tourEmacs documentation either available online or built into emacs it-self. However I'll try to post a few so called getting my-self and hopefully someone else ready to make the most of it.

Why emacs?

Because it's more than a text editor. It can run on almost anything, it's keyboard driven since its start, it's still being maintained, there is a huge community of emacs users.

What access solution?

I've chosen Speechd-el for now because it concentrates on what it has been designed for and is known for overriding as little emacs built-in stuff as possible. Hopefully I'll be able to borrow from other general and community provided tips later on as I discover them. Here's a discussion thread that inspired me. And the F123E initiative made me to start writing this series of posts.

Where and how to install it?

I've chosen Arch linux as my operating system of choice a few years ago because of its philosophy, its rolling release cycle so there is no need for a reinstall every so often and awesome but easily embraced packaging system that encourages creating own packages almost every time while installing something new avoiding dependency issues or other conflicts and any other kind of possible mess in general.

Installing is just a breeze. Emacs it-self can be installed from the Arch community repository by typing
sudo pacman -S emacs
Originally I've opted for nox package variant so I can run it on the text only console and I can be assured I won't turn into issues with graphics. I am now reconsidering that because it appears it would be nice to able to copy and paste between emacs and Firefox for example in the future.

Speechd-el has some hard dependencies. It's developed to speak by using speech-dispatcher. Except of speech-dispatcher, I need to install speech-dispatcher supported TTS engine. I'm using eSpeak with other screen reading apps so I'll just make sure both speech-dispatcher and eSpeak are installed at this point.
sudo pacman -S speech-dispatcher espeak
If you are already running orca on linux you should skip installation of these two as it's sure you do already have them working.
You can test if speech-dispatcher is working by typing in
spd-say hello

Speechd-el can be installed from the AUR.
cd /tmp
wget https://aur.archlinux.org/cgit/aur.git/snapshot/emacs-speechd-el-git.tar.gz
tar xvzf emacs-speechd-el-git.tar.gz
cd emacs-speechd-el-git
makepkg -s
sudo pacman -U emacs-speechd-el-git-<version>-1-any.pkg.tar.xz
All the above commands should be typed one at a time exactly as written except of the last one. In that last one you will have to find out the proper filename of the package you've just built.

How to activate it?

There is a file called .emacs you can put into your home directory to instruct emacs to do something while it's starting.
For now I won't be looking at if this is the proper emacs way of doing things because I am just at the beginning. My immediate goal is getting my current tools of choice working. So here are a few lines I have saved into my ~/.emacs file:
(setq speechd-out-active-drivers '(ssip ))
(autoload 'speechd-speak
"speechd-speak" nil t)
(speechd-speak)

What to do on the first run?

Now you can run
emacs
and it should start talking.

 

Emacs will display some introductory text in the default buffer. Buffer is kind of technical term however in the Emacs terminology it means a document open in the editor or otherwise generated content forming a document we can interact with.

To describe some commands we can use at this point we have to know that Emacs has implemented a lot of keyboard shortcuts and keyboard shortcuts configuration is layered. There are single key shortcuts multiple keys shortcuts or even shortcuts that consist of multiple keypresses one after the other.

When describing keyboard shortcuts a lot of keypresses are ordinary keys such as letters combined with either control / ctrl refferred to as C or meta / alt often reffered to as M . Other Emacs keynames include previous and next for page up / page down respectivelly, spc for space and esc for escape. Ofcourse there may be more.

Here are some command keys you can use to navigate over the text at this point:

  • C-f - next character
  • C-b - previous character
  • M-f - next word
  • M-b - previous word
  • C-p - previous line
  • C-n - next line
  • C-a - start of a line
  • C-e C-e - end of a line - yes this is overridden from a standard emacs install by Speechd-el. Emacspeak does the same thing as far as I know.
  • M-a - previous sentence
  • M-e - next sentence
  • M-less than symbol - begining of a buffer
  • M-greater than symbol - end of a buffer
  • F10 - menu bar
  • M-` (meta and back tick) - another way of showing the menu bar
  • C-H t - Emacs tutorial
  • C-x k - kill / close a buffer
  • C-e d l lang - change speech-dispatcher language within speechd-el. lang is abbreviation of your language code such as en, sk, cs, ru, de, fr, pt and similar.
  • C-x C-c - exit emacs

Summary

 

If you haven't managed to get Emacs with Speechd-el running go through this post, try out the commands and follow the Emacs tutorial.

 

What if I am using Emacspeak?

 

Please see this excelent guide by Alex Midence as an addition to this.