maandag 30 mei 2016

First stab at making solid rocket propellant (GALCIT)

Last weekend we took a first stab at making the solid rocket propellant GALCIT.

Long story short: melting bitumen on the temperature controlled hotplate took a lot longer than expected so we weren't able to mix in the potassium perchlorate yet. That's planned for the next session, tomorrow!

Below is a small report of the session with some visuals.

***

The goal was to make 2l of GALCIT, with the following composition:
  • 76% Potassium perchlorate (KClO4) Superfino from Nitroparis
  • 20% Solid block bitumen from Icopal through Defranq
  • 4% Paraffin oil from the local drugstore, Estfarma
Lots of gratitude to Peter Madsen of the RML spacelab for providing us with this formula and lots of useful pointers. They are doing amazing work.

Also a big thanks to the mentioned suppliers. Each of them went out of their way to guide us to the proper channels for acquiring these products. They seem to be of great quality!

We are making a volume 2l of GALCIT so at the published density of 1.72 kg/l the total propellant mass computes to 3.44 kg.

Applying the above GALCIT composition, that translates to:
  • 76% = 2614.4 g of potassium perchlorate
  • 20% = 688g of solid block bitumen
  • 4% = 137.6 g of paraffin oil
The high-level procedure to make GALCIT is:
  1. Heat paraffine oil
  2. Melt bitumen in paraffin oil
  3. Mix in potassium perchlorate through a fine sieve to remove lumps
This is our block of 10kg bitumen:


Cutting 688g off of it was difficult, as expected. Bart discovered that cutting it with a long, strong, heated knife turned out to be the easiest way to cut slices off. 

I was surprised to see that although bitumen looks heavy, it actually has a low density. Look at all that volume to make up just 689.28g! 




To melt the bitumen, we are using the RSM-05-H by Phoenix Instrument. This hot plate with built-in magnetic stirrer can stir 20l of water and reach up to 550 degrees Celsius. Having accurate temperature control is important to avoid overheating the propellant. Overheating is in any case unlikely because of the big difference in preparation temperature (less than 200 degrees C) and combustion temperature (500 degrees C).

The RSM-05-H has an RS-232 interface to control and monitor it from a computer but we didn't use that this time. And although it came with a probe for accurate in-liquid temperature control, we wanted to spare the poor probe from being dipped into sticky, molten bitumen...



Melting the bitumen took a lot longer than expected. This is not unusual - bitumen just takes a long time to melt. Also, we did the mixing outside with a light breeze, which is great for ventilation but causes quite some heat loss on the hot plate.

To speed up the melting process, we turned the temperature up to 200 degrees C, which is without risk as long as the oxidizer (the potassium perchlorate) is not mixed in yet.

In total, melting 689.28g of bitumen with paraffin oil took around 1 hour and 15 minutes.

***

Before melting bitumen, we took the time to make various cardboard test-engines to cast the propellant into. Bart knew that the best way to cut cardboard tubes is with a fine metal saw:





While melting, we experimented with a small amount of ignition powder, composed of 80% potassium nitrate (KNO3) and 20% fine carbon powder.



We were unable to ignite this mixture, not by electrically heating a thin copper wire until melting point and neither with open flames. The video isn't quite as spectacular as we hoped, anti-climaxing at around 0:20s with some smoke:


We posit 2 reasons the powder is not igniting:
  • Poor mixing of the ignition powder components
  • Lack of sulfur in the mixture
So next time, we'll add some sulfur to the mix and try to get our hands on an automatic powder mixer.





woensdag 7 januari 2015

3D File System Browser (3dfsb) forked back to life and improved

7 January 2015, Gent - The decades-old (but very cool!) 3D File System Browser tdfsb has been forked back to life and received new features, improvements, and cleanups. Version 1.0 has just been released under its new name: 3dfsb.

Among the new features are tons of additional supported audio and video formats (with GStreamer), better filetype identification (with libmagic), higher resolution textures and a new "lasergun tool" that allows you to zap your files away in the 3D world to delete them!

From the author, Tom Van Braeckel:

"I've been cleaning up and improving a very old 3D File System Browser. The original version was called tdfsb, and had been dormant for 7-13 years.

