Introduction...
MacroPage is basically an HTML compiler - it allows you to use variable, functions, etc in a very HTML-ish way and still generate normal run of the mill HTML at the end of the day. In the programming world, this is the equivalent of C/C++ (where source code is compiled into executables) vs scripting languages such as PHP which are processed at runtime. Don't confuse this with meaning MacroPage is better than PHP or whatever your scripting language of choice is - on the contrary, it's not nearly as versatile - but what it gives up in versatility it gets back in other ways.

Assumptions...
One of the biggest trends that I really dislike in the web world is the concept of realtime sites - by realtime sites I mean sites where every page is generated when it is requested by a user. Some of the scripting systems have decent caching systems incorporated, that if used properly can reduce the amount of times a particular page is regenerated. What I personally think are better are what I call 'near realtime' sites, meaning that at some specified interval a rebuild is triggered; in some cases this might be once a day (SnapFiles), every 5 minutes (Internet Traffic Report), or as content is added (AnalogX). There are several advantages to this approach; if something fails (such as the DB), for 90% of the site it's transparent to the end user, the site runs at peak performance, etc.

What is it Good For...
MacroPage has a couple of advantages over traditional scripting languages, but it doesn't solve everything. The biggest single advantage it has over all scripting languages is performance - nothing can come close since it effectively is compiled once with the result being usable an unlimited number of times. By contrast, a scripting language needs to generate a page each time a user requests it (at worst) or implement some sort of caching mechanism to only rebuild it periodically (at best). Since the output of MacroPage is plain old HTML, it's performance is limited only by the speed of the server that it's running on.

In the Beginning...
MacroPage dates back to the late 90's, when I originally started working with HTML and was frustrated by it's inability to abstract design from actual content - after mucking around with raw HTML for a few years, I finally just said the heck with it and wrote MacroPage. At first it was nothing more than a sort of preprocessed Server Side Include (SSI) basically supporting only the 'include' command you see today, but over the years it's grown in it's implementation and use. Now it provides a good base of functions, from ODBC database integration to conditional processing to basic HTML structure analysis.

MacroPage v0.743 (last updated &FileDate;, &FileSize;k)
MacroPage Examples (last updated &FileDate;, &FileSize;k)

