# Tahir Hassan's Blog

My Technical Notes

## Tuesday, 28 March 2017

### Using Gimp for precise cropping

Gimp is an excellent tool for precisely cropping an image. Once Gimp is loaded, you an open an image by either using File → Open (Ctrl-o), or using invoking Gimp from the command line passing in the path of the file. Because Gimp takes a long time to load, it is not worth having multiple instances of it open; rather, have one instance open, and open the files you wish to edit in this one instance.

Once you have opened the image in Gimp, select the cropping tool:

Draw a rectangle anywhere on the screen. In the Tool Options, in the Size textboxes, set the aspect ratio, for example, 16 by 9.Then tick Fixed and select Aspect Ratio drop the drop down:

Because the aspect ratio is fixed, if you enter a new size value in the Size textbox and tab out of it, the other size value will change according to the ratio.

Drag the rectangle around to capture your desired region. Click on Image → "Crop to Selection". Save this new image.

## Monday, 27 March 2017

### Converting ORG to PDF with custom CSS styling

OrgMode is a very simple and easy to use plugin for Emacs that allows you to organize yourself using text only.

One drawback of it is that Emacs/OrgMode has a high learning curve: too many keyboard shortcuts to remember, requires use of lisp to customise output etc.

However, its main strength is that OrgMode files are purely text - and text is very easy to process.

Emacs OrgMode already has PDF output capability (via LaTeX). However, to style its output, you have to use custom Lisp functions containing LaTeX code. As I am unfamiliar with both LaTeX and Lisp, I wanted to use familiar technologies, such as CSS, to style the content, and use Emacs purely for editing the OrgMode files.

Installing Pandoc   Pandoc needs to be installed first.

Installing wkhtmltopdf   wkhtmltopdf also needs to be installed because that is what actually does the HTML to PDF conversion. You also have to add C:\Program Files\wkhtmltopdf\bin to the PATH variable so it is visible to Pandoc.

Including CSS   Below is a sample css file sample.css which makes .done tasks green:


.done {
color: green;
}


Place it in the same folder as the .org folder for the commands below, which reference its path, to work.

OrgMode file   The commands will be run against the following OrgMode file, doc.org:


* DONE this is a done task
* DONE this is a second done task.


Pandoc Command   Execute the following command to create doc.pdf from doc.org:


pandoc -t html5 --css sample.css doc.org -o doc.pdf


The -t html5 in the command ensures that it uses wkhtmltopdf to create the PDF document instead of LaTeX.

#### Sources

• StackOverflow.com An answer explaining the user of pandoc to convert OrgMode to PDF

## Saturday, 25 March 2017

### Generating Random Strings in PowerShell

As part of unit testing my PowerShell functions, I have noticed a small potential issue with having data hard-coded into unit tests. Such tests can be made to pass by hard-coding the answer in the tested function. For instance we could have a unit test for a function called Concat-String that takes two string arguments and concatenates them together:


$result = Concat-String "Tahir" "Riyadh" Assert-AreEqual "TahirRiyadh"$result


Such a test could easily be passed by hard-coding a return value:


Function Concat-String([string]$First, [string]$Second) {
}


(Of course, a unit-testing purist would say that you need multiple tests to prevent the possibility of hard-coded values, but that is besides the point - I only want to write one unit test, not many versions of the same test with different data).

Instead, what I am now using to generate test data is the following function, New-RandomString:



Function New-RandomString {
param([Parameter()][int]$Size=10)$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_".ToCharArray();

$bytes = & {$data = [byte[]]::new($Size)$crypto = [System.Security.Cryptography.RNGCryptoServiceProvider]::new();
$crypto.GetBytes($data)
$data }$str = [char[]]($bytes | % {$_ % $chars.Length } | % {$chars[$_] }) [string]::new($str)
}


Instead of hard-coding test data in the unit test, New-RandomString can be used to give appropriate test values:


$firstVal = New-RandomString 15$secondVal = New-RandomString 20
$result = Concat-String$firstVal $secondVal$expected = $firstVal +$secondVal
Assert-AreEqual $expected$result


