Rtf2Html 1.2

I made some updates to the lightweight rtf to html converter I created a while back.

Changes include:

  • Context menu for textboxes, making it easy to select, cut, copy, paste, etc.
  • Ability to view a preview of the output to ensure correct result.
  • String for color hex values are now simplifed, if possible. (e.g. #0000ff = #00f). This, in a small way, conserves space.
  • Support for a few basic special entities, less-than sign, greater-than sign, quotation mark, and ampersand. Also, the copyright symbol is converted into it’s appropriate special entity (this allows compatibility with older browsers and/or content w/ non-unicode character sets)
  • Conversion of newline characters to <br /> elements.
  • The executable now has a cool icon.
These are in addition to the previous formatting options supported: text color, bold, italic, underline, and strike-thru.

Not supported are: font-type, font-size, bulleted lists, paragraph alignment, bold-italic font-style. I’ll probably look into these in the future. They’re not difficult to implement, but, especially when embedding within existing HTML content, it’s beneficial to be able to toggle these options on and off (specifically off, as it may be better for the styles of the parent element to be inherited in certain cases). The work of updating the interface + implementing these additional options is more than I’d care to undertake at this time. Especially as this app is only meant to format source code that I post here.


How to open the containing folder

Opening a window showing the contents of a folder and highlighting a specific file in the folder can be a pretty useful action, especially for applications that show or list files to the user, as it allows for the user to quickly get to a file and manipulate or open it via. the operating system’s shell. The most popular implementations of this features are, perhaps, in web browsers; it’s referred to by a couple of different phrases, “Open Folder” in IE7, “Show Containing Folder” in Safari, “Open Containing Folder” in Firefox.

Anyways, I wanted this feature for something I’m working on in Windows and it’s actually pretty simple to implement, but it took me a while to find information on it. There’s no Win32 function, instead, explorer has to be run with a command-line switch. Switches and accompanying examples can be found here.

So the command to open a containing folder would be:

explorer /select, <file_path>

Here’s a bit of C# code (it should be simple to do this in almost any language):

System.Diagnostics.Process p1 = new System.Diagnostics.Process();
p1.StartInfo.FileName =
"explorer";
p1.StartInfo.Arguments =
"/select, \"" + <file_path> + "\"";
p1.StartInfo.WorkingDirectory =
Environment.GetEnvironmentVariable("SystemRoot");
p1.StartInfo.UseShellExecute =
true;
p1.Start();

Of course, replace <file_path> with the file you want highlighted.

Based on the info here, as well as the page linked to above, it seems this should work on all versions of Windows since Win 95.


More background:transparent woes in IE

A similar issue to the one I mentioned in my previous post. The problem is the same, the behavior of anchor elements is broken, however, the cause seems to be different.

background transparent issue

The image above demonstrates the issue. The area enclosed by the blue box is the anchor element. It’s a block-level element (display:block) and positioned using position:absolute. The area enclosed by the white lines is part of a paragraph element. When the paragraph element overlaps the anchor element, the functionality of the anchor element is broken (oddly, the functionality on the border of the anchor element is still active).

I’ve found two solutions.

  • Reduce the width of the paragraph element or it’s container to prevent the overlap
  • Use a transparent gif for the background of the anchor element. The same solution for the issue described in my previous post


background:transparent and filter:alpha in Internet Explorer

I’ve previously expressed dissatisfaction w/ the look of my homepage but apparently there were functional issues as well. I never did a thorough test of the page in IE (either version 6 or 7), just a quick glance to see that the layout was correct, this bit of carelessness bit me in the ass as I’ve recently discovered the links weren’t working in IE.

The problem was the result of IE not allowing background:transparent AND filter:alpha on the anchor elements. Having both breaks the behavior of the elements (i.e. they don’t function like links and you can’t click on them). I needed the filter attribute for the translucency effect, so my fix was to simply use a 1×1 transparent gif for the needed transparent background.

background filter issue pic

oh, and these links are somewhat weird. They have no content, they’re just empty block elements absolutely positioned on top of their parent div (whose background image contains the text identifying the link’s function to the user). When hovered over, their background changes to a image that gives them a border. When clicked, their background changes to black and opacity decreases so it’s a translucent shade over the parent div. When unselected (i.e. another link is clicked), they have to go back to being transparent where the user sees right through to the parent div.


Programs and Files

This post is about an idea, a simple idea:

End-users of a PC should be able to transfer their programs between computers and easily as they transfer their documents.

There is of course the issue of OS and hardware dependency for applications, but even from one x86, 32-bit, Windows machine to another, transferring a program is a non-trivial process. Yet, from a technical point of view, there seems to be little justification for things to be this way.

So what is a program really and why is it so difficult to move them around?
(Note: This is primarily dealing with Windows and I’ll be referring to Windows 2000/XP/Vista constructs, however, the situation isn’t any better on OS X or Linux)

Part 1: Back to Basics
A program is just data. Some of it is logic (executable files, stuff executed on the CPU) and some of it is just raw information (images, music, settings, user information, etc.). All of this data, at some level, is contained in files.

Files are great because users understand files, they understand the concept itself (a file is an atomic unit of data) and execution of the concept on almost any operating system is such that working with and manipulating files (moving, copying, etc.) is trivial for all but the most illiterate computer users. This is likely why all user documents are single files. This ease-of-use, I believe, surfaces due to the atomicity of a file; everything about a file is within the file itself, and the metadata for a file (file size, time stamp, etc.) is managed and/or computed dynamically by the file system.

When dealing with multiple files that share a common function or purpose, aggregating files becomes necessary and as such we get to the concepts of directories and tags. While there are ways to make either work for what I’m going to describe, I’ll stick to directories as it’s a more familiar concept in the realm of the desktop.

Like files, users understand directories because of their simplicity in concept and execution, and as with files users are familiar with manipulating them. This simplicity comes about due to the fact that, like files, directories can be seen as atomic units of data. While looking inside a directory and seeing a mishmash of files makes it seem very much non-atomic, it is also a homogeneous container (it stores only files) and therefore, it can be viewed as a single object, a container, and this container can, for the most part, be manipulated as a single object, much like an individual file can. While their atomicity is important for ease-of-use by an end-user, directories are also important because they relate to the coupling of files. As mentioned, files within a directory share a common function or purpose, this is undoubtedly true for programs; each directory for a program contains files which are essential to its function (e.g. all of the files in my \Program Files\XML Notepad 2007\ directory relate to the functionality of XML Notepad). This coupling is important because it allows for easy organization, maintenance, and access to the program and it’s program-specific data.

Now to the crux of the matter, if programs are just files, and files are coupled together in directories, it should follow that we can move programs around by just copying directories. Unfortunately this is not the case because the coupling between a program’s logic and some specific pieces of information belonging to it are not coupled together in the same directory. While Windows users may assume that each subdirectory in \Program Files contains all the files for a program, this is not (in general) true, the files in these subdirectories represent only part of their program. The additional pieces of information are contained in the the system registry and/or somewhere within the Documents and Settings folder. This lack of coupling is the reason transference of programs between PCs is difficult and to tackle the problem tighter coupling must be provided while maintaining the operating system features provided by the registry and the Documents and Settings directory.

Part 2: The Registry
First off, the system registry is a nightmare. I can’t imagine who conceived of the idea that storing application level data and critical system specific data in the same location and allowing free access to it all would be a good thing. So much of our current malware, adware, spyware, etc. headaches have been caused by programs doing bad things to the registry. Additionally, although you can technically backup the registry easily, I’ve encountered errors restoring it which makes the backup useless and the only recourse is to reinstall applications just so they can rewrite their registry information. It should also be noted that most typical users I’ve encountered don’t know what the registry is or have a backup of it, but the more important question is, why should they? It’s a construct that simply appeases the operating system, it’s functional benefits could easily be refactored in more user friendly ways.

So, relative to a program, what’s actually in the registry?

  • Program-specific settings.
  • System-wide settings related to a program (e.g. file associations, uninstallation information, stuff that shows up in the OS shell).
The registry is deprecated for the first issue (so I’ve read, but I can’t actually find a Microsoft link), it is no longer recommended that program settings be stored in the registry. For the second issue, it seems that with the CPU and memory of a modern PC, dynamically reading and applying such settings would be a much more ideal solution. This can be done by specifying a convention for the settings file (it can be XML or whatever), then dynamically scanning each folder in the \Program Files directory for these files and applying the settings specified.

There are, of course, technical benefits (application not messing around in the registry) and tradeoffs (performance cost of scanning program directories) to doing this, but from the end-user’s perspective the ultimate benefit comes from the tighter coupling of a program’s files (program settings that effect the OS are no longer part of the registry file, they now reside in their own file, which is tightly coupled together with other program files in the same directory).

Part 3: Documents and Settings
Tackling the registry is somewhat easy as you don’t have to look far to see the flaws of the registry. The Documents and Settings folder seems a bit trickier, but it’s not. The Documents and Settings folder is a manifestation of the needs of a multiuser operating system. Fundamentally, it stores user-specific settings and program-specific setting for a specific user or all users (the other stuff like My Documents, or the desktop, can be moved; well, to a certain extent, some programs still seem to use an absolute path to C:\Documents and Settings\<user>\My Documents instead of querying the OS for the path). User-specific settings are the domain of the operating system so it can whatever it will with these files. Program settings are different, they’re the domain of the program which owns them (that’s a contract between the user and the program, not the user and the operating system). The policy of having the OS handle delineation and storage of per-user program settings seems to be just that, a policy. There’s no reason applications can’t do it themselves. There are 2 possible solutions I see here:

  • Solution A: The program can be written from a multiuser perspective. Querying all users, creating a directory for every user (within the program’s main directory), setting appropriate permissions for the directories created, and storing user-specific data in these directories.
  • Solution B: Create one \Program Files directorie s for every user. In effect, every user can have a different set of programs installed and/or copies of the same programs. Programs store whatever user-specific settings they want (which will be for the currently logged in user) in their main directory.
Solution A is a pain in the ass for developers. No developer is going to want to have the additional burden on managing data for multiple users when it can be done transparently by the OS. Solution A is also not ideal in how it addresses the overall problem, as to move or copy programs users have to either log in as an admin and copy over all the user data folders or figure out their specific user data folder and only copy over that one.

Solution B is ideal in my opinion, even though it wastes hard drive space, but space is cheap and aside from games most programs don’t use a whole lot. With at one \Program Files directory for every user, applications will still maintain transparency in how they manage user data for multiple users and user data can be stored in the application’s main directory. This solution also provides for greater security and stability as users’ program files are independent and they don’t have to risk running something modified by another user. (i.e. every user is in their own sandbox both for programs as well as documents).

The ultimate benefit here is that copying a program becomes just a matter of copying the program’s main directory.

(For sensitive information, the program is then responsible for determining what user information to keep and what to erase after a copy, but that’s as it should be, that information is a contract between the user and the program, not the user and the operating system).

Part 4: Wishful Thinking
I wrote specifically about Windows, but the central idea here is coupling of data, which can be applied across operating systems. The tighter the coupling, the easier it is for the user to manipulate their data as a whole. There’s no reason the same agility afforded to a user’s documents can’t be given to their programs as well.

Also, although I mentioned one directory for all programs, I see no reason why the system I described couldn’t scale to multiple program files directories (for multiple drives or whatever else).

There is, of course, one issue I didn’t tackle, which is DRM. I spoke about copying and moving without mentioning licenses or copy protection, techniques which greatly benefit from the way things are. However, I think that’s a separate issue, and, simply put, I see something terribly wrong with licensing software to a CPU instead of a user.

Anyways, it’s just an idea. In the end, all of this is wishful thinking, and there’s so much inertia and missteps from the operating system vendors that I’m not holding my breath for any fundamental changes. However, there’s something really sad about the fact that it’s easier to install an application on Facebook than it is to install an application on my desktop.


The commercial shortcomings of Beyond Good and Evil

From NextGen,

Ubisoft plans to make the sequel to Beyond Good & Evil more “accessible” than its predecessor, in order to avoid the commercial shortcomings endured by the original.

Apparently, Ubisoft evaluated the original and somehow came to the conclusion that difficulty was the reason the title flopped at retail. Maybe, but from the comments garnered by the article this doesn’t seem to be the case. Also, I dug up the old gamespy review and “low difficulty level” is actually listed as one of the cons.

Well, here’s another explanation, the reason I didn’t buy the game was that I played the demo: great characters, interesting environments, etc., but I had the game crash or freeze on me multiple times to the point where I just gave up and didn’t bother even finishing the demo. Now, this may have just been an issue with the demo, or maybe the PC version, or a graphics driver issue but, simply put, the demo left me with a very negative impression of the game’s technical quality and even now, when I pick it up for far less than the initial $45+, I’m apprehensive to do so. Maybe this was just my experience, but it certainly seems to be a more plausible factor (among many others) than difficulty.


Images from the Pheonix Mars Mission

As many already know, the Pheonix lander touched down on Mars a few days ago. It’s a great feat of engineering and it’ll be exciting if we find life under the permafrost. However, aside from whatever scientific value they may hold, I’m not really fond of the pictures from the lander or the rovers. While there is something eerily cool about seeing the surface of another planet, Mars is (1) not a very pretty planet and (2) the cameras can only give a very close-to-the-ground shot of the landscape (the flat, rock-covered, brownish-red landscape).

pheonix lander mars surface

That being said, one of the coolest images I’ve ever come across is below; it’s an artificial cloud formed from the gas of the rocket used to launch the pheonix lander.

pheonix rocket clouds

I also love the colors and how they blend together, as well as the “texture” of the clouds. I’m thinking this might be a great texture and color scheme for the design of a web site or GUI widgets or something… I don’t know, it just looks damn cool.

Full resolution images available at the Pheonix Mars Mission site.


Automatic mipmap generation on Radeon 9500

I stumbled upon an annoying little graphics bug recently where I was getting corrupted textures on a Radeon 9500 graphics card. I eventually came across this thread which hinted at the problem. Apparently, automatic mipmap generation is messed up on the Radeon 9500 and screws up your textures (I got rainbow colors, weird blocks, etc.). I’m pretty sure the hardware supports it, so perhaps it’s a driver issue, but in any case it didn’t work.

What’s even more annoying about this is that everything worked perfectly on a much older Radeon 7500 card.


Altering the file size limit for PHP uploads

Well, of course, you can edit php.ini to change the file size limit, but for cheap (typically, shared) hosting solutions the issue that pops us is that you don’t have access to it.

I was researching how I could do this w/o modifying php.ini and discovered a forum post that explain a few methods of how it could be done.

Method A (the one that worked for me):
Edit your .htaccess file (if you don’t have one in your web site’s public root directory, you should be able to just create one) and add the following:
php_value post_max_size 8M
php_value upload_max_filesize 8M
(of course, replace 8M with however many megabytes you wish to limit the file sizes of uploads by)

Method B (the one that didn’t work for me):
Use the ini_set function,
ini_set('post_max_size', '8M');
ini_set('upload_max_filesize', '8M');

Method C (the one I didn’t try):
Use a custom php.ini. Not sure exactly what would be involved here, but you’d likely have to programmatically make a copy of the existing php.ini file, modify the copy, and then place the copy in the directory of the script that needs it or in your web site’s public root directory.


Compiling Webkit on Win32

Compiling WebKit on Windows is far from trivial. In the process of getting it compiled and linked successfully, I took some notes which may help others struggling to getting it done.

First, a few precautions, don’t try to be smart. Follow the instructions on the site closely, this means:
  • Don’t try to compile w/ Visual C++ 2008, it won’t work. Use VC++ 2005.
  • For VC++ 2005 Express Ed., make sure you have SP1, compilation will fail w/o it.
  • For Vista, make sure you have the additional SP update.
  • Don’t try to compile outside of cygwin directory structure.
Next, you need to get the webkit source.
  • Get the source from a nightly build (make sure to download the source and not one of the platform specific builds). You can also get the files from the subversion repository, but I had issues with this and discovered missing files. It may have been fixed, but in general, I think just getting the nightly build is simpler.
  • The source is in a .bz2 file. So you’ll need a bzip2 decompressor.
  • The bz2 file decompresses to a .tar file (wtf?!), so you’ll also need a tar decompressor.
  • Next, download the WebKit Support Libraries.
  • Put the source under your cygwin/home/<username> directory (e.g. \cygwin\home\<username>\WebKit)
  • Finally, update, by running the update-webkit script.
Preparing for compilation.

Note: I tried to build from the cygwin shell, as demonstrated on webkit.org, but it failed. Failing in this way and then having to dig thru build logs is insane, so I diverted to building from within VC++ so I could easily spot and fix errors as they occurred.

Note: I failed to realize that I didn’t have SP1 for VC++ 2005 Express when I started this whole process and didn’t figure it out until I hit a few perplexing errors related to the linker failing because it detected different versions of the compiler were used for the 2 parts of compilation on a few object files (yea, it’s weird, I have no clue what was going on internally here). I found a few quick and dirty solutions to this problem by playing around with optimization settings, but eventually hit a brick wall, where no amount of fidgeting with optimization parameters resulted in compilation/linking going forward. Installing SP1 solved the issue and may have solved the earlier issues as well without me having to play with optimization settings.

So, onwards we go,
  • I found that after opening the WebKit solution, none of the projects were loaded. This is because the project files are looking for *.vsprops files in WebKit\WebKitLibraries\tools\vsprops, but the vsprops files are actually in WebKit\WebKitLibraries\win\tools\vsprops. The simplest solution is just copy over what’s in the /win directory into the parent directory (WebKit\WebKitLibraries). Looking at WebKit\WebKitLibraries now, I copied over the win/tools folder and the files in /win. Alternatively, you can edit the project files (they’re XML files, you can open them up in a text editor).
  • Set the 2 environment variables necessary for compiling within VC++,
    • WEBKITLIBRARIESDIR = cygwin\home\<user>\WebKit\WebKitLibraries
    • WEBKITOUTPUTDIR = cygwin\home\<user>\WebKit\WebKitBuild
  • Get the Platform SDK, specifically the Windows Server 2003 Ed. of the Platform SDK. I did not have luck getting it to work with an older or newer version of the SDK. I didn’t install the R2 update; I’m not sure what effect it would have.
  • Update VC++ directories:
    • Executables >> add cygwin/bin, windows/system32, Platform SDK/bin
    • Includes >> Platform SDK/include
    • Library Files >> Platform SDK/lib
  • Update VC++ directories for the WebKit Support Library:
    • Includes >> WebKit\WebKitSupportLibrary\WebKitSupportLibrary\win\include
    • Library Files >> WebKit\WebKitSupportLibrary\WebKitSupportLibrary\win\lib
  • Update VC++ directories for JavaScriptCore/icu:
    • Includes >> WebKit\JavaScriptCore\icu
  • Update VC++ directories for WebCoreSQLite3:
    • Includes >> WebKit\WebKitLibraries\WebCoreSQLite3
  • Update VC++ directories for JavaScriptCore:
    • Includes >> WebKit\JavaScriptCore
  • I had issues with the ARRAYSIZE macro not being defined, so in WebCore/config.h, add the following:

    #ifndef ARRAYSIZE
    #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
    #endif

    right before the line,

    #endif /* PLATFORM(WIN_OS) */

  • Get rid of cygwin’s link.exe in cygwin/bin (rename it or delete it). This causes a conflict with the real linker (VC++’s link.exe). It was likely caused by the order in which VC++ executable directories were set, so if you need it, you might be able to keep it.
  • For the QtMovieWin project, edit all source files (there’s only 2) so that windows.h is included first (this is due to macro above, which will now cause a macro redefinition by the preprocessor).
  • For QtMovieWin, also rearrange the order of include, so that #include <wtf/Vector.h> is included before config.h and windows.h to prevent some min/max macro nonsense.
  • For QtMovieWin, take off prompt error reporting for linking (ERRORREPORT:PROMPT) project (see Linker >> Advanced page in project setting).
  • Make a new config file by copying WebCore/config.h and making WebCore/config_qt.h. Remove the ARRAYSIZE macro defintions from config_qt.h. Update all files in QtMovieWin project so that config_qt.h is included instead of config.h.
  • Install the QuickTime SDK.
  • Update VC++ directories:
    • Includes >> QuickTime 7.3 SDK\CIncludes
    • Library Files >> QuickTime 7.3 SDK\Libraries
  • For QtMovieWin, make sure you linker inputs are set correctly for QuickTime libraries and VC++ can find them.
  • For QtMovieWin, add “CoreFoundation.lib” to linker inputs.
  • (This may have been an issue caused by not having SP1, you might not have to do this, try compiling first) Turn off whole program optimization for all projects.
  • (This may have been an issue caused by not having SP1, you might not have to do this, try compiling first) Turn off treat warnings as errors for JavaScriptCore, WebKit, WebKitGUID, WebCore, and WTF projects.
That should do it.

Some general advice, work from within VC++ and compile as you make changes; make it a touch-and-go operation. In this way you see errors as they occur and can more easily spot and fix issues. Don’t simply follow what I’ve written above as tutorial thinking it’s a sure-fire solution for compilation, things may very likely change with different iterations of the code.