Hey, Scripting Guy! How Can I Randomly Assign a Font to Characters in a Word Document?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I’ve come up with a way to imitate handwriting in a document, but I need some help. Because real handwriting is characterized by variability, I had the idea of using four slightly-different fonts, taken from my actual handwriting, and then randomly assigning a font to each letter. I think that would imitate handwriting a little better, but I’m not sure how to go about doing that.
— CW

SpacerHey, Scripting Guy! AnswerScript Center

Hey, CW. We have to admit that we’re intrigued by your theory of using random font assignment to introduce variability, and thus more-realistically imitate actual handwriting. The Scripting Guys actually debated this issue a couple weeks ago, when we were faced with the daunting task of signing hundreds and hundreds (and hundreds!) of Certificates of Excellence for the 2008 Winter Scripting Games. For a little while we toyed with the notion of having their signatures printed onto the certificates, but we had the same concern you do: that these printed signatures (using some font designed to look like handwriting) would still look phony.

Note. Were we also concerned about the ethics involved in promising everyone a certificate signed by the Scripting Guys, and then not actually signing those certificates? Um, sure, sure we were ….

In the end, we went ahead and signed all the certificates by hand, a process that required several hours to finish. (Admittedly, this might have gone a little faster, but at one point the Scripting Guy who writes this column literally could not remember how to write his name. That’s what signing your name several hundred times in succession will do to you.) On top of that, this was also a process that really deteriorated towards the end: if you have a last name beginning with the letter S, for example, then no doubt the “signatures” you got on your certificate were unreadable smudges that looked as though they were signed by a monkey.

Of course, as it turns out, it would be much better for you if your certificate had been signed by a monkey. After all, in June, 2005 three tempera paintings created by Congo the chimpanzee sold at auction for $26,352. That’s approximately $26,352 than you can expect to get at auction for anything created by the Scripting Guys.

Note. Not to take anything away from Congo, mind you, but creating a series of abstract paintings doesn’t seem anywhere near as impressive as the exploits of Bobo, the Detective Chimp. Incidentally, that has nothing to do with today’s column; we just wanted to pay homage to Bobo, and to the immortal Lancelot Link, Secret Chimp.

As it turns out, Congo the chimpanzee (who died many years ago) only painted for three years, at which time he became bored with art and no longer felt the need to put his feelings down on canvas. Fortunately for us, however, Congo next turned his attention to system administration scripting; in fact, one of the last scripts Congo ever wrote was a script that can randomly select a font for the individual characters in a Microsoft Word document. You know, a script just like this one:

Set objWord = CreateObject(“Word.Application”)
objWord.Visible = True

Set objDoc = objWord.Documents.Open(“C:\Scripts\Test.doc”)

Set objRandom = CreateObject(“System.Random”)

intLow = 1 intHigh = 5

Set objRange = objDoc.Range() Set colCharacters = objRange.Characters

For Each strCharacter in colCharacters intRandom = objRandom.Next_2(intLow,intHigh)

Select Case intRandom Case 1 strCharacter.Font.Name = “Arial” Case 2 strCharacter.Font.Name = “Times New Roman” Case 3 strCharacter.Font.Name = “Courier New” Case 4 strCharacter.Font.Name = “Forte” End Select Next

We should note that one of the drawbacks to reprinting scripts created by chimpanzees is that chimps typically don’t bother to explain how their scripts work. (Which should finally put to rest the rumor that this column is written by a monkey. This column is not written by a monkey; it only sounds like it was written by a monkey.) At any rate, we’ll see what we can do to explain how this script does its thing. However, if that explanation turns out to be unclear or misleading, well, don’t blame us; blame Congo the chimp.

That’s what we always do, especially now that Scripting Guy Peter Costantini is no longer on the team.

As you can see, Congo starts his script off by creating an instance of the Word.Application object, then sets the Visible property to True; that gives him – and us – a running instance of Microsoft Word that we can see on screen. Once we have that instance we can then use the Open method to open the document C:\Scripts\Test.doc:

