Tuesday, July 6, 2010

How to truncate an HTML/XHTML/XML snippet in PHP

<?php
function xmlentities($xml) {
return str_replace ( array ( '&', '"', "'", '<', '>' ), array ( '&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;' ), $xml);
}

function char_limit($text, $char_limit, $append = '...') {
$tok = strtok($text, " \n\t");
$result = '';

while ($tok !== false) {
if (strlen($tok) + strlen($result) + 1 <= $char_limit) {
$result = $result . ' ' . $tok;
} else {
$result .= $append;
break;
}
$tok = strtok(" \n\t");
}

return $result;
}

class TruncatingParser {
var $tagStack = array();

var $bufferedCdata = NULL;
var $out = '';
var $append = '';

var $maxChars = -1;
var $currentChars = 0;

function startElement($parser, $tagName, $attrs) {
$this->flushCharacterData();

if ($this->currentChars < $this->maxChars) {
$this->out .= '<' . $tagName;

foreach ($attrs as $key => $value) {
$this->out .= ' ' . $key . '="' . xmlentities($value) . '"';
}

$this->out .= '>';

$this->tagStack[count($this->tagStack)] = $tagName;
}
}

function endElement($parser, $tagName) {
$this->flushCharacterData();
if ($this->currentChars < $this->maxChars) {
$this->out .= '</' . $tagName . '>';
array_pop($this->tagStack);
}
}

function characterData($parser, $data) {
if ($this->currentChars < $this->maxChars) {
if ($this->bufferedCdata == NULL) {
$this->bufferedCdata = $data;
} else {
$this->bufferedCdata .= $data;
}
}
}

function flushCharacterData() {
if ($this->bufferedCdata != NULL && $this->currentChars < $this->maxChars) {
if ($this->currentChars + strlen($this->bufferedCdata) >= $this->maxChars) {
$charLimit = $this->maxChars - $this->currentChars;
$this->out .= xmlentities(char_limit($this->bufferedCdata, $charLimit, ''));
$this->out .= $this->append;

$this->currentChars = $this->maxChars;

while ($tag = array_pop($this->tagStack)) {
$this->out .= '</' . $tag . '>';
}
} else {
$this->out .= $this->bufferedCdata;
$this->currentChars += strlen($this->bufferedCdata);
}
}
$this->bufferedCdata = NULL;
}
}

function xml_char_limit($text, $char_limit, $append_text = '') {
$parser = new TruncatingParser();
$parser->maxChars = $char_limit;
$parser->append = $append_text;

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);

xml_set_object($xml_parser, &$parser);

xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

$text = '<div>' . $text . '</div>';

if (!xml_parse($xml_parser, $text, TRUE)) {
return '';
}

xml_parser_free($xml_parser);

$out = $parser->out;

// Strip out the temporary root tag that was added
$out = substr($out, 5, strlen($out) - 11);

return $out;
}
?>

Thursday, June 10, 2010

One-jar

If you're getting this error from one-jar, make sure you declared your main method as static.

Exception in thread "main" java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.simontuffs.onejar.Boot.run(Boot.java:306)
at com.simontuffs.onejar.Boot.main(Boot.java:159)

Monday, June 7, 2010

Hack for generating a random number in a script without $RANDOM

let "rand = 0x`dd if=/dev/urandom bs=4 count=1 2> /dev/null| md5sum | sed 's/................ .*//'`"

Thursday, May 27, 2010

Inserting CSS in HEAD with ModX

One of the neat things about ModX (or any CMS, really) is that you divide your HTML into chunks and reuse them across pages. Great as this is, it makes managing CSS a little annoying since you don't have any direct access to <head>.

Here's a quick snippet that solves that problem. Just insert [[register_css?file=`/assets/css/foo.css`]] in your template, page, or chunk, and create a snippet with this code:

if ($file) {
$modx->regClientCSS("<link rel='stylesheet' type='text/css' href='$file'></link>");
}
?>

Friday, November 27, 2009

How to flash your BIOS from a CD with free software

  • First, get your BIOS from your motherboard manufacturer.
  • Extract the files to a place you can remember.
  • Install CDBurnerXP.
  • Grab the FreeDOS "Balder" image.
  • Fire up CDBurnerXP.
  • Create a new data disc.
  • Drag the BIOS and flasher to the disc.
  • Go to "Disk," "Boot options."
  • Enable "Make disc bootable" and point the image to the FreeDOS "Balder" image.
  • Burn the CD.
  • You now have a CD you can use to flash your BIOS, all with free software.

Thursday, September 17, 2009

How to manually draw to an OpenGL ES texture

// Create steam texture. It's just a transparent circle
texture = 0;
GLubyte *textureData = malloc(sizeof(GLubyte) * 4 * (radius * 2) * (radius * 2));
memset(textureData, 0, sizeof(GLubyte) * 4 * (radius * 2) * (radius * 2));
unsigned int index = 0;
for (int y = 0; y <>
for (int x = 0; x <>
float d = sqrt((x - radius) * (x - radius) + (y - radius) * (y - radius));
if (d <= radius) {
GLubyte alpha = 255 * (int)(radius - d) / radius;
textureData[index++] = 250;
textureData[index++] = 250;
textureData[index++] = 255;
textureData[index++] = alpha;
} else {
index += 4;
}
}
}

// allocate a texture name
glGenTextures(1, &texture);
// select our current texture
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// build our texture mipmaps
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, radius * 2, radius * 2,
0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
// free buffer
free(textureData);

Sunday, July 5, 2009

TV color calibration

Recently, I had a TV I needed to calibrate the color on. I found a great guide, but it called for a Digital Video Essentials calibration DVD for just a few gray frames that were hidden--and some missing--on the DVD. If you have a DVD player or TV that can show jpegs from either flash or a CD/DVD, this might be easier than using a feature-laden DVD.

With the first image (PLUGE), the idea is to be able to see the lightest dark square (IRE 4), but not the darkest square.


The following set of images is used to measure red, green, and blue levels of grays and varrying intensities and to try to get them as close to the same as possible. You need some sort of color meter (the X-Rite Eye-One and Datacolor Spyder are covered in the guide) and software like ColorHCFR to measure the output. Again, see the guide for more details. I'm just providing IRE and PLUGE files hoping to save people time and money. Like the DVE DVD, the IRE corresponds to the k values (as in CMYK) of the color, not linear RGB values.