After trying to get in touch with the original author (Leander Seige) via various channels without reply, I decided it's probably best to fork the original code. Leander was kind enough to release his code under the GPLv2 software license, so no problems there. Thank you, Leander!

The new software is called 3D File System Browser, or 3dfsb for brevity.

The code was, and still is, fairly rough. It's all in one big .c file and comments were few and far between. That's completely understandable, historically speaking. Although I didn't hear from the original author, I imagine that it started out as some kind of a research/educational project to get to know the various libraries it uses.

And that's exactly why I picked it up: to deepen and refresh my GStreamer, OpenGL, SDL and 3D geometry knowledge. Yes, indeed: 3D geometry, of which you need a lot of when rendering 3D worlds! All in all, it's been very educational, and I hope we can keep improving this cool program further.

I'm releasing version 1.0 today for your feedback, testing and enjoyment."

Here's an excerpt of the CHANGELOG:

Version 1.0 (07-01-2015)
************************

Major changes
-------------
- Extended audio and video support: more than 100 additional container formats and decoders are now supported through the latest GStreamer 1.4.3
- Better file identification: filetype is now determined by the contents of the file (with libmagic) with the extension of the file as a fallback
- High-resolution video previews: cranked up from the old 256x256 pixels to however high your graphics card supports (eg: 8192x8192)
- More fun: you can now zap away at your files with the lasergun tool! For your own protection, nothing is physically deleted from disk, unless y
ou explicitly configure the program to do so.
- Video input device (eg: webcam) file previews: Video4Linux (V4L2) capture devices are now visible in the 3D world and can be viewed just like your movies!

Minor changes
-------------
- Faster navigation by default
- Visible on-screen info by default
- Uncapped framerate by default
- Uncapped texture size by default
- Higher rendering resolution by default
- Lots and lots of code cleanups and comments added
- No more dependency on libsmpeg

Performance
-----------
This version runs at 1920x1080 resolution while playing 720p H264 video (2048x2048 texture) on a single-core of the Intel Core i7 at 2.90Ghz.

Here are a few screenshots of the new features:

Above: all major audio and video formats are supported through GStreamer. Video texture size went up from 256x256 to however high your GPU can go. Think 8192x8192.

Above: hardware device files (such as webcams) are visible in the 3D world and can be accessed from it.

Above: filetype detection is much more robust and versatile, relying on libmagic to identify a filetype by its contents. The old method, which is based on filename extensions, is used as a fallback.

Above: you can use different tools to operate on your files, for example: blast them with the laser to delete them! And don't worry: for safety reasons, the program doesn't actually delete them from your disk unless you explicitly configure it to do so.


Download
All sources and releases are GPLv2 and published in the 3dfsb repository at GitHub.

Support
If you need any help, including (but not limited to) packaging this software, don't hesitate to contact me or drop a line in the comment section.

zaterdag 8 november 2014

Activating A2DP bluetooth stereo headphones in Ubuntu Trusty (14.04.1 LTS)

For future explorers who might struggle with this, and possibly for myself :-)

1) Install recommended software:

sudo apt-get install pulseaudio pulseaudio-module-bluetooth bluez-audio pavucontrol bluez-firmware bluez-tools blueman

2) Add the below line to the [General] section of /etc/bluetooth/audio.conf:

Enable=Socket

3) Ensure module-bluetooth-discover is loaded (can't hurt):

pactl load-module module-bluetooth-discover

Note: you can also disable unloading the module-bluetooth-discover this patch.

4) Restart all affected services to take the new configuration into account:

sudo service bluetooth restart; sudo killall pulseaudio

5) Pair your A2DP bluetooth headset and add the trust attribute. You can do this in the graphical manager, blueman-manager. 6) Activate the bluetooth audio sink in a graphical manager (blueman-manager) or on the command line:

bt-audio -c 0C:E0:E4:49:8D:FD

7) Now, in your favorite volume manager, pavucontrol, you can redirect any audio stream to your bluetooth stereo headphones. Enjoy!

Sources:

  • https://wiki.debian.org/BluetoothUser/a2dp
  • http://ubuntuforums.org/showthread.php?t=2144841&page=2

vrijdag 31 mei 2013

getChallengeResponse.sh script