Set objDoc = objWord.Documents.Open(“C:\Scripts\Test.doc”)

That’s a document that looks something like this:

Microsoft Word

Because we’re going to randomly assign fonts to each character we need two things: we need a method for generating random numbers, and we need a way to access each of the characters in the document. We can generate random numbers between 1 and 4, inclusive, by using the .NET Framework class System.Random, and by assigning our low number (1) to a variable named intLow, and our high number, plus 1, to a variable named intHigh. That’s what we do in this block of code:

Set objRandom = CreateObject(“System.Random”)

intLow = 1 intHigh = 5

As for accessing each and every character in the document, well, these two lines of code give us the ability to do that:

Set objRange = objDoc.Range()
Set colCharacters = objRange.Characters

In line 1 we’re creating an instance of Word’s Range object, an object that – in lieu of any other instructions – encompasses the entire document. In line 2, we’re creating an object reference to the range object’s Characters property; as the name implies, the Characters property contains a collection of all the characters found in the range.

So what comes next? Well, after a quick break to eat a banana or two, we proceed to set up a For Each loop to walk us through each character in the collection colCharacters:

For Each strCharacter in colCharacters

Inside that loop, the first thing we do is use the Next_2 method to generate a random number between 1 and 4, inclusive:

intRandom = objRandom.Next_2(intLow,intHigh)

Note. Did Congo come up with the name Next_2 for this method? Hey, come on: that’s an insult to chimpanzees everywhere!

As soon as we have a number between 1 and 4 we can then use the following Select Case statement to change the font for that particular character:

Select Case intRandom
    Case 1 strCharacter.Font.Name = “Arial”
    Case 2 strCharacter.Font.Name = “Times New Roman”
    Case 3 strCharacter.Font.Name = “Courier New”
    Case 4 strCharacter.Font.Name = “Forte”
End Select

And then from there we then go back to the top of the loop, where we generate another random number and change the font for the next character in the collection. When all is said and done we’ll end up with a document that looks something like this:

Microsoft Word

Granted, this particular example, using these fonts, might not look much like handwriting. But you get the idea.

Considering the fact that he created over 300 paintings in his brief, three-year career, it probably comes as no surprise that the prolific Congo also created a second script that can change the font of various letters throughout a Word document. Congo’s second script takes a different approach from his first: this script takes a set of letters (in this case, a, d, l, and s), methodically searches the document for each of those characters, and then changes the font of each a, d, l, or s it encounters. We’re not sure if that does you any good, but we have no doubt that Congo would have wanted us to give you the option of using this alternate approach instead. Here’s the code for Congo’s second script:

Const wdReplaceAll = 2

Set objWord = CreateObject(“Word.Application”) objWord.Visible = True

Set objDoc = objWord.Documents.Open(“C:\Scripts\Test.doc”) Set objSelection = objWord.Selection

arrLetters = Array(“a”, “d”, “l”, “s”)

For Each strLetter in arrLetters objSelection.Find.Text = strLetter objSelection.Find.Forward = TRUE objSelection.Find.MatchWholeWord = False

objSelection.Find.Replacement.Text = strLetter objSelection.Find.Replacement.Font.Name = “Forte”

objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll Next

That’s all we have time for today, CW; as it its, it’s almost time for the cleaning crew to come clean out our cages. In the meantime, some of you might be concerned about whether your Certificate of Excellence was really signed by the Scripting Guys. If you’re worried about that, take a careful look at the signatures on your certificate. Scripting Guy Greg Stemp’s largely-illegible signature should look similar to this:

Microsoft Word

Meanwhile, Scripting Guy Jean Ross’ signature should look like this:

Microsoft Word

And yes, we noticed that, too. But her handwriting was so nice we hated to say anything about her spelling. Maybe next year.