Archive for February, 2007

Easy acronyms generation

February 22, 2007

At work, we needed a way to easily generate a list of acronyms of our documents, so I wrote an script (tex-acronyms.py) that parses the acronyms in a specified LaTeX file and tries to find a description (specified as a nomencl definition) in the files (*.tex) located in a directory. The script will create two files: one with acronyms and their descriptions and the other with conflicts, that is, acronyms with no or duplicate description.

The following example is a sample of an acronyms list file. Note that the LaTeX document must use the nomencl package, since the acronyms are defined using the nomencl syntax.

\\nomenclature{ADDR}{Address}
\\nomenclature{ANSI}{American National Standards Institute}
\\nomenclature{API}{Application Programming Interface}
...

It is also possible to provide a list of words to be excluded in the exclude_acronyms.txt file, that must be located in the data directory by default (a different file can be specified using -x). For example:

CHAPTERS
CLOSED
DUPLICATE
FIRST
FIXED
BOTH
BUS
...

It is easy to find words to be excluded because they will be treated as errors (and written to the errors file) as no definition is available for them.

Finally, it is possible to parse the input files recursively passing the -r argument. This will parse all the files included with \input.

A possible program call could be:

tex-acronyms.py -r -d ~/acronyms -i article.tex -o acronyms.tex \
                -e acronyms.errors

where the acronyms found in the article.tex file (and its dependencies) will be matched against the acronyms found in ~/acronyms/*.tex. The matched acronyms will be written to acronyms.tex and the errors in acronyms.errors. Now, you just need to include acronyms.tex in your document.

Update 2010/10/22: Check script updates in the new article More on easy acronyms generation.

Update 2007/02/23: GlossTeX does the same (and much more) but à la TeX way.

Advertisements

Designated initializers

February 19, 2007

Last year, I discovered, thanks to the book “C, A Reference Manual“, a great C99 feature: designated initializers. Designated initializers allow you to initialize components of an aggregate (structure, union or array) by specifying their names within an initializer list.

Arrays initialization

What most people normally use to initialize an array is the following idiom:

int v[4] = { 4, 2, 1, -5 };

in which you need to initialize each component of the array sequentially. Designated initializers allow you to specify which component of the array you want to initialize. Thus, we could write the line above as:

int v[4] = { [1] = 2, [2] = 1, [0] = 4, [3] = -5 };

Note that we have specified the component indexes which has allowed us to initialize the array with our desired order. If we do not initialize all the components, those not initialized will get 0 values. We can also mix both methods, so the line below would be also correct:

int v[4] = { [1] = 2, 1, [3] = -5 };

in which the component not referenced goes right after the named one.

A possible use of this kind of initializations would be a mapping between a list of identifiers and a list of strings.

// The public interface

typedef enum {
  id_one,
  id_two,
  id_three
} id_t;

extern char const* string_by_id (id_t id);

// The private implementation

static char const* strings[] =
{
  [id_one] = "identifier one",
  [id_two] = "identifier two",
  [id_three] = "identifier three"
};

char const*
string_by_id (id_t id)
{
  return strings[id];
}

Structures and unions initialization

Designated initializers are also useful to initialize components of structures and unions by their name. In this case, the component to be initialized takes the form .c, where c is the name of the component. So, suppose we have the following structure:

struct point { float x; float y; float z; };

we could initialize each component of a struct point variable like this:

struct point my_point =
{
  .x = 0.34,
  .y = 0.98,
  .z = 1.56
};

With unions, we will use the same method, so having the following union:

union integer
{
  unsigned char int_8;
  unsigned short int int_16; 
  unsigned long int_32;
};

we can initialize it by any of its components:

union integer value = { .int_16 = 24000 };

Finally, we can merge both cases, so we can have arrays of structures or unions that can be initialized using designated initializers:

struct point pointvector[3] =
{
  [0].x = 0.34, [0].y = 1.78, [0].z = 3.18,
  [1] = { .x = 3.5, .y = 6.89 },
  [2] = { .y = 2.8, 1.23 }
};

Split <VirtualHost> directives into multiple files

February 15, 2007

Yesterday, I found out that I needed an application to split the virtual hosts of an Apache 1.3 configuration into separate files so I could use them in the sites-available/sites-enabled Debian‘s Apache 2 way. I googled just a bit and I did not find anything so I did my own one (vhost-split.py).

Just pass it the configuration file and the script will generate a bunch of files named with the ServerName variable found in each virtual host. Note that repeated entries will generate separate files (http://www.mydomain.com, http://www.mydomain.com-1, …). The script will also report commented entries.