#!/bin/sh
# getChallengeResponse.sh - login to my online banking website using the challenge-reponse mechanism
# Purpose of this script (work in progress) is to further automate online banking.
# More info: http://globalblindspot.blogspot.be/2010/07/getting-emvcap-challengeresponse-to.html
# Author: Tom Van Braeckel 

pin="$1"
challenge="$2"

if [ -z "$pin" -o `expr length "$pin"` -ne 4 -o -z "$challenge" -o `expr length "$challenge"` -ne 8 ]; then
 echo "Usage: $0  "
 echo "Example: $0 3117 12345678"
 exit 1
fi

# Can you guess what this method does ?
bintodec() {
 bin="$1"
 echo "obase=10; ibase=2; $bin" | bc
}

# remove < and " "
compact() {
 while read line; do
  echo "$line" | tr -d '<' | tr -d ' '
 done
}

# args: command to execute on the card
execOnCard() {
 cla="$1"
 ins="$2"
 p1="$3"
 p2="$4"
 le="$5"
 data="$6"
 tosend="${cla}${ins}${p1}${p2}${le}${data}"
 #echo "Sending $tosend" >&2
 echo "$tosend" | scriptor 2>/dev/null | grep -A 10000 "<"
  # does not work:
# echo "$cla $ins $p1 $p2 $le $data" | scriptor 2>/dev/null | grep "<"
}

execOnCardRespond() {
 cla="$1"
 ins="$2"
 p1="$3"
 p2="$4"
 le="$5"
 data="$6"
 result=$(execOnCard $cla $ins $p1 $p2 $le $data) ; echo "result = $result" >&2
 # get length in hex
 length=$(echo "$result" | cut -d ' ' -f 3); #echo "length = $length"
 execOnCard 00 c0 00 00 $length | compact
}

# Can you guess what this method does ?
hextobin() {
 hex="$1"
 echo "ibase=16; obase=2; $hex" | bc
}

# do a read data with the correct length...
readData() {
 p2="$1"
 recordLength=$(execOnCard 80 ca 9f $p2 00 | cut -d ' ' -f 3)
 #echo "recordLength = $recordLength" >&2
 # cut off first bytes (status code, length)
 # cut off last bytes (9000Normalprocessing)
 # for some reason we NEED CLA 80 here, 00 doesn't work...
 execOnCard 80 ca 9f $p2 $recordLength | compact | tail -c +7 | head -c -23
 echo
}

readRecord() {
 p1="$1"
 p2="$2"
 errorWithLength=$(execOnCard 00 b2 $p1 $p2 00)
 #echo "errorWithLength = $errorWithLength"
 recordLength=$(echo "$errorWithLength" | cut -d ' ' -f 3)
 #echo "recordLength = $recordLength"
 execOnCard 00 b2 $p1 $p2 $recordLength | compact
}

readRecords() {
 SFI="$1" # five most significant bits
 recNr="$2" # second byte
 lastRecNr="$3" # third byte
 if [ "$SFI" = "1" ]; then
  p2=0c # (sfi << 3) + 4
 else
  echo "I don't know p2 !"
  sleep 3
 fi
 # READ RECORD(s)
 for i in `seq $recNr $lastRecNr`; do
  readRecord 0$i $p2
 done
}

zeropadfront() {
 targetLength="$1"
# echo "targetLength = $targetLength"
 while read line; do
#  echo "got line $line"
  length=$(expr length "$line")
  while [ $length -lt $targetLength ]; do
   line="0${line}"
   length=$(expr length "$line")
  done
  echo "$line"
 done
}

#################################################################
###################### EXECUTION STARTS HERE ####################
#################################################################

# reset
execOnCard reset

#select file/application
aid=A0000000048002 # securecode aut
#aid=A0000000043060 # maestro (debit)
response=$(execOnCardRespond 00 a4 04 00 07 ${aid})
echo $response

# this is needed, otherwise the commands below fail...
PDOL=$(echo "$response" | grep -o -E "9F38........" | tail -c +7)
echo "PDOL = $PDOL"
# for securecode get a PDOL of "9F3501" (eg "9F38039F3501")
# this is the "Terminal Type" - don't know the value, but I use 00...

