Tuesday, June 3, 2025

LineageOS and Galaxy Tab 4 (SM-T530)

Motivation

I recently got an old Samsung Galaxy Tab 4, aka SM-T530, code name Matisse -- I will call it SM-T530 in the following. It's a 10,1" Android Tablet with a 1,2 GHz Snapdragon ARM processor. Old means: from 2014. It has Android 5.0.2 installed. The problem about that is twofold: No security updates for a long time (which you may ignore if you use it only internally) and, even worse: No Google Playstore!

The 10" display is quite nice and the tablet is quite light. So I thought that it may be perfect for reading ebooks. Since the Google Playstore is not available for Android 5 anymore and the apps I needed (to access ebooks from my public library) are only available there, I needed to update the device somehow.

Luckily, there exists an unofficial version of Lineage for the SM-T530. The latest version is Lineage 20.0 provided by reitredtab via the xdaforums. The posts are quite scaring: "If you are NOT an expert in using fastboot, adb, odin, heimdall, twrp, DO NOT use this rom.". Well, I'm not an expert in these tools, but it is also not too complicated -- once you know which versions to use and how to fix the problems. And then (at least in my case): I did not care whether I brick the device, as it is pretty useless with Android 5 anyway.

Installation Process

I am not responsible for lost data, identity theft, lost money, security vulnerabilities, bricked devices or any other hardware or software malfunctions that comes as a result of flashing this rom.

Download required software
Install Software to Flash Firmware on Windows machine

Since heimdall, an open source cross-platform tool to flash the firmware, is not available as binary (anymore) and fastboot is not available for the SM-T530, we need the original Odin software. Download from https://xdaforums.com/t/patched-odin-3-13-1.3762572 the two files Odin3 v3.14.1.zip and Odin3 v3.14.1_3B_PatcheD.zip. Extract both, copy patched version to original folder, we will use the patched version later on.

Prepare Android Packages on microSD card

The easiest way to later install Lineage 20.0 and the MindTheGapps tools is to download them and store them on a micro SD card which we will plug in the device later on.

We use Lineage 20.0 provided by reitredtab. At the time writing this, the latest version available is lineage-20.0-20250518-UNOFFICIAL-matissewifi.zip which we can download from https://sourceforge.net/projects/retiredtab/files/SM-T530NU/20/.

Download MindTheGapps-13.0.0-arm-20231025_200806.zip from https://github.com/MindTheGapps/13.0.0-arm/releases/tag/MindTheGapps-13.0.0-arm-20231025_200806. Unfortunately this package has a minor problem when installing on old devices as explained at the MindTheGapps_Legacy GitHub project. Thus we patch the package as explained above, i.e. unzip original package, change the one line in file META-INF/com/google/android/update-binary and create new zip.

Download TWPR (on Windows machine)

In order to install the android packages listed above, we need TWRP (Team Win Recovery Project). This replaces the original recovery software. The SM-T530 is not officially supported anymore, we can onl find old repositories. Fortunately, there is a binary twrp-3.5.2_9-0-matisse.tar of version 3.5.9 available.

Install Software

Before we start, we need to know how to start the device in two special modes. When device is off, press three buttons simultaneously when starting the device to activate special mode:

  • Download Mode: Home + Volume Down (-) + Power On
  • Recovery Mode: Home + Volume Up (+) + Power On
Note: In some howtos, you need to activate the "Developer Options":
  • Go to "Settings/General/About device"
  • Tap “Build number” seven times. ...
AFAIK this is only required if you want to upload files via adp(The Android Debug Bridge).
Install TWPR via Odin
First we need to install TWPR via Odin. Start the device in download mode and attach it via USB to your windows machine. Start Odin (the patched version). In the log, your device should be logged as "added". Select the afore mentioned TWPR file twrp-3.5.2_9-0-matisse.tar as BL (Boot loader) and install the TWPR bootloader via Start. Once the software is uploaded, Oding shows "PASS".
Install Lineage OS and MindTheGapps
Start the device in recovery mode. Now, TWPR is started. You may create a backup of the current stock os via TWPR. Then, format/wipe the device (advanced formatting) and reboot in recovery mode again. Now, select Install and select the lineage package lineage-20.0-20250518-UNOFFICIAL-matissewifi.zip and your patched version of MindTheGapps-13.0.0-arm-20231025_200806.zip. Start the installation. That's it :-)

Resumee

It works. That's great. And it is slow (as expected). But it works. I'm able to read PDFs with DRM from my public library with PocketBook. Not as smooth as on a new tablet, but it works. I do not comment here on Samsung and all the other companies about sustainability...

Sunday, February 9, 2014

UPS for Raspberry Pi

As described in the previous post, I'm using the Raspberry Pi as a server for my calender and addressbook data. It is directly connected to my WLan station, and I want to be able to simply shutdown both devices by simply switching off power. Simply switching off power is not the best idea for a Linux system. That is, the preferred way is to neatly shutdown the system before. Since I do not want to start a terminal application before in order to shutdown the Pi properly, I found a different solution: CW2's Pi USV (USV is german for UPS). It is a battery powered UPS, which comes with a nice software package for Pi's Debian Linux. The UPS and the software shutdown the system when the USB power supply is switched off. This is exactly what I needed.

Installation is rather easy. On piusv.de you find a short movie demoing the device, along with some PDFs of how to connect the hardware and set up the software (there are english manuals, even though the web page is in german language only).

I have a case for my Pi, and in order to be able to use that case with the UPS, I had to cut three holes as shown in the picture. The installation of the hardware is nicely documented in CW2's manuals.

Software

CW2 UPS comes with nice software, which monitors the power and automatically shutdown the system if the USB power is switched off. The software comes as a Debian package, and the installation sets up everything -- usually you do not need to manually adjust things.

This is how I installed the software on command line (as I have no monitor attached to my Pi, I always connect via ssh):

Download piusvmonitor software on command line via wget:

wget http://www.piusv.de/support/piusvmonitor.deb

Install piusvmonitor as super user:

sudo dpkg --install piusvmonitor.deb

After installation, you will find a shell script

piusvautostart
in /etc/init.d for starting the piusmonitor automatically. After installation, the software is automatically started. The monitor actually is a service, running in the background.

Configuration and log files are found in

/usr/share/piusvmonitor

Check functionality:

tail -f /usr/share/piusvmonitor/log.piusv
Initially:
Sun Feb  9 12:21:38 2014
PRI_POW 
Now, remove one battery as shown on the demo on pisv.de: This will be shown in the log:
Sun Feb  9 12:21:39 2014
PRI_POW BAT_LOW 
Sun Feb  9 12:21:39 2014
PRI_POW BAT_LOW
Now, put battery back:
Sun Feb  9 12:21:53 2014
PRI_POW 
Sun Feb  9 12:21:53 2014
PRI_POW 
Eventually, try the shutdown by removing the USB power supply:
Sun Feb  9 12:22:02 2014
SEC_POW BAT_LOW 
Sun Feb  9 12:22:02 2014
SEC_POW BAT_LOW 
Sun Feb  9 12:22:12 2014
 PIUSV shutdown
Sun Feb  9 12:22:12 2014
 PIUSV shutdown
Sun Feb  9 12:22:16 2014
SEC_POW BAT_LOW 
Connection to xxx.xxx.xxx.xxx closed by remote host.
Connection to xxx.xxx.xxx.xxx closed.    
The last two lines a due to the ssh connection, of course. After rebooting and reconnecting to the PI, the piusv software is started automatically:
Sun Feb  9 12:22:28 2014
PRI_POW 
Sun Feb  9 12:28:20 2014
PRI_POW BAT_LOW 
Sun Feb  9 12:28:21 2014
PRI_POW 

Summary

The CW2 UPS is a nice little device, and the software is working great. Unfortunately the common Rasperry Pi case does not really fit. Most of all, it would be nice to have a real connector for the battery package instead of the press-stud connection. The CW2 UPS costs about 30€ and can be ordered irectly from CW2. Additionally, you need batteries, of course. Note that the UPS does not automatically charge the batteries, so there is still some "manual" maintenance necessary.

Sunday, January 12, 2014

Raspberry Pi and ownCloud: Calendar and contact synchronization without Apple or Google

The probably badest news about Mac OS X Maverick is that the synchronization services were removed, thus disabling tools like Missing Sync to work. I used Missing Sync to synchronize calendar and contacts between my MacBook and Android phone. Since I do not want to use Google, I had to find another solution.
My new solution is a combination of the following things:
  • Raspberry Pi
  • ownCloud
  • CalDav- and CardDav-Sync for Android