MacroPage is geared towards programmers and web developers who spend a good amount of time 'in the code'. This is not your warm fuzzy happy Frontpage or Dreamweaver world - it's the cold harsh stark reality of the DOS box and batch files, so if you aren't comfortable with those you should probably move along... With the IF command, you can use what are called 'conditional operations'. What this means is that could make a function or template for a forms question, for example, which has a field called 'Required'. Now you can use this in your html, and if you want the question to be required, all you would do is set Required="TRUE", then the IF statement tests to see if Required is TRUE, and if so, then it includes the special html related to making the question required.
Did you know that &FakeValue; is less than 10? I did! The ELSE command is only used in conjunction with the IF command. The ELSE command tells IF, that if the first statement is not TRUE, then it should skip it and do the ELSE. If the statement is TRUE, the IF continues processing, and skips the ELSE to /IF.
Did you know that &FakeValue; is less than 10? I did! Did you know that &FakeValue; is greater than 10? I did! The WHILE command is similar to the IF command, except for one distinct difference; as long as the equation is *NOT* FALSE (ie; 0), the loop will jump up to the beginning and run through again. This is handy when you need to display or do something that doesn't differ too much from each iteration. An example might be if you used this in conjunction with the READFIELD command, you could load all the fields from a database file and display them to a table.
We are on count &IncrementValue; out of 10 Variables are similar to MACRO's, but they can be changes, combine, and manipulated throughout your HTML file. A variable can hold any type of data, from numbers to letters to words, and can be used anywhere, and is commonly used to store something that is likely to change in the future, like a color value or filename. To insert a variable into HTML, you simply type the '&' followed by the variable name, and finish with a ';'. If you want to access a portion of the variable, you can add a '+' and an offset in chars from the start. Similarly, you can add a '[' and an offset to return only 1 character from the variable (whichever one corresponds with the offset you select). You can also get the length of the string by simply adding an '!' before the semicolon. Finally, you can send a pointer to the variable by adding a '@' to the end, right before the ';'. Variables can be changed by calling them exactly the same way as you created them. Also note: Variables created inside of FUNCTIONs or TEMPLATEs will only be valid for the HTML inside the routine; this is what is referred to as 'local' scope. The scope type 'global' is used when you want to declare a variable inside of a function that will persist throughout the page. Scope can also be of type 'override', which is used when you want it to just past down exactly what the variable name is again. You might use 'override', when you're using another type of scripting that uses the same format as &ProductName; does. Please note that the parameters may NOT be global in scope.
Do you know what the ultimate answer is? Well, it's &ExampleValue;! Filter can be used for a variety of tasks, but the most common is to differenciate between a development section of a site and the release version. By setting one global variable to 'Skip', and then using that in areas describing unreleased products or sections of the website, the developers can work with the live content, while it can easily be turned off to update the main website.
No of this information will be used... Copy the contents of one variable into another.
Replace a specified search string with another value.
MACROs are simply like a cut and paste; you define a MACRO, and wherever it is used it will paste in what type defined. MACROs do not have parameters, so they are good for replacing small pieces of code you commonly use over and over. MACROs cannot be modified once they are created, so they are safe from being altered by another included file.
Always indent at the beginning of a paragraph. A function is similar to an HTML code which doesn't require a close, such as META or IMG. Functions can contain parameters, which can alternately be set to some default value if the caller doesn't pass them in. One good example of what you might make a function for would be to set the titlebar on the browser. Since this is never multiline, the phrase you wish to set the title to could be passed as a parameter, automatically placing it between the title commands.
&Message; A Template is conceptually very similar to a function, but has a required close statement (such as FONT is the open, and /FONT is the close). Templates work exceedingly well at encapsulating commonly used open/close code into an easier to read condensed form. One use for the template command might be for a product listing on a website, where each product would use a template to simplify the inclusion of new products at a later date. If you are nesting multiple templates that are contained with other HTML elements, it's possible the tag analyser could report that something wasn't closed properly. If this happens, you can tag the inner templates (the names only) to be ignored in the analysis - to do this simply add the parameter 'BypassAnalysis' when defining the template.
Put you content here... SOLVE allows you to perform complex mathematical calculations, and then output the results into a target variable. All of the common math functions, such as addition, subtraction, multiplication, and division, as well as higher math functions such as sin(), cos(), atan(), exp(), etc. Output can be set to any of the following formats: floating point (the default), integer, hex, or string.
I can even do math for you! Like this: &FakeValue; In some instances, you might find it more convenient to do comparisons against strings, instead of values, in conditionals. COMPARE allows you to test whether two strings are identical, including or excluding case comparison. In most instances, you will want to wrap each string with quotes (as illustrated below, to ensure that all of the text you have entered is compared. COMPARE returns a 1 (true) is the strings are the same, or a 0 (false) if they are not. By default, COMPARE ignores case.
">
Dog!

Cat!
WRITE allows you to store any subsequent HTML generated into another file. One common use is for pages that contain several frames, where each points to a different HTML file. With WRITE, you can store the entire framed page source in just one file, and then generate the additional files at compile time. The output file is stored in the same directory as the source file, unless otherwise specified.
This message will go to output2.htm! ODBC connects to a database using ODBC, allowing queries to be performed and the results to be used for further processing.
&RowNumber; : &TempVariable;
ODBCNEXTROW reads in the next row from a given SQL query and returns the current row number. If the current row number is less than 0, then the query has been completed. In order for this command to function an ODBC session must first be opened using the ODBC command.
The query was successful!
ODBCCOLUMN is used to retrieve values from the current row from the SQL query. In order for this command to function an ODBC session must first be opened using the ODBC command, and at least one ODBCNEXTROW must be called to fill in the information.
And their last name was &TempVariable;. ODBCCOLUMNCOUNT returns the number of columns in each row. In order for this command to function an ODBC session must first be opened using the ODBC command, and at least one ODBCNEXTROW must be called to fill in the information.
There are &TempVariable; columns! ODBCCOLUMNNAME returns the name of the specified column. In order for this command to function an ODBC session must first be opened using the ODBC command, and at least one ODBCNEXTROW must be called to fill in the information.
The first column's name is &TempVariable;! ODBCCOLUMNTYPE returns the type of the specified column. In order for this command to function an ODBC session must first be opened using the ODBC command, and at least one ODBCNEXTROW must be called to fill in the information.
The first column's type is &TempVariable;! READ opens a file for use by any of the READ-family of functions (such as READLINECOUNT or READLINE). If the file contains delimited data, such as a database, separated by commas (ie, comma-delimited), it can be specified with the 'delimiter' parameter.
This file contains &TempVariable; fields!! READFIELDCOUNT returns the number of fields contained in a delimited file. This is primarily used when you are not sure if you might be adding fields to a database at a later time, and would like the webpage to automatically support the new data. In order for this command to function, a file must be opened first using the READ command.
This file contains &TempVariable; fields!! READFIELD is used to retrieve the actual contents of a field from any delimited file. In order for this command to function, a file must be opened first using the READ command.
Did you know record 3, field 7 contains the text '&TempVariable;'? READLINECOUNT returns the number of lines inside a file. In order for this command to function, a file must be opened first using the READ command.
This file contains &TempVariable; lines!! READLINE is used to retrieve the actual contents of a line from inside a file. In order for this command to function, a file must be opened first using the READ command.
Did you know line 71 is '&TempVariable;'? The INCLUDE command allows you to 'include' another file into the current project. This might be a file that contains all of the functions and templates you normally use on your site, the colors that you use, javascript, or even additional HTML script. The included file is loaded from the same directory as the source file; if it cannot be found there, it will check the base path, and if the file is still not found, report an error. If an included file is changed, the DATE and TIME stamps for the source will not change.
The BYPASS keyword lets MacroPage know that it should ignore anything from the commands open, to the commands close. Keep in mind that this also means function, template, variables, etc will NOT work inside.
Anything in here is ignored, so &FakeValue; won't work! The SCRIPT keyword is functionally very similar to BYPASS, but the big distinction is that SCRIPT will still allow the use of variables, so it's possible to combine Macropage output with another 3rd party scripting language.
The ASCII keyword is very similar to BYPASS, they both will not use any advanced processing on their contents. But there is one distinct difference; ASCII will convert any special HTML characters (like the " or the &) into their HTML facsimiles. This can be very helpful when writing something that uses these specials symbols extensively.
&ASCII&
Anything in here is ignored, so &FakeValue; won't work, but better yet, any formatting will be retained, and the text will look the way it should. &/ASCII&
The comment command is much like the HTML comment, except that whatever is contained inside will NEVER be passed to the output HTML. This can be very convenient when you want to place titles at the top of template and functions to help remind you of what they do.
Dude, this is a comment, no one will every even know you tried to call &FakeValue;, let alone that it didn't work! The PASSTHRU keyword is used when you do something called 'function overloading'. What this means is if you decide you want to make the FONT keyword use some different type of defaults, then you could create a template named FONT, and it would override the default HTML FONT call. But now that you've done that, you want to use the original FONT inside of your template named FONT. That's where PASSTHRU comes in; any HTML line you type in will be passed directly down to HTML, very much like BYPASS. But unlike BYPASS, you still can use variables inside the arguments.
Sometimes on larger projects, or in special circumstances, it is convenient to see exactly what is going on while compiling. With the COMPILER command, you can display any message, such as a variables value, the output of a function, or any other message. COMPILER messages are not stored in the output file, and are only seen when compiling.
SYSTEM allows you to execute any commandline program. This is especially helpful when you may be including generated data, which needs to be rebuilt each time the page is updated. By using the system command, you can call the external executable automatically, ensuring that the information it uses is always up to date.
IMAGEWIDTH returns the width (in pixels) of the specified graphic file. Currently only JPEG and GIF images are supported.
IMAGEWIDTH returns the height (in pixels) of the specified graphic file. Currently only JPEG and GIF images are supported.
FILEEXISTS allows you to check whether or not a file exists in the filesystem.
FILESIZE returns the filesize (in bytes) of the specified file.
Displays the full filename of the current file being compiled.
Displays the current file time, in the following format: Hour:Minute:Second TimeOfDay (ie; 06:44:40 PM).
Displays the current file date, in the following format: Month Day, Year (ie; April 10, 1999).
Displays the current file day, in the following format: Day (ie; Saturday).
Displays the current time, in the following format: Hour:Minute:Second TimeOfDay (ie; 06:44:40 PM).
Displays the current date, in the following format: Month Day, Year (ie; April 10, 1999).
Displays the current day, in the following format: Day (ie; Saturday).