# get processing options:
# - Application Interchange Profile (AIP)
# - Application File Locator (AFL)
if [ -z "$PDOL" ]; then
 response=$(execOnCardRespond 80 a8 00 00 02 8300); echo $response
 # eg: ...94080801030110010201
 AIP=3800 # this means "initiate", "data auth", RFU
 AFLs="08010301 10010201"
else
 # PDOL specifies one tag with value of 1 byte, but I don't know which value...
 response=$(execOnCardRespond 80 a8 00 00 03 830100); echo $response
 # 770E82021000940808010100080404009000:Normalprocessing.
 AIP=1000 # this means "initiate"
 AFLs="08010100 08040400"
fi
echo "Found AIP = $AIP and AFLs = $AFLs"

# Read SecureCode records and extract valueable info
cardinfo=$(readRecords 1 1 1)
PAN=$(expr substr "$cardinfo" 9 18)
echo "Application Primary Account Number (PAN) = $PAN"
authinfo=$(readRecords 1 4 4)
bitmap=$(expr substr "$authinfo" 11 22)
echo "Proprietary Authentication Challenge-Reponse Bitmap = $bitmap"

# This works for maestro:
if false; then
 readRecords 1 1 3

 # second group in AFL
 SFI=10 # five most significant bits
 recNr=1 # second byte
 lastRecNr=2 # third byte
 offlineDataRec=1 # fourth byte
 # p2=binary(firstbyte)100 left shift 3 OR 100 ???
 # p2=binary(firstbyte) shift right 3
 # I calculated 84, but it seems to be (13) 14 / (1B) 1C / (23) 24
 # and also 03 04 0B 0C but we found those above
 p2s="14 1C 24"
 # READ RECORD(s)
 for p2 in $p2s; do
  for i in `seq $recNr $lastRecNr`; do
   echo -n "p2 = $p2, recordNr = $i: "
   readRecord 0$i $p2
  done
 done
fi

# get pin try counter length
pinTry=$(readData 17)
echo "pinTry = $pinTry"
if [ "$pinTry" != "02" -a "$pinTry" != "03" ]; then
 echo "WARNING: pinTry < 2 !"
 sleep 15
fi

# get Application Transaction Counter
echo -n "Application Transaction Counter = "
readData 36

# get Last Online ATC Register
echo -n "Last Online ATC Register = "
readData 13

echo -n "Log Entry = "
readData 4D

echo -n "Log Format = "
readData 4F

# submit pin
execOnCard 00 20 00 80 08 24${pin}FFFFFFFFFF

# generate Application RQ Cryptogram
# p1=80=Authorisation Request Cryptogram
countrycode=0056 # OTF mentions 0000, chip&pin uses 0826
currencycode=0978 # OTF mentions 0000, chip&pin uses 0826
date=$(date +"%y%m%d")
CardholderVerificationMethodResults=010002
# 8000000000 = Terminal Verification Codes: Data authentication was not performed (recommended by optimized to fail)
# 00 = transaction type
# 0000 = ICC Dynamic Number
ARQC_response=$(execOnCardRespond 80 AE 80 00 22 000000000000000000000000${countrycode}8000000000${currencycode}${date}00${challenge}0000${CardholderVerificationMethodResults})
echo "ARQC_response = $ARQC_response"
CID=$(expr substr "$ARQC_response" 11 2)
ATC=$(expr substr "$ARQC_response" 19 4)
AC=$(expr substr "$ARQC_response" 29 16)
#IAD=$(expr substr "$ARQC_response" 51 15)
# testing to see if we get the same response as in chip&pin - we do, so this is OK.
# CID=80; ATC=A52D; AC=AD452EF6BA769E4A; IAD=06770A03A48000; bitmap=00001F00000000000FFFFF00000000008000


# generate Application Cryptogram for challenge 12345678
# 5a33 = Authorisation Response Code, generated by terminal or bank (for online stuff)
IAuthData=0000000000000000000000000000000000000000 # Issuer Authentication Data (NOT Issuer Application Data !)
AC_response=$(execOnCardRespond 80 AE 00 00 2e 5a33000000000000000000000000${countrycode}8000000000${currencycode}${date}00${challenge}0000${CardholderVerificationMethodResults}${IAuthData})
echo "AC_response = $AC_response"
#AC_response="$ARQC_response" # Testing which response we need - normally the second one, but let's try this for a laugh
CID=$(expr substr "$AC_response" 11 2)
ATC=$(expr substr "$AC_response" 19 4)
AC=$(expr substr "$AC_response" 29 16)