I have a Raspberry Pi running ownCloud connected to my Airport Extreme via Ethernet cable (as it is directly placed near to the Airport). It has a static IP, so that it is easy to find in my local network. For security reasons it is only available in my local network: I don't need global access to my few contact and calendar data, as it is sufficient to sync the data when I (and my Android and MacBook) are at home. ownCloud is a little cloud solution, providing WebDav, CalDav and CardDav services. These services are used to sync the data similar to Google or Apple.
Why a Raspberry Pi?
For security reasons, I didn't want to use a (virtual) server publicly available on the internet. I simply do not have the time to constantly update a server for fixing security issues. Also, setting up a server in the cloud is not that much different from using Google, is it? Since the server needs to be accessible to the Android device, a static IP address is very convenient. I could have installed ownCloud on my MacBook directly, and assigning the book a static IP address (or reserve a specific DSCP IP address to the MacBook), however with the Pi I can use the server not only for me but also for roommates ;-) And then, for a geek a real local server is simply a must, isn't it?

Setup Raspberry Pi and ownCloud

Installation if this set up was pretty easy:
  1. Buy a Raspberry Pi along with an USB power supply, an SDHC card, and a little case and maybe little cooling elements
  2. Format SDHC card (luckily my MacBook has an SD card slot) via SD Formatter for Mac (https://www.sdcard.org)
  3. Install Rasbian via Noobs (http://www.raspberrypi.org)
    1. follow readme instruction foud in Noobs zip
    2. install Rasbian via Noobs, enable SSH via menu
    3. set up static IP address (e.g., see https://thepihut.com/blogs/raspberry-pi-tutorials/)
    4. while 3.1-3.3 needed the Pi to be connected to a monitor, once the static IP address is configured, the following steps can be applied via ssh.
  4. Install ownCloud (https://owncloud.com), following the tutorial at http://www.connect.de (german only).
    Minor adjustment: The SSL configuration file has to have newlines, that is, use this template:
    <virtualhost>
    SSLEngine On
    SSLCertificateFile /etc/apache2/ssl/apache.pem
    DocumentRoot /var/www
    </virtualhost>

Set up clients

Now, configure ownCloud, that is, set up initial admin user and create a new user via the web interface.
There is not much magic to configuring CalDav and CardDav to the OS X apps (in the apps, select preferences and add your own server using the static IP address and the configured user).
There may be some trouble setting up CardDav. For El Capitan, add a new CardDav account, manual setup, and use the following server address:
https://SERVER/owncloud/remote.php/dav/principles/users/USERNAME



For initial import of the calendar entries, export your calendar to a file. This file is then uploaded via drag'n drop to ownCloud and imported there via click (only click once, this might take a while).
The last point has been a little bit tricky, as I had to create a temporary folder manually in order make it work. This is how I did it:
cd /var/www/apps/calendar/
sudo mkdir import_tmp
sudo chown www-data:www-data import_tmp
Android Apps
I'm using the following Android apps now (instead of the Missing Sync software with Fliq Calendar, which I never really liked):
(Thank you Marcus for pointing me to these apps!)

Thursday, October 6, 2011

Latex listings definitions for modeling languages

Seems as if the Latex listings package does not let me go...

After blogging about how to nicely format listing with the Latex listings package, using a Eclipse syntax coloring style, and solving some tiny yet annoying problems with hyphenations of inline listings and labels within listings, I have compiled a couple of language definitions for (Eclipse) modeling languages.

Actually, these definitions are rather small, as they basically contain a list of keywords of a language. Besides the language definition, I usually define a command for quickly writing some inline listing code. I have explained this command in an earlier blog posting.

So, here are the definitions for QVT, ATL, ETL, Xtend, and Xtext.

QVT -- Query, View, Transformations

\lstdefinelanguage{QVT}{
  morekeywords={
% relations:  
   checkonly, domain, enforce, extends, implementedby, import, 
  key, overrides, primitive, query, relation, top, 
  transformation, when, where
% operational: 
 Bag, Collection, Dict, OrderedSet, Sequence, Set, Tuple, abstract, 
access, and, any, assert, blackbox, break, case, class, collect, 
collectNested, collectOne, collectselect, collectselectOne, 
composes, compute, configuration, constructor, continue, datatype, 
default, derived, disjuncts, do, elif, else, end, endif, 
enum, except, exists, extends, exception, false, forAll, forEach , 
forOne, from, helper, if, implies, import , in, inherits, init, 
inout, intermediate, invresolve, invresolveIn, invresolveone, 
invresolveoneIn , isUnique, iterate, late, let, library, literal, 
log, main, map, mapping, merges, metamodel, modeltype, new, not, 
null, object, one, or, ordered, out, package, population, primitive, property, 
query, raise, readonly, references, refines, reject, resolve, resolveIn, resolveone, 
resolveoneIn, return, select, selectOne, sortedBy, static, 
switch, tag, then, transformation, true, try, typedef, unlimited, 
uses, var, when, where, while, with, xcollect , xmap, xor, xselect 
 },
 keywordstyle=[2]{\textbf},
 morecomment=[l]{--},
 morestring=[b]{'},
 tabsize=4}
 
\newcommand{\lstQVT}[1]{\lstinline[language=QVT,breaklines=true,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]§#1§}

ATL -- Atlas Transformation Language

\lstdefinelanguage{ATL}{
  morekeywords={true,false,
   Bag,Set,OrderedSet,Sequence,Tuple,Integer,Real,Boolean,String,TupleType,
  not,and,or,xor,implies,module,create,from,uses,helper,def,context,
  rule,using,derived,to,mapsTo,distinct,
  foreach,in,do,if,then,else,endif,let,
  library,query,for,div,refining,entrypoint},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{--},
 morestring=[b]{'},
 tabsize=4}
 
\newcommand{\lstATL}[1]{\lstinline[language=ATL,breaklines=true,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]§#1§}

ETL -- Epsilon Transformation Language

\lstdefinelanguage{ETL}{
  morekeywords={true,false,
   pre, rule, operation, 
  var, transform,to,
  select, selectOne, all,
  @greedy,
  for,if,else,
  not,and,or,
  Any,String,Boolean,
  true,false,return},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{//}, 
 morecomment=[s]{/*}{*/}, 
 morestring=[b]",
 tabsize=4}
 
\newcommand{\lstETL}[1]{\lstinline[language=ETL,breaklines=true,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]§#1§}


Xtend 1.0.1

\lstdefinelanguage{Xtend}{
 morekeywords={cached,case,default,extension,false,import,JAVA,WORKFLOWSLOT,let,new,null,private,create,switch,this,true,reexport,around,if,then,else,context},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{//}, 
 morecomment=[s]{/*}{*/}, 
 morestring=[b]",
 tabsize=4}
 
\newcommand{\lstXtend}[1]{\lstinline[breaklines=true,language=Xtend,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]\S#1\S}

Xtext 1.0.1

\lstdefinelanguage{Xtext}{
 morekeywords={grammar, with, hidden, generate, as, import, returns, current, terminal, enum},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{//}, 
 morecomment=[s]{/*}{*/}, 
 morestring=[b]",
 tabsize=4}
 
\newcommand{\lstXtext}[1]{\lstinline[breaklines=true,language=Xtext,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]\S#1\S}

If you need a new language definition for your own Xtext based modeling or programming or domain specific or whatever language, it is very easy to retrieve the tokens of the language. Within the project of your Xtext grammar file, a special ANTLR file containing all the tokens will be generated. You will find that file in
src-gen//parser/antlr/internal/Internal.tokens

Xpand

[Updated February 2012] A friend of mine (thank you, Jens!) just sent me a new definition for Xpand:
\lstdefinelanguage{Xpand}{
 morekeywords={IMPORT, DEFINE, ENDDEFINE, LET, ENDLET, FOR, FILE, ENDFILE, ITERATOR, FOREACH, AS, IF, ENDFOREACH, ENDIF, EXPAND, INSTANCEOF, USING, SEPARATOR, CSTART, CEND, PROTECT, ENDPROTECT, ID, EXTENSION, ERROR, WARNING, INFO},
 inputencoding=latin1,
 extendedchars=true,
 % note: first and last guillemot of comments will not appear in comment style, guillemots are not possible in delimiters
 morecomment=[s]{REM}{ENDREM},
 morestring=[s]{"}{"},
 % for use with UTF-8
 literate={«}{\guillemotleft}{1}
          {»}{\guillemotright}{1}
}
This definition is a slight modification of the definitions posted in the Eclipse M2T forum (and also at the Rtsys Group Wiki, Uni Kiel) a while ago.

Saturday, July 23, 2011

Pimp your Kindle

I really like the idea of ebooks. These E Inks displays have an astonishing quality: I was very surprised to be even able to read a Din A4 PDF, downsized to fit the 6 inch display of a Kindle---although it is hard to read.

So, as I like the idea, I bought an ebook reader. I decided to buy Amazon's Kindle reader, as there are a lot of ebooks available thanks to Amazon. While I'm still enthusiastic about the really good display, I'm completely disappointed in the Kindle software. Most of all, ebooks are always displayed using justified text. But since hyphenation is not supported, this leads to really ugly layouts. The combination of justified text without hyphenation is a show-stopper!

So, I tried to figure out a solution to that problem. Fortunately, I found a Kindle version of the FBReader (fbkindle), which is not too complicated to be installed on the Kindle. FBReader displays ebooks in epubs format, and it provides hyphenation as known from TeX. Really nice! This blog entry summarizes the necessary steps along with a short presentation of additional tips.

Motivation


Before explaining the necessary steps to install FBReader, I just want to show you the differences between the original Kindle AZW reader and the FBReader.


Figure 1: Comparison of original Kindle AZW reader (left) and FBKindle epub reader (right)

Figure 1 shows two scans of the Kindle. I have used Melville's Moby Dick (free Amazon vs. Feedbooks version). It is freely available, not only at Amazon but also at some other ebook sites, and besides it is one book I always wanted to read. While some of the differences stem from the information stored in the ebooks themselves, other things are only (missing) features of the reader software. However, in my experience, the example is rather a typical one: I've found much worse (free) ebooks, and also slightly better ones. Let's go into the details:

The first obvious thing is hyphenation. As said above, the Kindle cannot hyphenate, which is a real problem due to the justified text layout used. The worst thing about that is, that it sometimes produces pseudo paragraphs, as you can see in the circle marked with "1a" (and also in the second line of the following chapter). FBReader supports hyphenation (circle marked "1b"). This is a software problem and no missing feature of the ebook. That is: No AZW ebook will support hyphenation, at least not with the current Kindle reader software.

The other differences stem from the ebooks themselves. As the headings demonstrate ("2a" vs. "2b"), the AZW book does not correctly layout the heading. That is, the title of the heading is formatted as plain text. While this is only ugly, I have found free AZW books with footnotes inserted into the plain text without anything indicating the footnote (the free version of Hegel's Logik). An even worse problem is, that some books do not come with no table of contents, and no chapter markers. As indicated with the "3a", the AZW version of Moby Dick does not provide any chapter markers, while the EPUB version does ("3b"). Actually, with out these markers and TOC, an ebook like Moby Dick is not usable at all. Sometime, it is possible to generate TOCs with tools such as Calibre, but, hey guys, I want to read a book, not create and fix it.

While the FBReader provides a much better layout, I really miss one feature the Kindle reader software provides: dictionary integration. This is a really cool feature, and although is is listed as a planned feature for FBReader, is is not implemented yet. At the moment, I'm using my Android's ColorDict to help me out, just as I used to do when reading books printed on paper. Weird! The dictionary coming with Kindle is an english dictionary, and I have installed a free german-english dictionary, as explained below.

Overview



Figure 2: Kindle root folder after installing 3rd-party software



Figure 2 shows my Kindle root folder, with some subfolder created by the software described below. It contains a folder with the collections database and some configuration files of the Kindle AZW reader (1), as well as your content (2). All third-party software is installed on the Kindle by first mounting the Kindle to your PC or Mac, and then by copying some installation file into the mounted root folder (0) (sometimes, this folder is referred to as "/mount/us", on MAc OS X, it is the root folder when you mount your Kindle). Then, the Kindle needs to be rebooted, and when starting up, the software is installed automatically (and the installer is removed). The installer usually creates a folder in the Kindle's root folder.

Frankly, I really hate to install hacks on the Kindle. So, please Amazon, improve your Kindle software! The hardware is really cool, but the software is rotten! Meanwhile, here's how to install alternative software. Frankly, this is not the first list, and you will find similar lists on the web. One of the best places is the mobileread.com forum, and a list of hacks can be found there as well.

The quick installation should only serve as a short guide, please read the documentation linked to before installing anything. You may lose warranty when applying the hacks described below, or you may break your Kindle. Use it on your own risk!

"Jailbreak" for Kindle


A small "security" feature built into the original Kindle software prevents arbitrary 3rd-party software to be installed. So, we first need a special piece of software, to work around this issue. This is the "jailbreak". There exists different software versions of the original Kindle software, and they require different software hacks as well. The Kindle (at the time writing this post) comes with version 3.1. Yifan Lu has published a jailbreak for that version:

Download
Yifan Lu's website: Kindle 3.1 Jailbreak
Quick install
  1. Unpack kindle-jailbreak.zip
  2. Copy installer update_jailbreak_*_*_install matching your kindle version into Kindle's root folder (Fig. 2 (0))
  3. Restart Kindle (Home, Menu - Settings, Menu - Restart
Documentation
See download location.


The ad-base Kindle is not that easy to jailbreak, and frankly: if you choose to save that little money and accept ads, then do not complain about the original software. However, according to Yifan Lu, some non-ad Kindles also come with the new 3.2.1 software, so here's the link on how to jailbreak this version as well (I didn't try it myself): Yifan Lu: Kindle 3.2.1 Jailbreak (also see thread at mobilreader).

Launchpad


In order to be able to start 3rd-party software, you need some launcher software (as there is no command line available by default). Launchpad is a small utility, which enables the user to execute commands after pressing a defined sequence of keys, as demonstrated on this Youtube video.. Launchpad is available via the mobileread.com forum:
Download
http://www.mobileread.com/forums/showthread.php?t=97636
Quick install
  1. Download and unpack lpad-pkg-001c.zip
  2. Copy installer update_launchpad_*_*_install.bin matching your kindle version into Kindle's root folder (Fig. 2 (0))
  3. Restart Kindle (Home, Menu - Settings, Menu - Restart
Documentation
See download location.

After successfully installing launchpad, a new subfolder should have been created in your Kindle's root folder, as shown in Figure 2 (3). Inside that folder, you will find the configuration files *.ini with defined key sequences and commands to be executed. Note that you always have to press Shift before the defined key sequences, and that you have to press all keys one after the other and not all at the same time.

FBReader (FBKindle)


Now we are ready to install FBReader, in order to be able to read DRM-free EPUB books on your Kindle. There exist two versions: FBReader by Dzha and FBKindle by Andy Wooden. I have chosen FBKindle , as it runs vis-a-vis with the original Kindle reader software, and one can easily switch between both version using a keyboard shortcut. Both versions are ports of the original C++ FBReader software. Unfortunately, this version has not been updated for quite some time, especially because nice things such as dictionary integration are still missing. Note: There also exists a sourceforge project called FBKindle, unfortunately it does not contain any files yet.

Download
http://www.mobileread.com/forums/showthread.php?t=107371
Quick install
  1. Download and copy fbKindle-bin.tar.gz into Kindle's root folder (Fig. 2 (0))
  2. Add the following lines to your launchpad/launchpad.ini file (or create launchpad/fbreader.ini containing these line):
    [Actions]
    F R = !/mnt/us/fbKindle/goqt.sh FBReader &
    U T = !cd /mnt/us; tar zxvf fbKindle-bin.tar.gz; rm fbKindle-bin.tar.gz;echo 101 >/proc/eink_fb/update_display
  3. Restart Kindle (Home, Menu - Settings, Menu - Restart) in order to activate new key sequences


  4. Activate FBKindle installation key-sequence, i.e. quickly press Shift, then U, and then T. This will unpack the FBKindle archive, and install FBReader in a subfolder fbKindle on your Kindle, as shown in Fig. 2 (4)


  5. Now, start FBKindle via Shift, then F, and then R. Actually, you will have to restart FBKindle every time after restarting your Kindle!


Documentation
See download location,german guide at e-reader-forum.de.
Unfortunately, the library management of FBReader/FBKindle is as bad as the the management functions of the original Kindle software. Seriously, I'm wondering how Amazon (or in that case the FBReader programmers) expects user's to install and manage more than 20 books. Anyways, the menu button will activate the FBReader menu, and from there on it should be self explaining (shortcuts are documented on the pages linked to above). The nice thing about FBKindle is, that you can easily switch forth and back between FBReader and the original Kindle software by pressing shift and alt simultaneously.

Free dictionaries for the Kindle software

Back to the original Kindle software. A really nice feature of the Kindle reader is that is comes with integrated dictionary support. Since I usually need english to german translations, I was looking for an english-german dictionary. There exists a lot of free dictionaries, and I found a free solution for the Kindle as well. Michael Sheldon (kudos to Michael) has converted free dictionaries into the mobi-format, which is supported by Kindle.
Download
http://mikeasoft.com/~mike/kindle-dicts/
Quick install
  1. Download dictionary file, e.g., English-German.mobi, and place it inside your documents folder
  2. Select this dictionary as your primary dictionary via menu - Settings, menu - Change Primary Dictionary
Documentation
Michael Sheldon's blog

Custom Screensaver

Not really necessary, but nice to have: screensaver with your own pictures. I really do not understand why Amazon does not directly support that feature. So, you have to firstly install a 3rd party screensaver hack. Then, you can copy your own pictures into a folder of the screensaver software.
Download
http://www.mobileread.com/forums/showthread.php?t=97636
Quick install
  1. Download and unpack kindle-ss-0.22.N.zip
  2. Copy installer update_ss_0.22.N_*_install.bin matching your kindle version into Kindle's root folder (Fig. 2 (0))
  3. Restart Kindle (Home, Menu - Settings, Menu - Restart
  4. Installer should have created a folder linkss, as shown in Figure 2 (5). Copy your images (600x800 pixels) into the created folder linkss/screensavers.
  5. Restart Kindle (Home, Menu - Settings, Menu - Restart) in order to activate new images.
Documentation
See download location.

Wednesday, May 11, 2011

Fun with Multiple VPN Connections on Mac OS X

Disclaimer: Frankly, I'm neither a Unix nerd nor a network freak. Maybe this is why I prefer using Mac OS X: In most cases things are simply working, or at least some nice graphical interfaces guides me through the network configuration jungle. So, use my tips on your own risk and feel free to write me a comment, if you can explain things better :-)

Virtual private network (VPN) are one of these things making me nervous without a nice GUI. Fortunately, OS X directly supports all the protocols I need (and thank you, Apple, for supporting the Cisco protocol as of OS X version 10.6). Setting up a VPN is as simple as installing a printer. Maybe even simplier ;-)

However, there are always new problems challenges waiting, and one of these challenges is the use of multiple VPNs simultaneously. I have the following situation: I can only connect to some local network, which does not allow any internet connections. For that purpose, I have to use a VPN "T" -- the VPN server "TServer" (names are only for simplify reading) is more or less the only thing accessible from that internal network. So, every connection to the internet runs through this VPN.

Now, I have to connect to a server "S", which only accepts connections from a local network, I call it "FNet". And my VPN server "TServer" is not part of this network "FNet". In order to access this server, I usually start another VPN "F" (with another VPN-server "FServ", virtually placing me (and my machine's IP address) inside the local network "FNet". Unfortunately, I can only connect to "FServ" via the first VPN. So, the question is, how to set up the second VPN?

Fortunately, it is possible to simply connect to two VPNs simultaneously. All you need to do is simply to configure both VPNs in your network settings.
Fig. 1:Simultaneously connect to multiple VPNs
I can then firstly connect to the VPN "T", and when this connection is establish I can use it to connect to the second VPN "F". Figure 1 shows the VPN menu in the system menu bar (OS 10.6, with elder versions, things look a bit different, as explained here).

Well, this is the easy part. The harder part is to tell the applications which VPN to use. This problem is (almost) the same problem as using different network interfaces (e.g., use the Ethernet connection for some tasks, and a WLan connection for others), as the VPNs create virtual network interfaces. So, it's time to start the console... ifconfig prints out the available network interfaces. E.g., my first VPN "T" has created a new interface called ppp0:

ppp0: flags=8051 mtu 1444
 inet 111.123.123.144 --> 111.123.123.166 netmask 0xffff0000

It is not that important to know exactly what you see here. The only important thing is the number 111.123.123.144 which is the IP-address assigned to my machine for VPN "T".

After connecting to the second VPN "F", another interface is available, representing the second VPN:

utun0: flags=8051 mtu 1280
 inet 222.123.123.155 --> 222.123.123.177 netmask 0xffffff00

Within this second VPN, I've got the IP 222.123.123.155.

So, I have two interfaces and two IP addresses, one for each VPN. This information can be used to tell applications to connect via one specific VPN.

In my case, I want to make an SSH connection to the server "S", which is only possible from within "FNet", that is, using the second VPN "F". Fortunately, I can tell ssh to use a certain IP address on my local machine. Let's assume 222.123.144.144 to be the IP address of the server S. This is how to connect to "S" via the second VPN "F":

>ssh -b 222.123.123.155 -l theUser 222.123.144.144

in which "theUser" the user login for "S". 222.123.123.155 is the IP of my machine within FNet (as F virtually places my machine in FNet). Note that you have to use the IP address rather then the name of the server (maybe some geek can tell me how to "update" the DNS stuff accordingly).

Other applications cannot be configured that easily, in these cases you have to add routing entries to your route table. E.g., instead of using the "-b" option of ssh, I could have added a new route (I found that tip here). To add a route, I need to be a super user, so we have to use sudo:

>sudo add route 222.123.144.144 222.123.123.155

Now, I can directly connect to S without the "-b" option:

>ssh -l theUser 222.123.144.144

Don't forget to delete the route when no longer needed:

>sudo delete route 222.123.144.144 222.123.123.155

Thursday, November 18, 2010

Problems with TortoiseSVN and authentication (on WinXP)

Newer versions of TortoiseSVN may produce errors when repositories reside on servers with unknown (untrusted, whatever) certificates. The very same repositories may be checked out and updated using a command line version (or with Mac tools). The error message may be a little too short and doesn't explain very much:
Update
OPTIONS of 'https://my.server.com/my/repository': SSL 
negotiation failed: Secure connection truncated (https://my.server.com)
Finished!
In order to fix this, you will have to change the underlying method of subversion/Tortoise for communicating with the server. This has to be specified in the server settings. This is a simple text file, hidden somewhere on your system. The easiest way of locating this file is by opening the Tortoise Settings and edit the "Subversion configuration file" (found under "General"). However, this only opens the "config" file, but what we need is the "server" file -- which luckily can be found in the very same folder as the "config" file. On my german Windows XP installation, its path is C:\Dokumente und Einstellungen\userid\Anwendungsdaten\Subversion\server. In "server" (pay attention to not accidentally add a ".txt" when saving the file), add a new server group in the group section, and set the http-library to "serf" for that group. E.g.,
[groups]
myserver = my.server.com

[myserver]
http-library = serf
Now, TortoiseSVN should work with your server.

P.S.: I found the solution at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=507374 (although I have no debian system, it solved my problem, so thank for the tip, Peter Samuelson) ;-). I adapted the solution for TortoiseSVN, as it fixes the problem with TortoiseSVN, and most TortoiseSVN forums suggest to downgrade to elder TortoiseSVN versions, which didn't worked in my case.


Tuesday, September 21, 2010

Mount Samsung GT-i5800 as an USB Drive

Today I wanted to sync some of my music files with my new GT-i5800. Unfortunately, it didn't worked with MissingSync via Wi-Fi, so I tried USB. Well, how do I mount my GT-i5800 as a USB drive on OS X? By default, USB settings are "Samsung Kies", which I do not need on OS X (and with MissingSync). This setting has to be changed to "Mass storage" before connecting the USB cable!
Settings > About phone > USB settings > (X) Mass storage (default: Samsung Kies)
or in german:
Einstellungen > Telefoninfo > USB-Einstellungen > (X) Massenspeicher
Only after changing this setting, you can connect the GT-i5800 as described in the Missing Sync manual: "pull down the notification window (aka ‘window shade’) and tap USB connected."

Well, and thanks to bTunes ($1.49), my Android device almost feels like an iPod :-D


Thursday, September 16, 2010

Android on Samsung GT-I5800 and Mac OS X

Eventually I had to admit being a geek. As a consequence, I'm an owner of a Samsung Galaxy 3 i5800 (or simply GT-I5800) now. I'm extremely impressed: This Android phone costs 200€ only, and frankly I don't know why to spent 1000€ for an iPhone. Moreover, to me the iPhone is a little bit too big. The i5800 is a little bit smaller, thus it better fits in my trouser pocket. OK, the camera (3.2 MP) is just good enough for funny apps such as the Barcode Scanner, but I do not really need a camera in my phone. As I'm an Mac OS X user, the most important thing is syncing with my MacBook Pro. This is really easy thanks to Missing Sync: Address Book contacts (with photos), iCal calendars, iTunes, iPhoto , arbitrary folders, SMS logs, phone logs, and other things (and in future versions bookmarks) are easily synced via WLan. It can be configured in order to sync automatically every n minutes via WLan or manually. IMHO, this app is worth it's 39$. Most of my friends have iPhones. So I knew about some great apps they demonstrated me on their gadgets. I'm really surprised finding all these apps available for Android as well and nicely working on my GT-I5800:
  • Dropbox for file syncing
  • 1Password password manager, can be used in combination with Dropbox!
  • Call-a-Bike, great for finding a free bike nearby.
  • Shazam to find out which song is currently played
  • DB Railnavigator
  • Remote for iTunes: With this app I have remote access to my iTunes library on my mac (via WLan), and thanks to my Airport Express I can now listen to my music w/o having to jump back to my computer (in another room) for selecting a new album. I can even select the speakers via this app.
Other applications for the daily information overkill:
  • I'm still not that happy with the browser (I tried the build in browser and Dolphin, and I probably will have to spend some time getting along with the latter one as it provides an ad-blocker and reader plugin).
  • For RSS, I installed gReader Pro. It uses my Google Reader settings, so that I do not have to configure all RSS feeds on the phone. Actually, it is one of the rare things I'm using my Google account for on my phone.
  • As a twitter client, I have installed Twidroyd Pro. Seems as if you have to pay a few bucks for good apps.
  • As I have mulitple mail accounts, I installed the K9 mail reader. It is free, and it does what it says.
However I'm not feeling comfortable with having my mail account passwords (and others) stored on the phone. Actually, the mail account password is one of the most sensible passwords. If one cracks the mail account, it is quite simple to change other passwords of web applications as most web apps sends you a new password if you have forgotten your old one. The lock method of Android 2.1 (which is not too secure, see this paper, however, PINs wouldn't solve that problem, would they?) may help, but I'm not really convinced about that issue. I definitely have to investigate further into that topic.

Monday, May 24, 2010

LaTeX: Listings and labels

I have blogged about the listing package here several times (nicely formatting, and hyphenations). This time I will write about creating labels inside a listing. First of all, the listing package allows to define a caption and a label for a listing, e.g.:
\begin{lstlisting}[caption={myListing},label={lst:myListing}]
void foo(int x) {
 doSomething();
 doMore();
}
\end{lstlisting}
Now the listing can be referenced via \ref{lst:myListing}. The listing package also nicely supports line numbers, there are a whole bunch of settings for that. But why do we need line numbers? In most cases, line numbers are used to refer to a certain line within a listing. E.g, we maybe want to write something like
In line 2 of the listing 1 we call method 'doSomething'.
Well, "listing 1" will look like "listing \ref{lst:myListing}" in the LaTeX source code, but how do we reference the line? Fortunately, the listing packages allows us to escape to latex inside a listing and add a label which can then be referenced:
\begin{lstlisting}[caption={myListing},label={lst:myListing},numbers=left,escapeinside={@}{@}]
void foo(int x) {
 @\label{lst:myListing_2}@doSomething();
 doMore();
}
\end{lstlisting}
Now we can reference the line: In line \ref{lst:myListing_2} ... Actually, you can use any label text, however I usually use the listings label with the line number or a small marker, in order to avoid conflicts with duplicate labels. As I do not want to write "line..." and "listing ..." over and over again, I use the autoref command from the hyperref package:
In \autoref{lst:myListing_2} of \autoref{lst:myListing}
autoref automatically adds a name to the reference counter. As there is no name defined for line numbers, it has to be defined previously:
\providecommand*{\lstnumberautorefname}{line} 
If you need names in a another language, you can add a translation:
\addto\extrasngerman{% 
\def\lstlistingautorefname{Quellcode}% 
\def\lstnumberautorefname{Zeile}% 
}
OK, we can add a line label and easily create a reference to that label. However, writing line labels means a lot of work, especially if you use a listing relative name pattern. So, let's add a macro to TeXShop, which uses some shell commands (mainly sed) and AppleScript in order to automatically create the label, even adding the line number to the label:
--Applescript direct
--
-- Create a label inside a listing, must be invoked at the position at which the label is
-- to be created.
-- Precondition: the listing is defined inside a lstlisting environment and 
--   a label is defined in the parameter list of the environment (label={..}).
--
-- New newly created label consists of the label of the listing with the line number
-- appended to the label. You can configure escape characters (as specified in
-- escapeinside={..}{..}) and the separator between listing label and line number.
--
-- E.g. label={myListing}, on line 5 leads to the following output:
-- @\label{lst: myListing!5}@
--
-- (C) 2010 Jens von Pilgrim, http://jevopi.blogspot.com

property texapp : "TeXShop"
property escapeLeft : "@"
property escapeRight : "@"
property separator : "_"
property maxLength : 2000

try
 tell application texapp
  
  if texapp = "TeXShop" then
   tell application "TeXShop" to set pos to the offset of the selection of the front document
   tell application "TeXShop" to set currentSelection to the content of the selection of the front document
  else if texapp = "iTeXMac" then
   -- ??
  end if
  
  set start to 1
  if (pos > maxLength) then
   set start to pos - maxLength
  end if
  
  set preceeding_text to (characters start thru pos of (the text of the front document)) as string
  set preceeding_text to my findAndReplace(preceeding_text, "\\", "_")
  
  set lineNumbers to do shell script ¬
   "echo " & the quoted form of preceeding_text & ¬
   "| sed -n '/label[:space:]*=[:space:]*{[^}]*}/=;$ {x;=;}'"
  
  
  
  set theLines to my splitLines(lineNumbers) -- as list
  set currentLine to last item of theLines as integer
  -- set startLine to item ((length of theLines) - 1) of theLines as integer
  -- length is not working when executed as macro... workaround:
  set startLine to first item of (rest of (reverse of theLines))
  
  set lstLine to currentLine - startLine
  
  set lastLabel to do shell script ¬
   "echo " & the quoted form of preceeding_text & ¬
   "| sed -n '/label[:space:]*=[:space:]*{[^}]*}/h;$ {x;p;}'" & ¬
   "| sed -n 's/.*label[:space:]*=[:space:]*{\\([^}]*\\)}.*/\\1/g;p'"
  
  set newSelection to escapeLeft & "\\label{" & lastLabel & separator & lstLine & "}" & escapeRight & currentSelection
  
  
  if texapp = "TeXShop" then
   tell application "TeXShop" to set the selection of the front document to newSelection
  else if texapp = "iTeXMac" then
   --tell application "iTeXMac" to insert new_section in the text of the front document
  end if
  
 end tell
on error errmesg number errn
 beep
 display dialog errmesg
 return
end try


on findAndReplace(strInString, strFind, strReplace)
 set ditd to text item delimiters
 set text item delimiters to strFind
 set textItems to text items of strInString
 set text item delimiters to strReplace
 if (class of strInString is string) then
  set res to textItems as string
 else -- if (class of TheString is Unicode text) then
  set res to textItems as Unicode text
 end if
 set text item delimiters to ditd
 return res
end findAndReplace


on splitLines(strInString)
 set ditd to text item delimiters
 set text item delimiters to "
"
 set textItems to text items of strInString
 set text item delimiters to ditd
 return textItems
end splitLines
Now things are really easy: Simply activate the macro at the appropriate location in the listing, and a new label will automatically be created. Note: The listing must have a label defined! You can configure the script by changing the properties at the beginning of the macro.

Tuesday, April 20, 2010

LaTeX: Lstinline and Hyphenations

I really like the LaTeX listing package. However, there is one serious problem: Hyphenations are not supported (Option breakline does not break words)! Fortunately I found a solution which is not 100% perfect, but almost (let's say 99% ;-) ). The idea is to use the replacement feature of listings in combination with the discretionary command. Actually, this is not my idea, its Andrei Alexandrescu's idea. I slightly modified his solution. So, here it is. Actually I define a new command for inline Java code -- you may do this using a style, but I prefer this one:
newcommand{\lstJava}[1]{%
\lstinline[language=Java,breaklines=true,mathescape,%
literate={\-}{}{0\discretionary{-}{}{}}]§#1§}
As '§' is rarely used in Java, I use this character as code delimiter in lstinline. Also, '$' is seldom found in Java code, so I activate mathescape by default as I use it from time to time (that is, more often then '$' in Java). Now, the trick is the literate option. It is used to replace a string in the code with another given string. So, the well known \- - command (telling LaTeX where to hyphenate a word) is replaced here! And it is replaced by the \discretionary command. This one tells LaTeX, how to hyphenate a word, which is especially useful in German writings, where "ck" becomes "k-k". We use this command here to output the hyphen only when necessary. With this command, hyphenation is working within lstinline -- however you will have to mark it manually.
Let's have a look at a rather long Java class, called \lstJava{ThisIsA\-VeryLong\-ClassName}.

Sunday, April 18, 2010

Create BibTeX Entry from Safari Document with BibDesk

I often have to reference webpages from my papers. I use bibtex and in order to reference a webpage I define a new bibtex entry of type webpage. Since I do not want to type in these entries manually, and thanks to BibDesk, a small applescript does the trick for me:
-- (C) 2010 Jens von Pilgrim
tell application "Safari"
 set theTitle to name of front document
 set theURL to URL of front document
end tell

set theDate to (year of (current date)) & "-"
set theMonth to (month of (current date)) * 1
if theMonth < 10 then
 set theDate to theDate & "0"
end if
set theDate to theDate & theMonth & "-"
set theDay to day of (current date)
if theDay < 10 then
 set theDate to theDate & "0"
end if
set theDate to (theDate & theDay) as text

display dialog "Key for webpage " & theTitle & ": " default answer ""
set dlgResult to result

if (button returned of dlgResult = "OK") then
 set theKey to text returned of dlgResult
 
 tell application "BibDesk"
  if (count of documents) = 0 then make new document
  
  tell document 1
   set newPub to make new publication at end of publications
   set type of newPub to "webpage"
   set cite key of newPub to theKey
   set the value of field "Key" of newPub to theKey
   set the value of field "Type" of newPub to "URL"
   set the value of field "Url" of newPub to theURL
   set the value of field "Lastchecked" of newPub to theDate
   set the value of field "Title" of newPub to "{" & theTitle & ", Project Website}"
   
   show newPub
  end tell
  
 end tell
end if
This script grabs the URL from the currently active Safari document and creates a new bibtex entry. Some field are automatically filled, including "Type" which is required by some styles I use.The script asks for the key of the new entry, as this cannot be determined automatically (at least, I don't want the script to make a false guess). I added the script to the BibDesk script folder (at ~/Library/Application Support/BibDesk/Scripts), so it is accessible from within BibDesk. Example: The script produces for http://bibdesk.sourceforge.net/ the following entry:
@webpage{BibDesk,
 Date-Added = {2010-04-18 13:40:38 +0200},
 Date-Modified = {2010-04-18 13:40:38 +0200},
 Key = {BibDesk},
 Lastchecked = {2010-04-18},
 Title = {{BibDesk, Project Website}},
 Type = {URL},
 Url = {http://bibdesk.sourceforge.net/}}

Convert Text to a (TeXShop) Convenient Label

TeXShop support smart selection of words. If you double-click a text, the whole word is selected. A word in TeXShop consists of the letters 'A/a' to 'Z/z' and underscores. Spaces and hyphen '-' are not interpreted as word but as whitespaces separating words. With BibDesk installed 1), you can press the F5 key within a \ref-command and a list will pop up with all the labels defined in your text.
If you want to quickly select a label in order to copy and paste it manually to a reference (e.g., if you do not use \ref but \autoref instead, the latter is not recognized as reference command by BibDesk), spaces and hyphens (and other punctuation characters) are really annoying as you cannot simply select the label using a double click. Even more annoying: If a label is selected from the proposal list (activiated via F5), only the label characters before the first space or punctuation character are pasted.
For that reason I do not use whitespaces or punctuation characters in labels. Since I do not want to convert all characters myself, I have added a new macro to TeXShop (with a nice shortkey on Cmd+'_') which does the trick:
--Applescript direct

-- Converts spaces and punctuation characters to underscores, useable for labels
-- (C) 2010 Jens von Pilgrim
tell application "TeXShop"
set snippet to the content of the selection of the front document
-- replace commands
set snippet to do shell script ¬
"echo " & the quoted form of snippet & ¬
" | sed -E 's/([[:space:]]|[[:punct:]])/_/g'"
set the selection of the front document to snippet
end tell
Note: In a previous posting, I published a macro creating section headers automatically. I have improved this macro in order to convert the whitespaces and punctuation characters in labels as well.
1)Thank you, Herb Schulz, for reminding me that it's BibDesk which adds the completion list to TeXShop ;-)

Tuesday, April 6, 2010

BBL to BIB with BibDesk

BibDesk manages my bibliography, just like iTunes manages my music. I have a single iTunes library, and I also have only a single master bibliography. However, when writing a paper, I want to create a new bib file with only the publications cited in the paper. BibTeX nicely creates a bibliographic reference file (*.bbl), but I want a bibliography file (*.bib) in order to be able to open the paper related publications with BibDesk. So, what I needed was a tool to convert the bbl file into a bib file. Fortunately, I found everything for that on my machine: AppleScript, grep, sed and, of course, BibDesk. I wrote a small script which simply creates a new bib file using a source bib file and a selected bbl file. Simply install the script listed below to your script folder (~/Library/Scripts) and name it "Create BIB from BBL.scpt" . Open your master bib file with BibDesk, then select a bbl file and activate the script(from the script menu in the menu bar). It will automatically create a new bib file in the folder of the bbl file, with the same name as the original bbl file (but with the extension bib).
-- Creates a new bib-file from an bbl-file using BibDesk -- (C) 2010 Jens von Pilgrim -- Version: 1.1, 20100615 tell application "Finder" set selectedItems to the selection end tell if ((count of selectedItems) = 0) then display dialog "Please select at least one bbl file" buttons {"OK"} return end if -- retrieve master bib file set sourceDoc to "" tell application "BibDesk" if (count of documents) = 0 then display dialog "Please open the source bibliography with BibDesk" buttons {"OK"} return end if if (count of documents) > 1 then set listOfNames to {} as list repeat with doc in documents set listOfNames to listOfNames & name of doc end repeat set selected to (choose from list listOfNames) as string repeat with i from 1 to the count of documents set doc to (item i of documents) set strDocName to name of doc as string if (strDocName is equal to selected) then set sourceDoc to document i log "source doc set" end if end repeat if sourceDoc is equal to "" then return end if else set sourceDoc to document 1 end if end tell -- log "copy items from master bib file" -- convert all selected bbl files repeat with theItem in selectedItems set theFile to theItem as alias set posixpath to POSIX path of theFile if (offset of ".bbl" in posixpath) > 0 then set destPosixpath to (my rename(posixpath, "bbl", "bib")) set destFile to POSIX file destPosixpath tell application "Finder" if (exists destFile) then set rep to display dialog "File " & destFile & " already exists. Overwrite?" buttons {"Yes", "No"} set skip to (button returned of rep = "No") else set skip to false end if end tell if (not skip) then -- log "examine bbl file " & quoted form of posixpath -- actually, this is the most important line: set allCites to do shell script "grep -E \"\\\\\\\\bibitem[:space:]*(\\[[^]]*\\])?[:space:]*{([^}]*)}\" " & (quoted form of posixpath) & " | sed -E \"s/\\\\\\\\bibitem[:space:]*(\\[[^]]*\\])?[:space:]*{([^}]*)}/\\2/\"" set numberOfItems to length of paragraphs of allCites if numberOfItems = 0 then display dialog "No bibitems found in " & posixpath & ", maybe the file does not contain any bibitems or the search pattern does not recognize your file format." buttons {"Too bad."} else set numberOfMissedItems to 0 set missedItems to "" tell application "BibDesk" set destDoc to make new document repeat with cite in paragraphs of allCites set bibs to search sourceDoc for cite set bFound to false repeat with bib in bibs set strFoundKey to cite key of bib as string set strCite to cite as string if strFoundKey is equal to strCite then -- log strCite & " found, add to new bib" set newBib to make new publication at end of publications of destDoc duplicate bib to newBib set bFound to true end if end repeat if not bFound then set numberOfMissedItems to numberOfMissedItems + 1 if (numberOfMissedItems > 1) then set missedItems to missedItems & ", " end if set missedItems to missedItems & cite end if end repeat save destDoc in destFile end tell if numberOfMissedItems > 0 then display dialog "Did not found " & numberOfMissedItems & " out of " & numberOfItems & " items: " & missedItems & "." buttons {"Uups"} end if end if end if else display dialog "Can only extract bib entries from BBL file, was " & posixpath end if end repeat -- this sub-routine just comes up with the new name on rename(item_name, item_ext, new_extension) set the trimmed_name to text 1 thru -((length of item_ext) + 2) of the item_name set target_name to (the trimmed_name & "." & new_extension) as string return the target_name end rename
If you don't have BibDesk, you might want to have a look at Michael Zhang's Perl Script. Instead of parsing the bbl file, Zhang's script parses the latex source. I prefer parsing the bbl file, as sometimes I use a whole bunch of latex sources, and BibTeX is quite good in gathering all citations into a single bbl file. You may also want to read the comments to Zhang's post for other solutions. If you don't have a master bib file, you may look at http://www.tex.ac.uk/cgi-bin/texfaq2html?label=makebib. There's a perl scrip provided reconstructing a bib file from a bbl file only. Update 2010-06-15: I updated the script as some BBL files were not recognized. If the script doesn't work, you may have a look at your BBL file. At the moment, the script searches for bibitems like "\bibitem{key}" or "\bibitem[abbr]{key}".

Tuesday, March 23, 2010

Nicely formatted listings in LaTeX with adjusted fonts

I'm using the listings package in order to get nicely formatted listings in latex. Since many people are used to the fonts and syntax highlighting of their IDE, I tried to emulate the layout and colors of code as it is formatted in Eclipse. Thanks to XeTeX, I'm able to simply change the font in listing as well. I use two fonts for listing paragraphs and inline:

\newfontfamily\listingsfont[Scale=0.7]{Courier} 
\newfontfamily\listingsfontinline[Scale=0.8]{Courier New} 
This enables bold fonts in typewriter, another way of solving this problem is to use LuxiMono, but I haven't tried that one. Then I define the colors Eclipse uses, comments are defined a little bit darker:

\usepackage{color}
\definecolor{sh_comment}{rgb}{0.12, 0.38, 0.18 } %adjusted, in Eclipse: {0.25, 0.42, 0.30 } = #3F6A4D
\definecolor{sh_keyword}{rgb}{0.37, 0.08, 0.25}  % #5F1441
\definecolor{sh_string}{rgb}{0.06, 0.10, 0.98} % #101AF9
Sometimes I need math text in listings, e.g. when writing pseudo code. Since I scaled the fonts down, the normal math fonts (displaystyle) are a little bit too large. One possible solution of resizing the math fonts would be to use \DeclareMathSizes, however I do not want to change the font for the whole document. The listings package provides two properties "escapebegin" and "escapeend", which are inserted before and after escaping to latex or math. However, simply using escapebegin={\ \scriptstyle} would cause errors when escaping not to math but to normal latex mode. In order to solve that problem, I define a custom command:

\def\lstsmallmath{\leavevmode\ifmmode \scriptstyle \else  \fi}
\def\lstsmallmathend{\leavevmode\ifmmode  \else  \fi}
Now I'm ready to define the overall style for listings:

\lstset {
 frame=shadowbox,
 rulesepcolor=\color{black},
 showspaces=false,showtabs=false,tabsize=2,
 numberstyle=\tiny,numbers=left,
 basicstyle= \listingsfont,
 stringstyle=\color{sh_string},
 keywordstyle = \color{sh_keyword}\bfseries,
 commentstyle=\color{sh_comment}\itshape,
 captionpos=b,
 xleftmargin=0.7cm, xrightmargin=0.5cm,
 lineskip=-0.3em,
 escapebegin={\lstsmallmath}, escapeend={\lstsmallmathend}
}
Comments are printed italic for black-white prints. In order to simplify the use of \lstinline, I define some commands for my favorite languages, e.g.,

\newcommand{\lstJava}[1]{\lstinline[language=Java,breaklines=true,basicstyle= \listingsfontinline]$#1$}

Example


%:lst:Test
\begin{lstlisting}[language=Java, caption={Just a test}, label={lst:Test}]
package de.jevopi;

/*
 * This is my class
 */
public class Test {

 public void foo(String s) {
  System.out.println("Hello " + s);
 }

}
\end{lstlisting}
will produce the following output (on the left). On the right, you can see the Eclipse version of the very same code snippet. (Click to enlarge images)

Thursday, March 4, 2010

Spell Checker, LaTeX, and OS X

Spell checking is a standard feature today. With LaTeX however it is not too easy to achieve. You can certainly use the build-in spell checker of OS X, but then you have to "proof read" all LaTeX commands and their parameters, which can be annoying. So I was looking for a better solution.

Because it was automatically installed I tried Excalibur. Frankly, I don't like it at all, but maybe I have missed something. It only offers very limited options. Unfortunately it doesn't support UTF-8. Since I'm using XeTeX wiht UTF-8, a spell checker w/o UTF-8 support is useless for me.

So I tried Aspell. If you look at the Aspell webpage, you'll get this "Linux users have to compile their application" feeling. There is a darwin port of aspell triggering a "Darwin users have to compile their application" feeling...

Fortunately, I eventually found CocoAspell. (Yes, well, there's a link to it on the TeXShop website ;-) ...) It comes with an installer, so you don't have to install XCode or Fink :-D. Best of all, it installs a system preference panel -- and that's really great! With this filter shown in the screenshot you can define LaTeX commands and if their arguments are to be spell checked. For example, the argument of \section{} is to be spell checked, while labels (\label{} ) are not to be spell checked. It comes with a list of predefined commands, and I added some commands, e.g., \autoref{} (as you can see in the screenshot).

You can find dictionaries at ftp://ftp.gnu.org/gnu/aspell/dict, before downloading them read the hints at cocoAspell's webpage.

I had some problems activating the Aspell dictionaries in TeXShop. Of course, you have to activate the dictionary in cocoAspell's prefernce panel. And I had to deactivate the "check spelling" box in the TeXShop preference, I don't know why. Spell checking is activated in TeXShops edit menu, I don't know what this preference setting is good for...

Well, spell checking a document for the first time usually means to add a lot of word to the dictionary. Sometimes, you want to edit this user dictionary (maybe because you added a word by mistake of because you want to add an existing list). The user dictionaries can be found at ~/Library/Spelling. These files are simple text files and you can open and edit these files with almost any editor. However, the words are separated with an usually invisible character, so you have to use an editor which can show invisible characters, such as SubEthaEdit (unfortunately, TeXShop cannot show these characters).

OK, now that we have a nice spell checker for LaTeX, we only have to change the language in "Spelling and Grammar". However, opening that tiny window requires a bunch of mouse clicks, and often we do not want to actually spell check but only change the dictionary. I found a small applescript at maxoxhints forum, and the version provided by Eponymous works for me. Eponymous' script could be added to the apple script menu and then will be available in all applications. Note: In order to make this script work, you have to activate "Enable access for assistive devices" in the "Universal Access" panel of the system preferences.


Tuesday, March 2, 2010

Create Section Headers with TexShop and Applescript

I really like the macro feature of TexShop. One of the most common use cases of macros would probably be the definition of a section (or subsection etc.). My section-creation-macro has been quite simple in the past:

% ----------------------------------------
% \section{#SEL##INS#}
% \label{sec:#SEL#}
% ----------------------------------------
This small snippet creates a nicely formatted section header including a label. However, there's a really annoying problem: When creating a reference to a section (that is, to its label), TeXShop does not handle spaces accordingly when selecting a label from the dropdown list. For example, if your label is something like \label{sec:Hello World}, the complete label is shown in the list, but only \ref{sec:Hello} is inserted into the text. In order to overcome this problem, I always replace spaces in labels with underscores. So my label would be "sec:Hello_World", and TeXShop is working perfectly. But replacing spaces with underscores by hand is even more annoying. So I replaced my section macro with an applescript version:

--Applescript direct

-- Create a section header from selected text. A label is automatically added with a prefix
-- "sec:", spaces are converted to underscores.
-- (C) 2010 Jens von Pilgrim

property level : "section"
property cmtchar : "-"
property cmtlength : 78
property labelprefix : "sec:"
-- property newline: "\n"
tell application "TeXShop"
 
 
 tell application "TeXShop" to set title to the content of the selection of the front document
 
 set new_title to title
 if ((count of the paragraphs of title) ≥ 1) then
  set this_line to paragraph 1 of title
  set label to this_line
  set add to "true"
  
  -- replace commands
  set label to do shell script ¬
   "echo " & the quoted form of label & ¬
   " | sed -E 's/([[:space:]]|[[:punct:]])/_/g'"
  
  set comment to "% "
  repeat with ii from 1 to cmtlength
   set comment to comment & cmtchar
  end repeat
  
  set new_title to ¬
   comment & return & ¬
   "\\" & level & "{" & title & "}" & return & ¬
   "\\label{" & labelprefix & label & "}" & return & ¬
   comment & return
 end if
 
 tell application "TeXShop" to set the selection of the front document to new_title
end tell
This macro creates a section just like the initial macro version, but this time spaces are automatically replaced in the label. That is, simply select your section title, activate the macro, and you get a nicley formatted title with a TeXShop compatible label. E.g. Mark
Hello World, this is great
and the macro will convert this to
% ==============================================================================
\section{Hello World, this is great}
\label{sec:Hello_World__this_is_great}
% ==============================================================================
You can easily adjust the macro in order to create subsection, subsubsections or chapters as well. I have different kind of comments for different section levels, all you have to change are the properties in the first line:

...
property level : "section"
property cmtchar : "-"
property cmtlength : 78
property labelprefix : "sec:"
...
Change level to "subsection" or whatever, and set the cmtchar to "*", "." or whatever you like. Changing a section level has already been subject of another blog post: Increase/Decrease Section Level with TeXShop Macros.

Friday, January 29, 2010

OmniGraffle and multi-language diagrams

Sometimes I need diagrams in different languages for different purposes. E.g., for presentations on international conferences, I use english labels, while I need german labels for my thesis (which is written in German). I sometimes change my diagrams, I don't want to have two version of a diagram, one in english, another one in german. Because I always export my diagrams to PDF, I'm using two smart export scripts in conjunction with layers, used for internationalization (i18n). First of all, I add a layer for each language. In order to distinguish these internationalization layers from other layers, I use a prefix "lang_". All language specific labels and elements are added to that layer. Other things are placed on layers without my language prefix. Usually, I initially create the diagram in one language, and then move all language specific stuff to the language layer. I then copy all that language specific stuff and paste it onto another language layer (or, simply duplicate the layer), where it is translated. By changing the visibility of the language layers, I can change the language of the diagram. Since it is one diagram, changes on the shared layer are reflected in all language versions, language dependant things have to be adjusted (and translated) manually. The following screenshots show a sample diagram with three layers for shared, english and german elements. In order to create language specific PDFs, I have modified a script I published here some time ago. Here is the modified version:
-- converts selected OmniGraffle files to PDF with internationalization -- based on Greg Titus's script found at -- http://forums.omnigroup.com/showthread.php?t=106&highlight=export+applescript -- -- by jevopi, 2010 global export_language, layer_prefix set export_language to "de" set layer_prefix to "lang_" tell application "Finder" set these_items to the selection end tell repeat with i from 1 to the count of these_items set this_item to (item i of these_items) as alias set this_info to info for this_item -- insert actions here for: this_item set item_path to POSIX path of this_item set item_folder to (parent of (item i of these_items)) as string set item_name to name of (item i of these_items) set item_ext to name extension of (item i of these_items) set exp_name to my rename(item_name, item_ext, "pdf") set exp_path to item_folder & exp_name set msg to "Path: " & item_path & ", Exp: " & exp_path --display dialog msg buttons {"OK"} default button 1 my omniConvert(this_item, item_path, exp_path) end repeat -- this sub-routine just comes up with the new name on rename(item_name, item_ext, new_extension) tell application "Finder" if the item_ext is "" then set the trimmed_name to the file_name else set the trimmed_name to text 1 thru -((length of item_ext) + 2) of the item_name end if set target_name to (the trimmed_name & "_" & export_language & "." & new_extension) as string end tell return the target_name end rename -- this sub-routine does the export on omniConvert(source_file, source_path, target_path) with timeout of 900 seconds tell application "OmniGraffle Professional 5" -- save the current export settings so we can replace them later set oldAreaType to area type of current export settings set oldBorder to include border of current export settings set oldBackground to draws background of current export settings -- here is where you set the export settings you want set area type of current export settings to all graphics set include border of current export settings to false set draws background of current export settings to false set export scale of current export settings to 1 set border amount of current export settings to 0 -- open the file if it isn't already open set needToOpen to (count (documents whose path is source_path)) is 0 if needToOpen then open source_file end if -- do the export set docsWithPath to documents whose path is source_path set theDoc to first item of docsWithPath set allLayers to layers of first canvas of the theDoc repeat with i from 1 to the count of allLayers set theLayer to (item i of allLayers) -- repeat with theLayer in layers of first canvas of theDoc set theName to name of theLayer if (offset of layer_prefix in theName) > 0 then if theName = layer_prefix & export_language then set visible of theLayer to true else set visible of theLayer to false end if end if end repeat save theDoc in file target_path -- if the file wasn't already open, close it again if needToOpen then close theDoc saving no end if -- put the original export settings back set area type of current export settings to oldAreaType set include border of current export settings to oldBorder set draws background of current export settings to oldBackground end tell end timeout end omniConvert
This script exports an OmniGraffle diagram to PDF. Besides, only one language specific layer is made visible and the langauge id is added to the filename. The language is defined in line
set export_language to "de"
That is, this script automatically creates a german version of the diagram. I have a script for each language (and one w/o i18n) in my script folder, e.g. After applying the both i18n-scripts to the diagram, two PDFs are created from my diagram: This technique works pretty well with text and connection labels. Unfortunately labels placed on shapes cannot be moved on a layer different from the shape. So, in these cases you have to move the whole shape to the language layer. If you translate a diagram after you have created it, this works pretty well. It may become a little bit annoying if you have to change the diagram, but at least you are aware of the changes and don't have to work with two separate files.

Sunday, September 20, 2009

Acronyms and LaTeX

Computer geeks like acronyms, especially three-letter acronyms (TLAs). To give you an impression: I'm working in the area of MDD. Actually, OMG calls it MDA, Stuart Kent MDE, and others MDSD. In short, models, such as UML or EMF models, are transformed into other models or code by M2M- or M2T-transformations, such as QVT or ATL. Writing a thesis in that area is really hard, since you have to keep an eye on all that TLAs. So I've looked for a LaTeX package doing the job for me, and what I found is a package called acronym by Tobias Oetiker. I really like the simplicity of this package, this is why I decided to use that instead of other alternative solutions.

Install acronym

Surprisingly, it was already installed with my tex installation (gwTeX), but it requires a packages called suffix, which was not. The later is contained in a bundle called bigfoot. Here are the CTAN locations of acronym and bigfoot: In order to install a package from the files available at CTAN, you usually have to
  • download the zip or all the files from CTAN
  • unzip them (or put them into a folder) and put the folder somewhere tex can find it, e.g. into $HOMETEXMF (i.e. ~/library/texmf/tex)
  • run the installer via latex *.ins, in that case latex bigfoot.tex
Now you are ready to use acronym. It is quite simple: simply include the package via
\usepackage{acronym}
Instead of simply writing the acronym in your text, you now have to write \ac{..} (or, in case of a plural, \acp{..}). You have to add a new environment with a list of all the acronyms and their long form with

\begin{acronym}
\arcro{..}{...}
\end{acronym}
The first time an acronym is used, \ac prints the long form with the acronym in brakets. There are also some other commands available, see the acronym documentation for details.

Add list of acronyms to table of contents

Unfortunately, there is no command available for adding an entry to the table of contents. I have written my own command for that, which creates an entry similar to the list of figures. You have to add the following code somewhere in your preamble:

\@ifundefined{listofacronymsname}{\newcommand{\listofacronymsname}{Acronyms}}{}
\@ifundefined{chapter}{%
\newcommand{\listofacronyms}{%
\section*{\listofacronymsname}%
\addcontentsline{toc}{section}{\listofacronymsname}%
\label{sec:acronyms}%
\markboth{\listofacronymsname}{\listofacronymsname}%
}}{%
\newcommand{\listofacronyms}{%
\chapter*{\listofacronymsname}%
\addcontentsline{toc}{chapter}{\listofacronymsname}%
\label{sec:acronyms}%
\markboth{\listofacronymsname}{\listofacronymsname}%
}}
It defines two commands:
\listofacronymsname
defines the name of the heading used for the list of acronyms. It is "Acronyms" by default, but you can change that with \renewcommand, as demonstrated below.
\listofacronyms
creates a heading and a section or chapter definition (depending on the document class), which is also added to the table of contents. A label "sec:acronyms" is added as well.
(Update 2012-05-21: \markboth adjusts the header accordingly, see mrunix thread)

Put it all together

Let's put it all together. Firstly, we use the package and define the \listofacronyms command:

\usepackage[printonlyused,smaller]{acronym}     % acronyms ac
\@ifundefined{listofacronymsname}{\newcommand{\listofacronymsname}{Acronyms}}{}
...
I have added some parameters to only list the used acronyms and use a slightly smaller font. Secondly, we create a new file "acronyms.text" with a list of the acronyms, which makes it easier to maintain. This is how my file looks like:

\renewcommand{\listofacronymsname}{Abkürzungsverzeichnis} % german title
\listofacronyms

% \acro{acronym}[shortname]{fullname}
% inside fullname: \acroextra{} -- not in text, only in description list
\begin{acronym}
\acro{EMF}{Eclipse Modeling Framework \cite{EMF}}
\acro{GEF}{Graphical Editing Framework \cite{GEF}}
\acro{MDD}{Model Driven Development}
\acro{MDA}{Model Driven Architecture}
\acro{UML}{Unified Modeling Language}
...
\end{acronym}
The acronyms are not sorted automatically, I use SubEthaEdit for sorting the acronyms from time to time, but I guess there are several editors which can do that. This file has to be included in your main latex source document, e.g.,

\begin{appendix}
\input{acronyms}
\end{appendix}
Last but not least, we have to use the acronym commands in the text, just like that:

I'm working in the area of \ac{MDD}. Actually, \ac{OMG} calls it \ac{MDA}, Stuart Kent \ac{MDE}. In short, models, such as \ac{UML} or \ac{EMF} models, ...
You do not have to look for the first usage of an acronym anymore, acronym is doing that for you. If you forget to define an acronym, you will see that in the generated output as acronym creates a bold placeholder in that case. If you do not want to printed the list of acronyms, you can use acronym just as described before, you only have to add a package option nolist (i.e. \usepackage[nolist]{acronym}). This is especially useful in combination with the option footnote, as in that case the description of the acronym is printed as a footnote and not in the text (and one can find the definitions by scanning the footnotes, which is ok for shorter texts). Thank you very much, Tobias Oetiker, for writing that package!

Wednesday, July 22, 2009

OmniGraffle Stencils

My favorite application for creating nice drawing is OmniGraffle. At Graffletopia you can find lots of user created stencils, that is templates for using in your own drawing. The latest version of OmniGraffle let you search a stencil directly at Graffletopia, so if you think you need something like UML notation elements, just enter UML in OmniGraffel's stencil window and you will find several stencils at Graffletopia. I have created some stencils as well, and you can download them from Graffletopia. You can either search for them from within OmniGraffle, or you can download and install them manually. Here is a list of my stencils:
  • UML 2.1 Collection: A collection of notation elements for creating UML 2 class, activity, use case, sequence, or component diagrams. It's a rather large stencil, but it contains most UML 2.1 elements
  • Feature Diagrams: Feature Diagram stencil, notation based on the book "Generative Programming" by K. Czarnecki and U.W. Eisenecker. (Updated today and fixed some problems)
  • Post-it Notes: A collection of six colored post-it notes with nice shadow, slightly bended.
Have fun!