Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
BinaryReplace and BinaryTags: Processing Templates Files
Contents
- Introduction - Processing Template Files in WinBatch
- BinaryReplace
- BinaryTag's
- Example 1 - Make a HTML filename/title database
- Example 2 - UPPERCASE HTML title tags
- Example 3 - Strip HTML tags from HTML files
- Example 4 - The Full Deal
- Conclusion
Processing Template Files in WinBatch
Introduction
One powerful trick in computing is the use of template files. Template files can be used when you need to produce a large number of files which are very similar but have different content.A template file is a file what is similar to the desired output file, except that certain placeholders are put into the file instead of the parts of the file that change. The files produced can be nearly any sort of text file. For example, this site World Wide School Library, with maybe 40,000 web pages, is all produced from a small number of different template files.
For a example we can refer to, here is a small template file that we can work with.
Hello {{name}} The weekly diskscan has examined your used diskspace and your {{diskspace}}MB is {{overunder}} quota.This may be, for example, a small report that is sent out to all network users of some department having disk space problems. Of course it could be a lot fancier, or maybe even a HTML page for HTML email.
In any case you can note that there are three {{placeholders}} in the file. The theory is that instead of placing the entire message in a program, a template file can be produced, and a program written to use the template file to produce a new file with the desired contents.
WinBatch can easily process template files. There are a large number of different ways to do it. Two of the better ones are known as the "BinaryReplace" method and the "BinaryTag" method.
BinaryReplace
The BinaryReplace method is quick and easy, and works in perhaps most of the cases you may come across. The BinaryTag method is just a bit more complicated, but is also much more powerful. BinaryTag will be discussed in the next section.
BinaryReplace Simple Sample
The BinaryReplace method is based on the WinBatch BinaryReplace function.
Mass file generationThe BinaryReplace function can almost instantly change all the occurrences of a string in a binary buffer to a different string. So it is used to convert the desired {{placeholders}} to the desired values.
To make this work in an example, we will use three files, Template.txt, InputData.txt, and a WBT file that we'll call BinaryReplace.wbt
If you copy and paste this example and run it, it will produce four files, Msg00001.txt, MSg00002.txt, Msg00003.txt, and Msg00004.txt. If you examine the contents of a file, it will look like....
- First the template file again
Hello {{name}} The weekly diskscan has examined your used diskspace and your {{diskspace}}MB is {{overunder}} quota.
- Secondly, the input data file
John Doe~1234 Suzy Simpson~873 Peter Paulson~762 Harvey Wallbanger~875
- And finally the script
; This program will create a number of files based on the lines ; in the "inputdata.txt" file. The output files will be ; named Msg0001.txt Msg0002.txt and so on. ; Define template file name to use template="template.txt" ; Define input file infile="inputdata.txt" ; The first trick. We allocate a BinaryBuffer to use. ; The BinaryBuffer must be LARGER than the maximum possible ; output file. In this case we start with the template ; file size and add 10000, which should cover most cases. bbsize=FileSize(template)+10000 ; Then the Binary Buffer is allocated bb=BinaryAlloc(bbsize) ; And a counter is initialized to zero for our output file names count=0 ; A standard FileOpen to read in the input file, line by line handle=FileOpen(infile,"READ") ; We process each line of the input file in this while loop While 1 ; Standard file read code, checking for the EOF condition. line=FileRead(handle) If line=="*EOF*" Then Break ; Now we break the data out of a line of the input file Name=ItemExtract(1,line,"~") DiskSpace=ItemExtract(2,line,"~") ; And clean the data up in case there are extra spaces around it Name=StrTrim(Name) DiskSpace=StrTrim(DiskSpace) ; We'll assume everybody's quota is 1000MB If DiskSpace > 1000 overunder="over" Else overunder="under" EndIf ; Increment output file name count ; and build an output file name count=count+1 outfilename=StrCat("Msg",StrFixLeft(count,0,5),".txt") ; Now the magic starts. ; First we read the template file into our Binary Buffer BinaryRead(bb,template) ; And the BinaryReplace's to edit the file BinaryReplace(bb,"{{name}}",name,@FALSE) BinaryReplace(bb,"{{diskspace}}",diskspace,@FALSE) BinaryReplace(bb,"{{overunder}}",overunder,@FALSE) ; And the file is written out to the desired filename BinaryWrite(bb,outfilename) ; Another important trick. Clear Binary Buffer for next pass BinaryEodSet(bb,0) EndWhile ; Repeat for each line of the file ; Close file FileClose(handle) ; Free Binary Buffer BinaryFree(bb) ; All Done Message("Job","Complete")
...and you can see the various {{placeholders}} now contain data from the input file.Hello John Doe The weekly diskscan has examined your used diskspace and your 1234MB is over quota.
BinaryReplace
Useful Example
In this example a HTML slide show is created out of a directory containing a number of JPG files. We will take a simple HTML template file and use it to create a slideshow containing all the JPG's in some indicated directory.
HTML Slideshow for JPG filesFirst of all, here is a template file. If you wish you can make it more elaborate later.
<html> <head> <title> {{IMAGETITLE}} </title> </head> <body bgcolor="#000000" text="#FFFFFF" LINK="#FFFF00" VLINK="#FFFF00" ALINK="#00FFFF"> <pre> </pre> <center> <a href="{{PREVLINK}}">Previous</a> <a href="{{NEXTLINK}}">Next</a> <p> <img src="{{IMAGE}}"> <!-- Or perhaps to force image sizing use the line below instead of the line above. <img src="{{IMAGE}}" width="400" height="300"> --> <p> <font color="#00FFFF">{{IMAGETITLE}}</font> <p> </center> </body> </html>In this simple HTML template file there are just four different types of placeholders. They are:Now to build the slide show, this code can be used. Be sure to fix the pointer to the JPG directory, or perhaps insert an AskDirectory function instead.
- {{IMAGETITLE}}
- Used for both the HTML page title, and the title on the image on the page. It is simply the "root" part of the image filename, the part without the path information and without the .jpg extension.
- {{IMAGE}}
- This is the full filename to the file. If you plan to place these pages on a real website, you would modify this to be the URL to the image file.
- {{PREVLINK}}
- The name of the previous page to link to.
- {{NEXTLINK}}
- The name of the next page to link to.
;THIS LINE will REQUIRE fixing for your system JPGDir="C:\JPGS\" ;Directory of a bunch of JPG files. Put \ on end ;This line will probably work as-is. HTMLDir="Pages\" ;Directory to place new HMTL files. Put \ on end ;If destination directory does not exist, make it If DirExist(HTMLDIR)==@FALSE Then DirMake(HTMLDir) ;Define the template file filename templatefile="template.html" ;And allocate a (greatly) oversized Binary Buffer bb=BinaryAlloc(FileSize(templatefile)+10000) ;Now we collect a list of all the JPG files in the JPGDir directory JPGList=FileItemPath(StrCat(JPGDir,"*.jpg")) ;And count how many there are JPGCount=ItemCount(JPGList,@TAB) ;Now we build one HTML page per JPG file for the slide show. For xx= 1 To JPGCount ;Extract a JPG filename from the list thisjpg=ItemExtract(xx,JPGList,@TAB) ;Using just the root part of the file name for the title. ;If the JPG's are named something reasonable, this should work. DaTitle=FileRoot(thisjpg) ;Now, based on the title, make a HTML file name HTMLFilename=StrCat(DaTitle,".html") ;And expand the HTML file name to a fully pathed file name ;to the desired html file FullHMTLFilename=StrCat(HTMLDir,HTMLFilename) ;Now we want to work out what html files the PREVIOUS and NEXT ;links should point to. First we do the obvious ones PrevNum = xx - 1 NextNum = xx + 1 ;Then we fix the numbers for the first and last images If xx==1 Then PrevNum=JPGCount If xx==JPGCount Then Nextnum=1 ;And we then build the HTML filenames for the previous and next ;links, based on the numbers set just above. PrevHTML=StrCat(FileRoot(ItemExtract(PrevNum,JPGList,@TAB)),".html") NextHTML=StrCat(FileRoot(ItemExtract(NextNum,JPGList,@TAB)),".html") ;And now the BinaryReplace Magic occurs ;First we read the template file into a BinaryBuffer BinaryRead(bb,templatefile) ;Then do our BinaryReplace's to edit the BinaryBuffer BinaryReplace(bb,"{{IMAGETITLE}}",DaTitle,@FALSE) BinaryReplace(bb,"{{IMAGE}}",thisjpg,@FALSE) BinaryReplace(bb,"{{PREVLINK}}",PrevHtml,@FALSE) BinaryReplace(bb,"{{NEXTLINK}}",NextHtml,@FALSE) ;And we write the edited buffer out BinaryWrite(bb,FullHMTLFilename) ;Then reset the BinaryBuffer EOD pointer for the next pass BinaryEodSet(bb,0) Next ;When done, we free the BinaryBuffer BinaryFree(bb) ;And use ShellExecute to display the first HTML file in the user's ;default browser ShellExecute(StrCat(HTMLDir,NextHtml),"","",@ZOOMED,"") ;And we are all done. ExitIf you try this, you can see that you can create many HTML pages practically instantly. And it makes a nice little slide show.
The BinaryReplace function may be able to do all the template file processing you will ever need. However... You may have more demanding requirements. Thus the BinaryTag method.
BinaryTag's
Whileas the BinaryReplace functions discussed previously changes every occurence of a {{placeholder}} in a template file to the same replacement string, there are cases where more intelligence might be desired. These "more intelligent" placeholders are called "tags", the idea being that it tags a spot where special processing should occur. Thus the family of functions are called the BinaryTag functions. For example, if you were writing a book, you could place a {{CHAPTER}} tag at the beginning of each chapter. The idea being that the first {{CHAPTER}} tag would be replaced by "Chapter I", the next one by "Chapter II", "Chapter III", "Chapter IV", and so on, a different, intelligent replacement string each time.Of course a given template file may have all sorts of different tags in it.
There is no particular "magic" about rooting through a file, looking for various {{tags}} and processing them accordingly. However, the BinaryTag functions allow you to do this in a fast, efficient, clean manner, with a minimum of code.
It turns out that, these days, the production of HTML files is the most common use of the BinaryTag functions, however these concepts can be used for any kind of template file processing. In deference to the wide usage of HTML template files, we will use HTML based examples to help explain how to use it.
First of all, there are four primary BinaryTag functions. These are:
The basic sequence of operations goes like this:
- BinaryTagInit
- Sets up a program to perform a series of BinaryTag operations on a template file that has been read into a Binary Buffer.
- BinaryTagFind
- Locates the next tag in the file.
- BinaryTagExtr
- Grabs the contents of a tag so it can be examined and processed
- BinaryTagRepl
- Replaces a previously found tag with the desired placement information.
Next, we will cover three simple examples to get the basic comprehension of the BinaryTag functions straight, and then a real one where the power of the BinaryTag functions is more fully exposed.
- Load a template file into an oversized BinaryBuffer.
- Perform a BinaryTagInit to set up for rummaging through the buffer.
- Then the following is repeated until no more tags are found.
- Do a BinaryTagFind to find the next tag.
- BinaryTagExtr to retrieve the contents of the tag.
- Tag is examined by the program.
- Optionally, replacement text is built and a BinaryTagRepl replaces the tag with desired replacement text.
- When complete, the modified buffer may be written to a file.
- The process may be repeated to generate a different file.
BinaryTag Example 1
In this first example, the idea is that we will point the script to a directory full of HTML files, and the script will root through all the HTML files in the directory and extract the title field from the HTML and build a tab delimited text file that relates the HTML file names to the HTML title fields. Thus...
Make a HTML filename/title database;This script builds a tab delimited text file containing ;HTML file names and the title fields from the HTML documents ;Point this variable to a directory full of HTML files htmldir="C:\MyHtmlDocs\" ;remember \ on end ;Define output file name for the text file dbfile="HTMLTitles.txt" ;This gets a tab delimited list of all the HTML file names HtmlFiles=FileItemPath(StrCat(htmldir,"*.htm*")) ;This counts them to see how many we have HtmlCount=ItemCount(HtmlFiles,@TAB) ;Opens the output file to receive the information we ;are going to write to it handle=FileOpen(dbfile,"WRITE") ;Allocate a BinaryBuffer BIGGER than any HTML file. Guess. bbsize=100000 ; must be bigger than any html file bb=BinaryAlloc(bbsize) ;For each HTML file in our list For xx=1 To HtmlCount ;Get next file to work with from list. It will be a ;fully qualified filename with path and everything thisfile=ItemExtract(xx,HtmlFiles,@TAB) ;Work out just the plain filename without the path info plainfilename=StrCat(FileRoot(thisfile),".",FileExtension(thisfile)) ;Read the file into our Binary Buffer BinaryRead(bb,thisfile) ;Initialize the BinaryTag operations. We will use ;<title> for the beginning tag and </title> for the ;ending tag. structure=BinaryTagInit(bb,"<title>","</title>") ;We do not expect to find more than one tag, so there ;is no loop set up to rummage thru the whole file ;Find the tag structure=BinaryTagFind(structure) ;If no tag found, then document does not have a title If structure=="" Then title="***No Title Found***" ;else extract contents of tag Else title=BinaryTagExtr(structure,1) ;Write filename and extracted title to our file FileWrite(handle,StrCat(plainfilename,@TAB,title)) ;Clear out BinaryBuffer for reuse BinaryEodSet(bb,0) ;Then do it again for the next file Next ;Free the BinaryBuffer BinaryFree(bb) ;Close the file FileClose(handle) ;Display the file Run("browser.exe",dbfile) ;All done
BinaryTag Example 2
This example is similar to the previous one, except that the BinaryTagRepl function is now brought into play, and edited copies of the source files are actually created. Try it with a large directory of HTML files. You will see that it is incredibly fast.
UPPERCASE HTML title tags;This script will edit HTML files to make the title ;of the HTML document all UPPERCASE. ;Point this variable to a directory full of HTML files htmldir="C:\MyHtmlDocs\" ;remember \ on end ;This will make a folder to place the edited HTML files outputHTMLDir="FixedHTML\" If DirExist(outputHTMLDir)==@FALSE Then DirMake(outputHTMLDir) ;Make a "mask" for the FileMapName function to transmorgify ;the input filename to an output file name. OutputMask=StrCat(outputHTMLDir,"*.*") ;Get the list of HTML files HtmlFiles=FileItemPath(StrCat(htmldir,"*.htm*")) ;Count them HtmlCount=ItemCount(HtmlFiles,@TAB) ;Allocate a BinaryBuffer to work with bbsize=100000 ; must be bigger than any html file bb=BinaryAlloc(bbsize) ;For each file in the list For xx=1 To HtmlCount ;Get the next HTML file name thisfile=ItemExtract(xx,HtmlFiles,@TAB) ;Create the output file name for later outfile=FileMapName(thisfile,OutputMask) ;Read the HTML file into the buffer BinaryRead(bb,thisfile) ;Initialize the BinaryTag logic structure=BinaryTagInit(bb,"<title>","</title>") ;Again, there is no loop here as we only expect ;the <title> tag to appear once ;Find the <title>xxx</title> tags. structure=BinaryTagFind(structure) ;Assuming we found a set of title tags... If structure != "" ;Extract text between the tags title=BinaryTagExtr(structure,1) ;UPPERCASE the title tag UPPERtitle=StrUpper(title) ;Now we want the <title> </title> around it. So ;we have to add them back in to the replacement string UPPERtitle=StrCat("<title>",UPPERtitle,"</title>") ;Update the BinaryBuffer with the new data structure=BinaryTagRepl(structure,UPPERtitle) EndIf ;Write the edited file out BinaryWrite(bb,outfile) ;Clear out the BinaryBuffer for next time BinaryEodSet(bb,0) Next ;Free the buffer BinaryFree(bb) Message("All Done","Examine files in the output directory")
BinaryTag Example 3
In this example we actually work thru the entire contents of an HTML file, several times actually, to strip the HTML from the file and to leave a plain text document. Depending on your HTML files, your luck with this code may vary.
Strip HTML tags from HTML files; In this example the BinaryTag functions are used to locate and ; strip HTML tags from a html file, and to produce a text only ; file. ;In this example, set the htmlfile variable to any handy HTML file htmlfile="winbatch.html" ;And set the textfile variable to a suitable output filename textfile="winbatch.txt" ;Per usual, allocate an oversize BinaryBuffer. Not strictly ;necessary in this case as we will be reducing filesize ;rather than enlarging it. bbsize=FileSize(htmlfile)+10000 bb=BinaryAlloc(bbsize) ;Read the HTML file into the BinaryBuffer BinaryRead(bb,htmlfile) ;Pass 1. Strip HTML comments ;In this first pass thru the file, we remove the HTML comments ;as the HTML comments may contain items that may confuse ;the BinaryTag functions. Mostly items that look like end tags ;that we will use later. ;Initialize BinaryTag operations structure=BinaryTagInit(bb,"<!","-->") ;Now we have a simple while loop, working thru the entire ;HTML file While 1 ;Find next HTML comment structure=BinaryTagFind(structure) ;If not found, exit loop If structure=="" Then Break ;If found, replace comment with an empty string structure=BinaryTagRepl(structure,"") EndWhile ;Pass 2. Strip remaining HTML ;Now that the confusing HTML comments are removed, now we ;go after the normal HTML in the file ;Initialize the BinaryTag logic again, with the ;normal HTML < and > tags structure=BinaryTagInit(bb,"<",">") ;And another loop, similar to above to remove ;all the html from the file While 1 structure=BinaryTagFind(structure) If structure=="" Then Break structure=BinaryTagRepl(structure,"") EndWhile ;Now at this point the job is basically done. However ;the stripped file then usually contains a large ;number of blank lines where HTML used to be, and this ;makes the resulting file a tad messy. So now there ;is a little cleanup work. ;Convert line endings to @LF to make processing easier ;and also to handle UNIX-style HTML files properly BinaryReplace(bb,@CRLF,@LF,@TRUE) ;Pass 3. Remove spaces at ends of lines ;This replaces all occurrences of {SPACE}@LF with ;plain @LF, thus removing spaces at the ends of lines. ;The process is repeated until there are no remaining ;spaces at the end of the line While BinaryReplace(bb,StrCat(" ",@LF),@LF,@TRUE) !=0 EndWhile ;As above, except for tabs this time While BinaryReplace(bb,StrCat(@TAB,@LF),@LF,@TRUE) !=0 EndWhile ;Pass 4. Remove extra line endings ;In this pass we remove white space between lines, ;simply by replacing duplicate adjacent @LF's with ;a single one. Similar to the above While BinaryReplace(bb,StrCat(@LF,@LF),@LF,@TRUE) !=0 EndWhile ;Pass 5. Getting a normal file back ;Restore normal DOS @CRLF line endings BinaryReplace(bb,@LF,@CRLF,@TRUE) ;Pass 6 ;HTML has some special character string representations. ;The code below picks up a few of the more common ones, ;and changes them back into human readable text. ;Convert some typical HTML special character representations BinaryReplace(bb," "," ",@FALSE) BinaryReplace(bb,">",">",@FALSE) BinaryReplace(bb,"<","<",@FALSE) BinaryReplace(bb,"&","&",@FALSE) ; Write out results BinaryWrite(bb,textfile) ;Free the buffer BinaryFree(bb) ;Display converted file Run("browser.exe",textfile)
BinaryTag Example 4
In this example we expose some of the full power of the BinaryTag functions, wherein they allow the scripts to make decisions based on the contents of the tags. The important concept here is that some of the programming shifts from the WinBatch script itself, which can be relatively simple, to the file being worked on.
The Full DealFor this example we will use the following html file. Note that there are various {{ and }} tags contained within it that have all sorts of additional information embedded within the tags. Save this file as WhereAmI.html in any convenient spot.
<html> <head> <title> Quick Orientation </title> </head> <body bgcolor="{{randomcolor LIGHT}}"> <blockquote><blockquote> <a href="http://heasarc.gsfc.nasa.gov/docs/cosmic/milkyway.html"> {{PickImageSaveAltText <img align=right alt="Lost in space. Near outer event horizon." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/nicmos.jpg"> |<img align=right alt="South of the Great Wall. Somewhat north of the Persens-Pisces Chain." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/sheets_voids.jpg"> |<img align=right alt="In non-descript galactical star agglomeration approximately midway between the larger Coma and Persens Clusters." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/nearest_superclusters.jpg"> |<img align=right alt="Near a smaller group of stars in the general vicinity of the Virgo cluster." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/local_supercluster.jpg"> |<img align=right alt="Within a smaller spiral armed galaxy near the Magellanic Clouds." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/local_group_layers.jpg"> |<img align=right alt="Eastern arm, so-called 'Milky Way' galaxy." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/nearest_galaxy.jpg"> |<img align=right alt="Eastern arm of the so-called 'Milky Way' galaxy, on a small blue-green planet currently in orbit around a mid-life star locally known as 'The Sun'." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/milkyway.jpg"> |<img align=right alt="Near Alpha Centauri, on a small blue-green planet currently in orbit around a mid-life star locally known as 'The Sun'" src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/solar_neighborhood.jpg"> |<img align=right alt="Near Alpha and Proxima Centauri, on a small blue-green planet currently in orbit around a mid-life star locally known as 'The Sun'" src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/nearest_star.jpg"> |<img align=right alt="Third planet out. Note planet with concentric rings. Not that one." src="http://heasarc.gsfc.nasa.gov/docs/cosmic/gifs/solar_system.jpg"> |<img align=right alt="Someplace surface or in orbit around small planet. Local name is 'Earth'." src="gifs/earth.jpg"> }} <h1>Current Location</h1></a> {{SavedAltTextFromImage}} <h1>Local Time</h1></a> {{Date}} <br clear=all> <pre> </pre> <hr color="{{randomcolor DARK}}" size=4 width="50%"> <h2>Alerts</h2> Sensors detect <font size="+1"><b> {{PICKONE Mild|Urgent|Immediate|Emergency|Dire}} </b></font> need for caffeinated beverages. <p> <font size="+1"><b>Be Alert!</b></font> We need more lerts. <p> Your lucky color for today is <font size="+1"><b> {{PICKONE Chartuese|Magenta|Puce|Pumpkin|Cerise|Cerulean|Cyan|Aquamarine|Carmine|Fuchsia}} </b></font>. <p> Your lucky number for today is <font size="+1"><b> {{PICKONE 1|2|3|4|5|6|7|8|9|pi|e|The Golden Mean|c<superscript>2</superscript>|The Fine Constant}} </b></font>. <p> <pre> </pre> <hr color="{{randomcolor DARK}}" size=4 width="50%"> <h2>Sponsors</h2> This message has been brought to you by the letter <font size="+3"> {{PICKONE A|B|C|D|E|F|G|H|J|K|M|N|P|Q|R|S|T|U|V|W|X|Y|Z}} </blockquote></blockquote> </body> </html>If you study the above pseudo-html template file and locate the various {{tags}} you will find a small assortment. These are:
- {{Date}}
- Has no parameters. Used to place current date.
- {{RandomColor}}
- Takes one parameter, LIGHT or DARK. Chooses a random color, but biased either light or dark, as specified in the parameter.
- {{PickOne}}
- The PICKONE keyword is followed by a |-delimited list. One item of the list is chosen at random to replace the entire tag.
- {{PickImageSaveAltText}}
- This is similar to PickOne, except that it expects a number of HTML <img src=> tags with alt= text contained within the tag. An image is selected and used to replace the entire tag. The alt= text embedded within the image tag is saved for future use....
- {{SavedAltTextFromImage}}
- This tag is replaced by the alt= text saved by the PickImageSaveAltText tag processing.
So now we have a HTML template file with a few weird {{tags}} in it. The beauty of this is that this file can be processed almost instantly, and an unlimited number of similar files can be built using the same tags or others that you make up. Once you get your tag processing script going, you can make all the different template files you want and don't have to alter the main script unless you decide to define some new sort of tag.
In any event here is my overly commented version of the processing script...
;In this example the variable UseHtmlFile ;points to the template HTML file. UseHtmlFile="whereami.html" ;Tempfile points to a scratch file used ;later to save the modified data Tempfile="output.html" ;This example uses a number of #defined ;functions/subroutines. We define these ;at the end of the example. Most of these ;functions below define what processing is ;to get done for each keyword. In any event ;we gosub the subroutine to get all the ;#DefineFunctions and #DefineSubroutines ;defined now. GoSub DefineFunctions ;Now that all the helper functions are defined, ;we cover the main processing part of the script. ;BinaryAlloc is used to obtain a ;BinaryBuffer of a size greatly in ;excess of any reasonable HTML page. bb=BinaryAlloc(100000) ;BinaryRead is used to read the entire ;template file into the allocated ;BinaryBuffer. BinaryRead(bb,UseHtmlFile) ;It begins to get interesting here. ;BinaryTagInit is used to define the ;buffer in question, bb, and the start ;tag {{ as well as the end tag }}. ; ;BinaryTagInit returns a special value ;that we call a structure. WIL uses the ;structure to keep track of what is ;going on. Structure=BinaryTagInit(bb,"{{","}}") ;while @TRUE is simply a cute trick that ;means loop forever – at least until ;a break statement elsewhere causes the ;loop to exit While @TRUE ;The BinaryTagFind function locates ;the next tagged keyword. It knows ;where to start from the information ;passed to it in the "structure" variable, ;and it also saves updated information in ;the structure variable. structure=BinaryTagFind(structure) ;If the structure variable comes back ;from the BinaryTagFind as a null string, ;then no more tagged keywords were found ;and it is time to break out of the loop If structure=="" Then Break ;The BinaryTagExtr function extracts the ;text in between the {{tags}}. Leading and ;trailing whitespace is deleted. ;In addition, the 1 option indicates that ;tabs and line terminators should be ;removed and spaces inserted if required. wbdata=BinaryTagExtr(structure,1) ;At this point we’re going into the deep ;end. In addition to the keyword we ;alluded to previously this code also ;allows parameters behind the keyword. ;For example something like {{DORANDOM 9}} ;is possible (meaning, I suppose, a ;random number between 0 and 9) We ;extract the real keyword DORANDOM into ;the wbcmd variable and then in the next ;statement…. wbcmd=StrLower(ItemExtract(1,wbdata," ")) ;...using sleight of code, we now extract ;the remainder of the wbdata variable ;into the wbparams variable. In the case ;of the {{DORANDOM 9}} example it would be 9. ;If there was nothing behind the keyword ;it would be a null “” string. wbparams=StrTrim(StrSub(wbdata,StrLen(wbcmd)+1,-1)) ;More magic. Real Magic this time. Instead ;of a plethora of IF statements or other ;convoluted logic this single statement will ;execute the #DefineFunction or #DefineSubroutine ;contained in the wbcmd variable. The trick is to ;set up functions/subroutines to handle all the ;keywords in your template file. A few sample ;functions are shown below. In theory the function ;will examine parameters in wbparams,if any, ;and then return the text string that the entire ;{{tag xxx}} should be replaced with. HtmlValue = %wbcmd% (wbparams) ;The BinaryTagRepl takes the string in the ;HtmlValue variable and uses it to replace the ;tagged keyword (such as {{DORANDOM 9}} in our ;running example.). The structure variable is ;also updated with new information. structure=BinaryTagRepl(structure,HtmlValue) ;The EndWhile just tells the while loop to ;loop again to process the next tag EndWhile ;When no more tags are found, a break statement breaks ;out of the while loop and execution continues here ;The BinaryWrite writes out the modified ;HTML file to an outputfile BinaryWrite(bb,tempfile) ;The memory used by the BinaryBuffer is now returned to the system. BinaryFree(bb) ;And then we display the page ShellExecute(tempfile,"","",@ZOOMED,"") Exit ;At the point the script is actually done. Below ;are the various #DefineFunctions and #DefineSubroutines ;that make this all work. In addition to the ones used ;by the example a few other handy functions are included. ;*********************************************************; ;* Definition of Functions and Subroutines for BinaryTag *; ;* keywords. This code has been Gosub'ed from above *; ;*********************************************************; :DefineFunctions ;The VALUE subroutine is the easiest and ;perhaps the most handy of all. It takes a tagged ;keyword like ;{{VALUE FRED}} ;and substitutes the global current value of the ;variable FRED. #DefineSubroutine VALUE(valueX) If IsDefined(%valueX%) subretvar = %valueX% Else subretvar="???subretvar error %valueX% ???" EndIf Return (subretvar) #EndSubroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;The DATE function is also a no-brainer. ;Its take a tagged keyword of {{DATE}} ;and substitutes today’s time and date. #DefineFunction Date(dummy) Return (TimeDate()) #EndFunction ;The purists would holler if we did not have a ;DORANDOM example as referred to above. #DefineFunction DORANDOM(Randmax) Return (Random(RandMax)) #EndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;The PICKONE function receives the choice list from the ;tag as a single variable called choices. It chooses ;one of the choices at random and returns it. #DefineFunction PICKONE(choices) ;Count how many different choices are available count=ItemCount(choices,"|") ;pick a random number in the correct range pick=Random(count-1)+1 ;return that particular choice Return ItemExtract(pick,choices,"|") #EndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This function generates a random color like #123456 ;and returns it, based on a preference for a DARK or LIGHT ;color #DefineFunction RandomColor(type) If type=="DARK" Then offset=0 Else offset=8 color="#" For i=1 To 6 color=StrCat(color,StrSub("0123456789abcdef",Random(7)+1+offset,1)) Next Return color #EndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;PickImageSaveAltText is similar in concept to the PICKONE ;function, except it has the added complexity of parsing out ;the alt= text in the image tag and saving it away in ;a variable. #DefineSubroutine is used instead of #DefineFunction ;as we need to save a persistent copy of the variable away. #DefineSubroutine PickImageSaveAltText(choices) count=ItemCount(choices,"|") pick=Random(count-1)+1 DaChoice= ItemExtract(pick,choices,"|") ;Scoop up and save alt text for a little later SavedAltText="" x=StrIndexNC(DaChoice,'alt="',0,@FWDSCAN) If x!=0 y=StrIndexNC(DaChoice,'"',x+5,@FWDSCAN) If y!=0 SavedAltText=StrSub(DaChoice,x+5,y-x-5) EndIf EndIf Return DaChoice #EndSubroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;The companion function to PickImageSaveAltText, also a ;#DefineSubroutine, that just returns the value of the ;saved variable containing the alt= text. #DefineSubroutine SavedAltTextFromImage(dummy) Return SavedAltText #EndSubroutine Return
Conclusion
The theory is that you should copy and paste this code into WinBatch Studio and make it work. Then play around with it, changing perhaps both the code and the template file and see what you can make work.In any event it is hoped that by studying this document you can imagine things you can do with template file processing. Perhaps just using the BinaryReplace method, or perhaps even getting into modifying one of the above scripts to do your own BinaryTag processing.
And that's it for this month.
Good Luck.
Article ID: W15107File Created: 2014:07:18:13:46:04Last Updated: 2014:07:18:13:46:04