# extract response
echo "CID=$CID, ATC=$ATC, AC=$AC, IAD=$IAD"

# length of bitmap is used as the target length for the response
bitmap_hex_length=$(expr length "$bitmap")
bitmap_bin_length=$(expr "$bitmap_hex_length" \* 4)
echo bitmap_hex_length=$bitmap_hex_length, bitmap_bin_length=$bitmap_bin_length

# Do logical AND with bitmap
CIDATCAC_bin=$(hextobin "${CID}${ATC}${AC}${IAD}" | zeropadfront "$bitmap_bin_length")
echo "CIDATCAC_bin = $CIDATCAC_bin"
bitmap_bin=$(hextobin "$bitmap" | zeropadfront "$bitmap_bin_length")
echo "  bitmap_bin = $bitmap_bin"

# if a bit of bitmap = 1, then we add the bit from CIDATCAC_bin to filtered_bin
filtered_bin=
for bitpos in `seq 1 $bitmap_bin_length`; do
 bitmap_bit=$(expr substr "$bitmap_bin" "$bitpos" 1)
 if [ $bitmap_bit -eq 1 ]; then
  CIDATCAC_bin_bit=$(expr substr "$CIDATCAC_bin" "$bitpos" 1)
  filtered_bin=${filtered_bin}${CIDATCAC_bin_bit}
 fi
done
echo "filtered_bin = $filtered_bin"
# Note: if ATC>0x26(38) then response = 8 characters
# if ATC=0xFFFF(65536) then response = 12 characters !!! is this correct ?

filtered_dec=$(bintodec $filtered_bin)
echo "RESPONSE = $filtered_dec"

exit


# this is never executed

if false; then
# Make AND of ARQC and Cap bit Filter:
fortis: 77269F2701 00 9F3602 00B7 9F260886F857BEB767E8FB 9F100F 0601560384B0A80701030000000000
kbc:    77269F2701 00 9F3602 0004 9F260831F94BDAB5DF0F38 9F100F 0601560384B0400701030000000000
kbc: 77269F2701 00 9F3602 0005 9F2608B29D6D20BFE004AD 9F100F 0601560384B0400701030000000000
# extracted values
output 00 00B7 86F857BEB767E8FB 0601560384B0A80701030000000000
output 00 0004 31F94BDAB5DF0F38 0601560384B0A80701030000000000
bitmask 00 00FF 000000000003FFFF
filter .. ..04 ...........30F38
binary     0100 110000111100111000
decimal 1249080
fi




Example protocol log:

Collected from a NatWest reader and card performing a respond computation
(ISO 7816, T=0 protocol). Personal details have been redacted.

Command:   00a4040007 (select application)
Proc:      a4
Data:      a0000000048002
Proc:      61
Status:    6112 (more data available)

Command:   00c0000012 (application selected)
Proc:      c0
Data:      6f108407a0000000048002a5055f2d02656e
Proc:      90
Status:    9000 (OK)

Command: 80a8000002 (initiate transaction)
Proc:    a8
Data:    8300
Proc:    61
Status:  6108 (more data available)

Command: 00c0000008 (transaction initiated)
Proc:    c0
Data:    8006100008010100
Proc:    90
Status:  9000 (OK)

Command: 00b2010c00 (get static data length)
Proc:    6c
Status: 6c57 (wrong length)

Command: 00b2010c57 (read static data)
Proc:    b2
Data:    7055
          8e0a 00000000000000000100 (CVM list)
          9f5501 a0 (unknown)
          9f5612 00001f00000000000fffff00000000008000 (bit filter)
          8c15 9f02069f03069f1a0295055f2a029a039c019f3704 (CDOL1)
          8d17 8a029f02069f03069f1a0295055f2a029a039c019f3704 (CDOL2)
Proc:    90
Status: 9000 (OK)

Command: 80ca9f1700 (get PIN try counter length)
Proc:    6c
Status: 6c04 (wrong length)

Command: 80ca9f1704 (get PIN try counter)
Proc:    ca
Data:    9f170103 (3 remaining tries)
Proc:    90
Status:  9000 (OK)

