NIEDZIELSKI.COM
 

Sizing Tab Stops in HTML & CSS

  HTML and CSS have poor support for tabulation. The tab character (&#09;) is only rendered within preformatted tags (<pre>). There’s almost no control over the width of tab stops, as described in the CSS3 working draft:

  ’A tab (U+0009) is rendered as a horizontal shift that lines up the start edge of the next glyph with the next tab stop. Tab stops occur at points that are multiples of 8 times the width of a space (U+0020) rendered in the block’s font from the block’s starting content edge.’

  The HTML 4.01 specification describes tab stops differently:

  ’The horizontal tab character (decimal 9 in [ISO10646] and [ISO88591] ) is usually interpreted by visual user agents as the smallest non-zero number of spaces necessary to line characters up along tab stops that are every 8 characters. We strongly discourage using horizontal tabs in preformatted text since it is common practice, when editing, to set the tab-spacing to other values, leading to misaligned documents.’

  I find that trying to hack around this by adjusting font size works in Firefox, but not Internet Explorer or Opera:

<pre style='font-size: 2.5pt'>
	<span style='font-size: 10pt'>text</span>
</pre>

  The above example will show a tab width of 2 characters in Firefox 3.0.13.

  Sometimes I require a literal tab character, spaces or other kluges will not suffice. Particularly, for makefile snippets which do not function properly with spaces. The HTML GNU Make manual cautions scripters to use tabs as appropriate, but otherwise seems to ignore the issue and uses spaces throughout all their examples.

  There’s a working draft for adding control of tabbing attributes in CSS, but it’s dated Jan., ‘97. Dave Raggett, author of aforementioned draft, said it wasn’t accepted by MS or Netscape.
  Dave directed me to Bert Bos for present details on the issue. Bert replied with an extensive email that outlined all general use cases for tabs and stated that this particular issue had been discussed since the beginning of CSS but never published due to its low priority in the world of tabulation troubles.
  Finally, there used to be a tab tag in HTML 3 .

  And that’s why my makefile snippets look terrible.

RSS Email Notifications for WordPress

Introduction
  I share a group blog at waterblogged.net with a couple friends. I wanted to get regular email notifications containing complete content for new entries and comments, even for password protected feeds. Some email clients provide varying support for RSS feeds, but I’m a Gmail user and at present this support is very limited. So, I wrote a couple scripts that run on my web server. This documents makes a couple notes and provides links to the source.
  As a disclaimer, a big goal of this project was experimentation. The other part being that the end product work specifically for my configuration, in particular, a WordPress blog. Areas of my scripts drift between wildly impractical to very hackish. There were many solutions to this problem and I’m certain what I present is not ideal.

mr_wb.mk – master script
  This makefile wraps all operations in one. In retrospect, I think it would be better to have written this in Python, but I also wanted to experiment. Assume spaces are tabs as appropriate when copying snippets or grab the original source.
  This useful snippet from the GNU Make manual provides fast PATH searching:

path_search	=	\
	$(firstword $(wildcard $(addsuffix /$(strip $(1)),$(subst :,$(space),$(PATH)))))

  Here I experiment with makefile error handling which is basically BASH error handling. I force immediate trap on commands returning non-zero status and print some info.

red				:=	'\e[1;31m'
colorless	:=	'\e[0m'
begin_rule	= \
	set -e; \
	set -o pipefail; \
	function err_trap() \
	{ \
		echo "error: $$BASH_COMMAND returned $$1 at time $(exec_date)."; \
	}; \
	trap 'err_trap $$?;' ERR; \
	echo -e $(red)--- rule: $@ ---$(colorless)

end_rule	:= \
	echo --- done ---

format_feed.py – new feed item to HTML email
  This script uses Universal Feed Parser to parse a downloaded comment or entry feed. If new items are found since last execution, they are extracted and converted to a rich text HTML file.

print_missing_modules.py – Python prerequisite checking
  This is one of those wildly impractical parts of the script I mentioned I was experimenting with earlier. I ended up canning this feature since the modulefinder module prints a ton of missing modules but most scripts usually run anyway.

cron – regular script execution
  Nothing special going on here for cron junkies, but this was my first time, actually, so I’ll explain it in brief. Cron provides for regular execution of arbitrary scripts. A tab delimited format describes regularity and command. For further information, Wikipeda has a nice article. In my case, my cron script looks something like:

*/9  *  *  *  *  make -C scripts/mr_wb -f mr_wb.mk -rR --warn-undefined-variables;

  Please imagine the spaces surrounding the asterisks as tabs. This script causes Make to be invoked every 9 minutes of every hour. I launch the Cron service by typing crontab .crontab (this script being named .crontab).

  Download the file archive here.

opaque types in C89

Introduction
  I’ve been fascinated with exploring different object oriented programming techniques in C89 since I started C++ coding a few years back. I only recently concluded my exploration of opaque types. I think they’re interesting but impractical.

Definition of Opaque Type
  A user data type, normally a struct, that presents no public member variable interface.

Example Case
  The following examples were compiled with ‘gcc -std=c89 -Wall’:

/* opaque.h */
#ifndef __OPAQUE_H__
#define __OPAQUE_H__

struct opaque_type;
typedef struct opaque_type opaque_type;
extern const unsigned sizeof_opaque;

void opaque_init(opaque_type * o, unsigned data);
unsigned opaque_data(const opaque_type * o);

#endif

  There’s no implementation in the above header, only declarations. Clients are unaware of implementation, their only interface is provided by the function prototypes.

/* opaque.c */
#include “opaque.h”

struct opaque_type
{
  unsigned data;
};

const unsigned sizeof_opaque = sizeof(opaque_type);

void opaque_init(opaque_type * o, unsigned data)
{
  o->data = data;
}

unsigned opaque_data(const opaque_type * o)
{
  return o->data;
}

  The above source contains the implementation for the opaque type. This implementation has file scope and is unknown at compile time to all other files in the build.

/* main.c */
#include <stdio.h>
#include “opaque.h”

/* not permitted: variable sized type outside function.
unsigned char mem[sizeof_opaque];
*/

opaque_type * o;

int main()
{
  /* not permitted: size unknown.
  opaque_type o;
  */
  unsigned char mem[sizeof_opaque];

  o = (opaque_type *)mem;

  opaque_init(o, 10);
  printf(“%u\n”, opaque_data(o));

  return 0;
}

  The above source shows how a client may interface with the opaque type.
  Now that we see how most implementations may be written, let’s look at a simpler case. Here’s what it would like if we stuffed it all in main.c:

/* main.c */
#include <stdio.h>

/* forward declarations. */
struct opaque_type;
typedef struct opaque_type opaque_type;
extern const unsigned sizeof_opaque;

void opaque_init(opaque_type * o, unsigned data);
unsigned opaque_data(const opaque_type * o);

/* client code. */

/* not permitted: variable sized type outside function.
unsigned char mem[sizeof_opaque];
*/

opaque_type * o;

int main()
{
  /* not permitted: size unknown.
  opaque_type o;
  */
  unsigned char mem[sizeof_opaque];

  o = (opaque_type *)mem;

  opaque_init(o, 10);
  printf(“%u\n”, opaque_data(o));

  return 0;
}

/* opaque implementation. */

struct opaque_type
{
  unsigned data;
};

const unsigned sizeof_opaque = sizeof(opaque_type);

void opaque_init(opaque_type * o, unsigned data)
{
  o->data = data;
}

unsigned opaque_data(const opaque_type * o)
{
  return o->data;
}

Analysis
  The example case demonstrates that it is impractical to allocate opaque types at compile time. Since the opaque_type implementation is unknown in main, the compiler cannot instantiate an object of this type. Hacking around this problem by making an opaque_type * and assigning statically allocated memory works, but you can only make the allocation in function scope. In systems permitting dynamic allocation, this may not be an issue. Even an opaque_ctor() function could be defined.
  This case also shows there’s no partial public / private interfaces possible. It’s all public or all opaque. Consequently, this means that every member variable to be exposed must have an associated getter and setter function. This may cause poor code optimization in our multiple file example since the implementation will be unknown at compile time and the compiler will be unable to eliminate the overhead of a function call. The exception here is if the compiler generates intermediate code in the object files to allow for optimizations in the linking step.

Conclusion
  I like simplicity, I like static allocation, and I’m not a huge fan of universal setters and getters no matter the context. It should come as no surprise that I don’t like opaque types.