Such a test cannot be passed by hard-coding a correct return value. It can also be run multiple times to ensure that it passes i all cases.

## Wednesday, 22 March 2017

### Using DebugView for Debugging AutoHotkey Scripts

DebugView is an application made by SysInternals that can be used to view debug messages produced by applications.

To create a debug message using AutoHotkey, use the OutputDebug command:


OutputDebug, Hello World


Because many other applications also produce debug messages, you want to be able to show only those messages produced by your AutoHotkey script. For this, you can wrap the above command in a function that prepends [AHK]  to messages to make them searchable:


DebugMsg(Msg) {
OutputDebug, [AHK] %Msg%
}


This function is called by passing in a string argument, as below demonstrates. The result is that [AHK] Hello World will appear in DebugView's message list.


DebugMsg("Hello World")


#### Configuring DebugView

##### Filter to only include [AHK] messages

To configure DebugView to only show messages from AutoHotkey, first show the "DebugView Filter" dialog, by either doing Ctrl-L or Edit → Filter/Highlight. In this dialog, in the Include field, add [AHK]* and press OK. This will not filter existing messages in the list, only new ones.

##### Highlighting messages by color
To highlight messages containing some text by color, first select a Filter from the list, and then in the colored textbox below it, enter some text to highlight:

Strangely enough, in contrast to the filtering behavior only affecting newly captured messages, the highlighting affects existing messages too.

##### Other...

If DebugView is not capturing messages (with filter set as *), then you may have to run it as administrator.

## Sunday, 19 March 2017

### Resizing Images using ImageMagick on Windows

ImageMagick is a handy commandline tool for every major platform that can be used to resize images (among its other uses). To install it on Windows, the recommended installer ImageMagick-<version>-Q16-x64-dll.exe worked fine and added magick.exe to the PATH. The installer recommends installing GhostScript for processing PDF and GhostScript, but because we are only using it to resize images, there is no need to install it.

When resizing an image, it is worth thinking about how big you want the resized image to be. To simplify matters, you can think of the resized image as fitting into a rectangle of $n$ by $m$ pixels. When an image is resized, its aspect ratio is maintained, but it has to fit inside this rectangle.

For illustration purposes, we use magick.exe to create a sample image file, wizard.jpg:


magick.exe wizard: wizard.jpg


This image is $480$ by $640$ pixels in size. For simplicity, let's say that we wish to shrink it so that it fits inside a $400$ by $400$ square. Its larger side (vertical), which is $640$, becomes $400$, therefore this side has shrunk by a percentage, $400/640$, which is $.625$. Its horizontal therefore will be $480 * .625$, which is $300$. In summary, the resized image will be $300$ by $400$ pixels in size.

To shrink it to this size, do:


magick.exe wizard.jpg -resize 400x400 resized-wizard.jpg


### Adding a .cmd wrapper for an executable

When wanting to invoke an .exe on the commandline without specifying its full path, the usual course of action is to modify the PATH environment variable to include the .exe file's directory. A simple alternative, as described here, is to to create a .cmd wrapper for the .exe and place it in a folder which is already on the PATH environment variable.

An example git.cmd file is shown below. As mentioned earlier, you must put this .cmd into a folder which is in PATH environment variable.


@echo off
"C:\Program Files\Git\bin\git.exe" %*


@echo off disables echoing, and %* passes along all incoming arguments to the git executable.

On the Windows command-line, whether CMD or PowerShell, you can invoke an .exe, .bat or .cmd without specifying the .extension.

## Saturday, 18 March 2017

### PowerShell: Get a Service's Description

The result of Get-Service is a set of System.ServiceProcess.ServiceController objects, a type which does not have a property for the description shown in the Windows Services Window. The below sample code shows how to get the description for of the XboxNetApiSvc service.


& {
$svc = [System.Management.ManagementObject]::new("Win32_Service.Name='XboxNetApiSvc'")$svc["Description"];
\$svc.Dispose();
}


In order to get the description for a ServiceController object, pass in the object's Name property in place of XboxNetApiSvc.