PIN entered: ?

Command: 0020008008 (verify PIN)
Proc:    20
Data:    24xxxxffffffffff
Proc:    90
Status:  9000 (OK)

Challenge entered: 12345678

Command: 80ae80001d (generate ARQC)
Proc:    ae
Data:    0000000000000000000000000000800000000000000000000012345678
Proc:    61
Status:  6114 (more data available)

Command: 00c0000014 (return ARQC)
Proc:    c0
Data:    80 1280 0042b7f9a572da74caff 06770a03a48000
Proc:    90
Status:  9000 (OK)

Command: 80ae00001f (generate AC)
Proc:    ae
Data:    5a330000000000000000000000000000800000000000000000000012345678
Proc:    61
Status:  6114 (more data available)

Command: 00c0000014 (return AAC)
Proc:    c0
Data:    80 1200 00424f1c597723c97d78 06770a03258000
Proc:    90
Status:  9000 (OK)

Response returned: 4822527



donderdag 31 januari 2013

Love is Math As Well


We don't remember what it was like
that first time
what we talked about 
whether we showed each other things 
which we didn't yet have
the stale wines
in the polished vases
warm bodies in winter
whether we read
from closed books
added ourselves together and 
knew we never
would have to divide
together exponential
a multiplication with
in the cross that we
no longer wanted to carry
a conclusive casting out of nines.

[I translated "Liefde is ook Wiskunde" by Bart Plouvier from Dutch to English for the national poetry day in Belgium.]

donderdag 6 september 2012

File type associations with xdg-open and xdg-mime (for openbox) example


Just so I don't forget, here is how to do it - it's very simple, really:

xdg-mime default xarchiver.desktop application/x-compressed-tar

Why ?


When I clicked on a .tar.gz file in chromium, my desktop environment would hang.

This was caused the fact that chromium calls xdg-open to know which program to use to open the .tar.gz file. xdg-open used "xdg-mime query default application/x-compressed-tar" to figure out what application to use (which was none, because I hadn't configured any default application).

After that, xdg-open doesn't stop. If /etc/debian-version exists, it additionally uses run-mailcap to figure out which program to use. And mailcap was configured to run "less" somewhere down the line, which stops and apparently, stops it's parent processes for some unknown reason when run in this configuration.

So I deleted /etc/debian-version because I don't see the point of having it. We'll see if something what breaks.

How ?

xdg-mime will create the file ~/.local/share/applications/mimeapps.list which then contains:

[Default Applications]
application/x-compressed-tar=xarchiver.desktop

zondag 17 juni 2012

Rudimentary PDF to LaTeX conversion in Linux

I finally got around to trying a rudimentary PDF to LaTeX conversion in Linux.

"It's like turning a hamburger into a cow" :-)

Usage:

./pdftolatex.sh "filename.pdf"

Example output:

# pdftolatex.sh test.pdf 

PDF to LaTeX conversion script
Copyleft 2012 (c) Tom Van Braeckel <tomvanbraeckel@gmail.com>

WARNING: this is a rudimentary first stab. Proceed with caution.

Checking if all dependencies are found...
/usr/bin/pdftohtml
Dependency pdftohtml found.
/usr/bin/gnuhtml2latex
Dependency gnuhtml2latex found.
/usr/bin/pdflatex
Dependency pdflatex found.

Converting test.pdf to test.pdfs.html
Page-1
Page-2
Page-3
Page-4
Page-5
Page-6
Page-7
Page-8
Page-9
Page-10
Page-11

Fixing up test.pdfs.html to test.pdf_fixedup.html...

Readying test.pdf_fixedup.html for tex conversion in test.pdf_fixedup_ready_for_tex_conversion.html

Converting test.pdf_fixedup_ready_for_tex_conversion.html to test.pdf_frompdf.tex
The resulting file is in test.pdf_frompdf.tex

Fixing up test.pdf_frompdf.tex to test.pdf_frompdf_fixedup.tex

Converting test.pdf_frompdf_fixedup.tex to test.pdf_frompdf_fixedup.pdf for inspection...

Opening test.pdf_frompdf_fixedup.pdf with Evince - you can try another PDF viewer if you like...

Script source code:

#!/bin/sh
file="$1"
dependencies="pdftohtml gnuhtml2latex pdflatex"
echo "PDF to LaTeX conversion script"
echo "Copyleft 2012 (c) Tom Van Braeckel <tomvanbraeckel@gmail.com>"
echo
echo "WARNING: this is a rudimentary first stab. Proceed with caution."
echo
if [ -z "$file" ]; then
echo "Usage: $0 <pdf file>"
echo "The resulting .tex file will be stored somewhere here."
exit 1
fi
echo

echo "Checking if all dependencies are found..."
for dependency in $dependencies; do
which $dependency
if [ $? -ne 0 ]; then
echo "Dependency $dependency not found, install it using:"
echo "sudo apt-get install $dependency"
exit 1
else
echo "Dependency $dependency found."
fi
done
echo

echo "Converting $file to ${file}s.html"
pdftohtml -nomerge "$file" "$file".html
echo

echo "Fixing up ${file}s.html to ${file}_fixedup.html..."
# This nasty br in a b causes problems later on
sed "s,<br/></b>,</b><br/>,g" "${file}s.html" > "${file}_fixedup.html"
# ending with bold text menas it is the end of a title and can be on a newline
sed -i "s,</b><br/>\$,</b><br/><br/>,g" "${file}_fixedup.html"
# starting with bold text means it is the start of a title so can be on a new line
sed -i "s,^<b>,<br/><b>,g" "${file}_fixedup.html"
# spaces ?
sed -i "s,\&#160;, ,g" "${file}_fixedup.html"
# there is no use in a space before a newline, and it causes a bogus indent when converting to .tex later on
sed -i "s, <br/>,<br/>,g" "${file}_fixedup.html"
# encoding, although gnuhtml2latex ignores this
sed -i "s,<HEAD>,<HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />," "${file}_fixedup.html"
echo

echo "Readying ${file}_fixedup.html for tex conversion in ${file}_fixedup_ready_for_tex_conversion.html"
cp "${file}_fixedup.html" "${file}_fixedup_ready_for_tex_conversion.html"
# br is ignored and should be replaced by a newline
sed -i "s,<br/>,<p></p>,g" "${file}_fixedup_ready_for_tex_conversion.html"
# Remove bogus links - this fixes the empty } problem
sed -i "s/<A name=[0-9]\+><\/a>//g" "${file}_fixedup_ready_for_tex_conversion.html"
echo

echo "Converting ${file}_fixedup_ready_for_tex_conversion.html to ${file}_frompdf.tex"
# -c = table of contents
# -s = write to standard out
# -p  Break page after title / table of contents
# -H  use hyperref package to process anchors
# -g images
# -n  Use numbered sections
gnuhtml2latex -c -s -p -H -n "${file}_fixedup_ready_for_tex_conversion.html" > "$file"_frompdf.tex
echo "The resulting file is in ${file}_frompdf.tex"
echo

echo "Fixing up ${file}_frompdf.tex to ${file}_frompdf_fixedup.tex"
sed -i 's/\\par/\\newline/g' "${file}_frompdf.tex"
( cat header.inc ; tail -n +7 "${file}_frompdf.tex" ) > "${file}_frompdf_fixedup.tex"
echo

echo "Converting ${file}_frompdf_fixedup.tex to ${file}_frompdf_fixedup.pdf for inspection..."
pdflatex -interaction nonstopmode "${file}_frompdf_fixedup.tex" > tex_to_pdf_errors_and_warnings.txt
echo

echo "Opening ${file}_frompdf_fixedup.pdf with Evince - you can try another PDF viewer if you like..."
evince "$file"_frompdf_fixedup.pdf

The script uses one extra file, header.inc, which contains customizations:

\documentclass[a4paper,11pt,oneside]{article}
\usepackage{a4wide}                     % Iets meer tekst op een bladzijde
\usepackage[dutch]{babel}               % Voor nederlandstalige hyphenatie (woordsplitsing) en het euro-symbool
\usepackage{amsmath}                    % Uitgebreide wiskundige mogelijkheden
\usepackage{amssymb}                    % Voor speciale symbolen zoals de verzameling Z, R...
\usepackage{url}                        % Om url's te verwerken
\usepackage{graphicx}                   % Om figuren te kunnen verwerken
\usepackage[small,bf,hang]{caption}    % Om de captions wat te verbeteren
\usepackage{xspace}                     % Magische spaties na een commando
\usepackage[utf8]{inputenc}           % Om niet ascii karakters rechtstreeks te kunnen typen
\usepackage{float}                      % Om nieuwe float environments aan te maken. Ook optie H!
\usepackage{flafter}                    % Opdat floats niet zouden voorsteken
\usepackage{listings}                   % Voor het weergeven van letterlijke text en codelistings
\usepackage{marvosym}                   % Om het euro symbool te krijgen
\usepackage{eurosym}                   % Om het euro symbool te krijgen
\usepackage{textcomp}                   % Voor onder andere graden celsius
\usepackage{fancyhdr}                   % Voor fancy headers en footers.
\usepackage{graphics}                   % Om figuren te verwerken.
\usepackage[a4paper,plainpages=false]{hyperref}    % Om hyperlinks te hebben in het pdfdocument.
\usepackage[usenames,dvipsnames]{xcolor}

% Definitie algemene macro's
\newcommand{\npar}{\par \vspace{0.2ex }}

\setlength\textheight{9.75in}
\setlength\textwidth{7in}

\topmargin -0.5in 
\headheight 0.0in
\oddsidemargin -.25in 


[Update] You can also try the following method, using abiword, but the method above yields better results, in my opinion:

abiword --to=tex "filename.pdf"

zaterdag 5 mei 2012

Please don't blame the weather

Please don't blame the weather
It’s got nothing to do with the weater.

Blame me and sincerely blame yourself.


Try waking up in the morning and
feeling better than the day before.


Wash off your guilt, get over yourself,
and stop wasting time persuing shit.


Contemplate life’s meaning and
the sadness of existence.

donderdag 1 maart 2012

Keycodes and coffeeshops in the Linux kernel

We are using gpio-keys to configure 2 GPIO's coming from 2 sensors (left and right on our device) as keyboard interrupt lines.

So I had to choose 2 obscure keycodes to map on "proximity meter left" and "proximity meter right"...

Here are the results:

        {
                .gpio           = INT_PROX_L,
                .code           = KEY_COFFEE,
                .desc           = "Proximity Left",
        },
        {
                .gpio           = INT_PROX_R,
                .code           = KEY_SHOP,
                .desc           = "Proximity Right",
        },

These keynames and their order are easy to memorize now, because (since we read from left to right) we know that coffee = left and shop = right :-)

zondag 8 januari 2012

rsync and scp autocompletion

Apparantly, rsync and scp boast tab autocompletion !

When you have configured passwordless SSH access (by copying over your public key) and you use these tools, tab autocompletion works as expected.

For example, typing the following on a bash shell:

rsync localfile.txt exampleserver:/examp<TAB>

will automatically autocomplete the foldername.
In the example's case, it becomes:


rsync localfile.txt exampleserver:/examplefolder/


The same goes for scp, like:


scp localfile.txt exampleserver:/examp<TAB>


becomes


rsync localfile.txt exampleserver:/examplefolder


rsync and scp are able to do this because the passwordless SSH allows them to see what files can be found on the other server without asking for a password.

On my LAN network, it takes about 1 second to autocomplete, which is perfectly acceptable for me. It certainly beats having to open a seperate SSH session and manually making a lising ;-)

Super-sleek shell script as a simple touchscreen controller for Linux

#!/bin/sh

# Beautifully simple shell script to detect screen touches

# I use it to toggle the music player on my FriendlyARM 2440 Mini
# but it can be used for any Linux touch screen


# Copyleft 2011 - t-Omicr0n

while true; do
     head -c 1 /dev/input/event0
     echo "You touched it !"
done &

Hunting advice

Let's say you're a hunter. If a deer takes your gun, shoots itself and then straps itself to the roof of your car..... you have to take it home and eat it ! -- Two and a Half Men

donderdag 15 september 2011

Calculating significance indicates insignificance

Calculating significance indicates insignificance -- Jasper Nuyens, 2011

dinsdag 6 september 2011

Joan Halifax's "Compassion"

Equanimity is a state of mental or emotional stability or composure arising from a deep awareness and acceptance of the present moment.

Great TED talk: Joan Halifax: Compassion and the true meaning of empathy