Macro Examples

Contents  Previous  Next

 

The following example macros show the syntax of Boxer's macro language, while also suggesting useful methods of attack for common programming tasks:

 


Move cursor to bottom of paragraph


 

// move the cursor to the bottom line of the current paragraph

 

macro BottomOfParagraph()

{

while (LineNumber < LineCount && !LineIsEmpty(LineNumber+1))

   Down;

}

 


Move cursor to top of previous paragraph


 

// move the cursor to the top line of the previous paragraph

 

macro TopOfPreviousParagraph()

{

Up;

 

while (LineNumber > 1 && !LineIsEmpty(LineNumber-1))

   Up;

 

StartOfLine;

}

 


Move cursor to top of current paragraph


 

// move the cursor to the top line of the current paragraph

 

macro TopOfCurrentParagraph()

{

while (LineNumber > 1 && !LineIsEmpty(LineNumber-1))

   Up;

}

 


Move cursor to top of next paragraph


 

// move the cursor to the first line of the next paragraph

 

macro TopOfNextParagraph()

{

while (LineNumber < LineCount && !LineIsEmpty(LineNumber))

   Down;

 

Down;

StartOfLine;

}

 


Add a newline after every closing angle bracket


 

// add a newline after each closing angle (>) character

// unless the angle already appears at end of line

 

macro AddNewlineAfterCloseAngle()

{

int line, i, j;

string str;

 

// loop on all lines in the file

for (line = 1; line <= LineCount(); line++)

   {

   // get the text of line 'line' into string 'str'

   GetLineText(line, str);

 

   // get the index of the closing angle

   j = strchr(str, '>');

 

   // if the character was found and was not at end-of-line...

   if (j != -1 && str[j+1] != '\0')

       {

       GotoLine(line);

       GotoColumn(1);

 

      // advance the cursor to the character     

       while (ValueAtCursor() != '>')

           Right;

 

       // and past the character

       Right;

 

       // insert a newline

       Enter;

 

       // process this line again in case other tags exist

        line--;

        }

   }

}

 


Apply HTML markup to a simple text file


 

// apply HTML markup to a simple text file

// also converts double quote, ampersand, and

// angle brackets to HTML equivalents

 

macro ApplyHTMLMarkup()

{

int prevlen, len, i;

string str;

int numchanges;

 

// loop on all lines in the file

for (i = 1; i <= LineCount; i++)

   {

   // get the text of line 'i' into 'str'

   GetLineText(i, str);

 

   // reset the change counter

   numchanges = 0;

       

    // convert sensitive characters to HTML codes

   numchanges += ChangeString(str, "&",  "&amp;");

   numchanges += ChangeString(str, "<",  "&lt;");

   numchanges += ChangeString(str, ">",  "&gt;");

   numchanges += ChangeString(str, "\"", "&quot;");

 

    // if changes were made, replace the line's text

   if (numchanges > 0)

        PutLineText(i, str);

   }

 

// move to top of file

StartOfFile;

Down;

 

// loop on all lines in the file, starting on line 2

for (i = 2; i <= LineCount; i++)

    {

    // get the length of the previous line

    prevlen = LineLength(i-1);

 

    // get the length of this line

    len = LineLength(i);

 

    // if this line is empty, and the previous line isn't...

    // apply <br> markers to the end of the line

    if (len == 0 && prevlen != 0)

       {

        Up;

        EndOfLine;

        PutString("<br><br>");

        StartofLine;

        Down;

        }

 

    Down;           // move down to the next line

    }

 

StartOfFile;

 

PutString("<html>\n");

PutString("<head>\n");

PutString("<title></title>\n");

PutString("</head>\n\n");

PutString("<body>\n");

 

EndOfFile;

EndOfLine;

PutString("\n");

PutString("</body>\n");

PutString("</html>\n");

 

// place cursor between title and /title

GotoLine(3);

GotoColumn(8);

}

 

 


Display an ASCII chart in a new file


 

// ASCII chart example

 

macro ASCIIchart(void)

{

char i;

 

// open a new file

New;

 

// loop from space to 255 to show all chars

for (i = ' '; i <= 255; i++)

   printf("The ASCII value of '%c' is %d\n", i, i);

}

 


Convert comma-separated-value (CSV) data


 

// convert comma-separated-value (CSV) data on the current

// line so that each field is placed on its own line

 

macro ConvertCSV()

{

string str;

int numquotes, numcommas;

 

// get the count of quotes/commas on this line

numquotes = LineContains(linenumber, "\"");

 

numcommas = LineContains(linenumber, ",");

 

// if this appears to be CSV data...

if (numcommas+1 == numquotes / 2)

   {

   // get the text of the current line

   GetLineText(linenumber, str);

 

   // remove any empty data fields

   ChangeString(str, "\"\",", "");

 

   // convert "," to a newline

   ChangeString(str, "\",\"", "\n");  

 

   // remove the first and last quotes

   ChangeString(str, "\"", "");

 

   // select the line     

    GoToColumn(1);

   SelectToEndOfLine;

 

    // replace the selection

   PutString(str);

   }

 

// position for next line

Down;

StartOfLine;

}

 

 


Cut lines containing a user-defined string


 

// cut lines containing a user-defined string to the Windows clipboard

 

macro CutLinesContaining();

{

int line;

int len;

string str;

int numcut = 0;

 

// get the string from the user

len = GetString("Cut lines containing this string:", str);

 

if (len == 0)

   return;

 

// make the Windows clipboard the active clipboard

SetClipboard(0);

 

// clear the Windows clipboard

ClearClipboard(0);

 

// move cursor to start of file

StartOfFile();

 

// loop on all lines in the file

for (line = 1; line <= LineCount(); line++)

   {

   // does this line contain the string?

   if (LineContains(line, str))

        {

        GotoLine(line);

        CutAppend();

        numcut++;           // tally the cut

        line--;             // stay here for next line

        }

   }

 

// report the results

if (numcut == 1)

   message("Results", "1 line was cut to the Windows clipboard");

else

   message("Results", numcut,

                " lines were cut to the Windows clipboard");

}

 

 


Delete blank lines


 

// delete blank lines in the current file

 

macro DeleteBlankLines(void)

{

int i, len;

 

// start at the top of the file

StartOfFile;

 

// loop on all lines in the file

for (i = 1; i <= LineCount; i++)

   {

   // get the length of this line

   len = LineLength(i);

 

   // is this line empty?

   if (len == 0)

        {

        DeleteLine;     // delete this line

        i--;            // stay at this line #

        }

   else

        {

        Down;           // move down to the next line

        }

   }

}

 

 


Delete lines containing a user-defined string


 

// deletes lines containing a user-defined string

 

macro DeleteLinesContaining()

{

int line;

int len;

string str;

int deleted = 0;

 

// get the string from the user

len = GetString("Delete lines containing this string:", str);

 

if (len == 0)

   return;

 

// loop on all lines in the file

for (line = 1; line <= LineCount(); line++)

   {

   // does this line contain the string?

   if (LineContains(line, str))

        {

        DeleteLine(line);   // delete it

        deleted++;          // tally the deletion

        line--;             // stay here for next line

        }

   }

 

// report the results

if (deleted == 1)

   message("Results", "1 line was deleted");

else

   message("Results", deleted, " lines were deleted");

}

 

 


Delete lines NOT containing a user-defined string


 

// deletes lines NOT containing a user-defined string

 

macro DeleteLinesNotContaining()

{

int line;

int len;

string str;

int deleted = 0;

 

// get the string from the user

len = GetString("Delete lines that do NOT contain this string:", str);

 

if (len == 0)

   return;

 

// loop on all lines in the file

for (line = 1; line <= LineCount(); line++)

   {

   // does this line contain the string?

   if (!LineContains(line, str))

        {

        DeleteLine(line);   // delete it

        deleted++;          // tally the deletion

        line--;             // stay here for next line

        }

   }

 

// report the results

if (deleted == 1)

   message("Results", "1 line was deleted");

else

   message("Results", deleted, " lines were deleted");

}

 

 


Compute return on a deposited amount


 

// Compute result of amount left on deposit with continuous

// compounding.  Uses the formula: P = pe^rt

 

macro ComputeDeposit()

{

float amt, newamt, rate, years;

string str;

 

GetFloat("Enter the amount on deposit:", amt);

 

GetFloat("Enter the interest rate:", rate);

 

// if user entered 5, make it .05, for example

if (rate > 1.0)

   rate /= 100.0;

 

GetFloat("Enter the number of years on deposit:", years);

 

newamt = amt * pow(e, rate * years);

 

sprintf(str, "The amount with interest applied is: %.2f", newamt);

Message("Result", str);

}

 

 


Add blank lines after lines ending with !.?


 

// add a blank line after any line that ends with !.?

 

macro AddBlankLines(void)

{

char ch;

int i;

 

// loop on all lines in the file

for (i = 1; i <= LineCount; i++)

   {

   // make sure this line is not empty

   if (LineLength(i) > 1)

       {

       // move the cursor to this line

       GotoLine(i);

 

        // move to the end of the line

        EndOfLine;

 

        // backup off newline and onto last char

        Left;

 

        // get the value of char at the cursor

        ch = ValueAtCursor();

 

        // if it's a line ender, add Enter

        if (ch == '.' || ch == '?' || ch == '!')

            {

            EndOfLine;

            Enter;

            }

        }

  }

}

 

 


Double space and reformat


 

// double space and reformat the text on the clipboard

// prepares a web document for printing

 

macro DoubleSpaceAndReformat(void)

{

int i;

int numlines;

 

// save various editor settings

SaveSettings;

 

// open a new file and paste from clipboard

New;

Paste;

 

// set Text Width to 96

TextWidth(96);

 

// delete all blank lines

DeleteBlankLines;

 

// record the number of lines BEFORE we start adding lines

numlines = LineCount - 1;

 

// go to the top

StartOfFile;

 

// double space the file

for (i = 1; i <= numlines; i++)

   {

   Down;

   PutString("\n");

   }

 

// reformat the whole file

SelectAllText;

Reformat;

 

// remove any small indents that might be present

SelectAllText;

for (i = 1; i <= 12; i++)

Unindent;

 

// release the selection

Deselect;

 

// restore various editor settings

RestoreSettings;

}

 


Extract email addresses


 

// extract email addresses from all lines within the current file

// and append them to the end of the file

 

macro ExtractEmailAddresses()

{

int i, line, origlinecount;

int inword, isdelim;

int atsigns, dots;

int startword, endword;

string linetext, email;

char c;

 

// note the linecount before we start adding more lines

origlinecount = LineCount;

 

// loop on all lines in the file

for (line = 1; line <= origlinecount; line++)

   {

   // get the text of the whole line into the string 'linetext'

   GetLineText(line, linetext);

 

   // add a space to make end-of-line handling smoother

   strcat(linetext, " ");

 

    // loop on all characters in 'linetext'

   for (inword = FALSE, i = 0; linetext[i] != 0; i++)

        {

        c = linetext[i];

 

        // set a flag if this character is one that delimits words

        if (isalnum(c) || (strchr("_@.-", c) != -1))

            isdelim = FALSE;

        else

            isdelim = TRUE;

 

        // decide whether this character starts a new word,

        // or ends an existing word

        if (inword && isdelim)

            {

            inword = FALSE;

            endword = i-1;

 

            // we've just left a word: see if it had both

            // the required characters

            if (atsigns == 1 && dots >= 1)

                {

                // get the linetext address into a string

                SubString(email, linetext, startword, endword-startword+1);

 

                // add it to the end of the file

                EndOfFile;

                EndOfLine;

                Enter;

                PutString(email);

                }

            }

        else if (!inword && !isdelim)

            {

            inword = TRUE;

            startword = i;

            atsigns = 0;

            dots = 0;

            }

 

        // tally whether or not we see the required chars while we're in a

        if (inword)

            {

            if (linetext[i] == '@')

                atsigns++;

 

            if (linetext[i] == '.')

                    dots++;

            }

        }

   }

}

 

 


Hex to Decimal


 

// shows hex to decimal conversion technique

 

macro HexToDecimal()

{

string str;

int x = 0;

int i, val;

char ch;

 

GetString("Enter a hexadecimal string", str);

 

for (i = 0; str[i] != '\0'; i++)

   {

   ch = str[i];

 

   if (!isxdigit(ch))

       {

       message("Error", "Invalid character encountered: ", ch);

       return;

       }  

 

   ch = toupper(ch);

 

   if (isalpha(ch))

       val = ch - 'A' + 10;

   else

       val = ch - '0';

       

   x = x * 16;

   x = x + val;

   }

 

message("Result", "The decimal value is ", x);

}

 


Obfuscate the selected text with HTML codes


 

// convert the word selected into its HTML coded format

 

// this can be used to convert phone numbers and email addresses

// in web pages to frustrate automated crawlers from harvesting

// your information for spam lists

 

macro Obfuscate()

{

int i;

string str;

string result;

string tmp;

 

if (!TextIsSelected)

   {

   Message("Error",

        "Please select a word before\nrunning the macro.\n");

   return;

   }

 

GetSelection(str);

 

// loop on all characters in 'str'

for (i = 0; str[i] != '\0'; i++)

   {

    sprintf(tmp, "&#%03d;", str[i]);

   strcat(result, tmp);

   }

 

PutSelection(result);

}

 


Display 24-hour time


 

// display the current time in 24-hour time format

 

macro Print24HourTime()

{

int h, m, s;

 

GetTime24(h, m, s);

printf("%d:%02d:%02d", h, m, s);

}

 


Reduce blank lines


 

// reduce multiple blank lines to one blank line

 

macro ReduceBlankLines(void)

{

int thislen, prevlen, i;

 

// position cursor to line 2

StartOfFile;

Down;

 

// loop on all lines in the file (starting with line 2)

for (i = 2; i <= LineCount; i++)

    {

    // get the length of the previous line

    prevlen = LineLength(i-1);

 

   // get the length of this line

   thislen = LineLength(i);

 

   // are both previous and this line empty?

   if (prevlen == 0 && thislen == 0)

        {

        DeleteLine;     // delete this line

        i--;            // stay at this line #

        }

   else

        {

        Down;           // move down to the next line

        }

   }

}

 


Reformat to alternate text width


 

// Reformat the current paragraph to 70 characters, regardless

// of what the current Text Width setting is

 

macro ReformatAlternate()

{

SaveSettings;

TextWidth(70);

Reformat;

RestoreSettings;

}

 


Extract double quoted strings


 

// extract double quoted strings from the current file

// and append them at the bottom of the file

 

macro ExtractStrings()

{

string s, s1, s2, s3;

int i, j, k;

int found = 0;

int original_linecount = LineCount();

 

// loop on all lines in the current file

for (i = 1; i <= original_linecount; i++)

   {

   // does this line have two or more double quotes?

   while (LineContains(i, "\"") >= 2)

       {

       // tally number of strings found

       found++;

 

       // get the text of line 'i' into string 's'

      GetLineText(i, s);

        

       // get the offset of the first double quote    

       j = strchr(s, '\"');

        

       // get the index of the second double quote

       for (k = j + 1; s[k] != '\"'; k++)

           ;

        

       // get the first portion into 's1'

       SubString(s1, s, 0, j);

              

       // get the second portion (the string) into 's2'

      SubString(s2, s, j, k-j+1);

        

       // get the third portion into 's3'

      SubString(s3, s, k+1, 2048);

        

       // build the new line and replace it

       s = s1;

       s += s3;

      PutLineText(i, s);

              

       // gather the strings at the bottom of the current file

      EndOfFile();

      EndOfLine();

      printf("\n%s", s2);

       }

   }

 

// report the results

if (found == 1)

   printf("\n\n%d string was found and removed\n", found);

else

   printf("\n\n%d strings were found and removed\n", found);

}

 


Reverse the text of each line


 

// reverse the text on every line in the file

// "abcdefg" becomes "gfedcba"

 

macro ReverseLineText()

{

int i, len, line;

string str;

char tmp;

 

// loop on all lines in the file

for (line = 1; line <= LineCount; line++)

   {

   len = linelength(line);

 

   // ignore lines too short/long

   if (len >= 2 && len < 2000)

       {

       // get the text of line 'line' into string 'str'

      GetLineText(line, str);

 

       // loop through half this line 

      for (i = 0; i < len/2; i++)

           {

           // swap the characters...

           tmp = str[i];

           str[i] = str[len-1-i];

           str[len-1-i] = tmp;

            }

 

       // replace line with reversed line

        PutLineText(line, str);

        }

   }

}

 


Reverse names: Smith.Bob to Bob.Smith


 

// changes a list of "Smith.Bob" entries to "Bob.Smith"

 

macro ReverseNames()

{

int line, i;

string str;

string first, last;

string newstring;

 

// loop on all lines in the file

for (line = 1; line <= LineCount; line++)

   {

   // get the text of line 'line' into string 'str'

   GetLineText(line, str);

 

   // look for a '.' within 'str'

   i = strstr(str, ".");

 

   if (i != -1)

       {

        // 'last' gets 'i' chars from 'str' starting at index 0

        SubString(last,  str, 0,   i);

 

        // 'first' gets up to 100 chars from 'str' starting at index i+1

        SubString(first, str, i+1, 100);

        

        // build a new string from 'first' and 'last'

        sprintf(newstring, "%s.%s", first, last);

        

        // replace the text of the line

        PutLineText(line, newstring);

        }

   }

}

 


Truncate lines after a user-defined string


 

// truncate lines after a user-defined string

 

macro TruncateLineAfterString()

{

int j, line, len;

int truncated = 0;

string str, linestr, newstr;

 

// get the string from the user

len = GetString("Truncate lines after this string:", str);

 

// if the string is empty, quit

if (len == 0)

       return;

 

// loop on all lines in the file

for (line = 1; line <= LineCount; line++)

   {

   GetLineText(line, linestr);

 

   // does this line contain the string?

   if ((j = strstr(linestr, str)) != -1)

        {

        // create a new string without the trailing text

        SubString(newstr, linestr, 0, j+len);

 

        // replace this line with the new text

        PutLineText(line, newstr);

 

        // tally the truncation

        truncated++;

        }

   }

 

// report the results

if (truncated == 1)

   message("Results", "1 line was truncated");

else

   message("Results", truncated, " lines were truncated");

}

 


Truncate lines at a user-defined string


 

// truncate lines at a user-defined string

 

macro TruncateLineAtString()

{

int j, line, len;

int truncated = 0;

string str, linestr, newstr;

 

// get the string from the user

len = GetString("Truncate lines at this string:", str);

 

// if the string is empty, quit

if (len == 0)

       return;

 

// loop on all lines in the file

for (line = 1; line <= LineCount; line++)

   {

   GetLineText(line, linestr);

 

   // does this line contain the string?

   if ((j = strstr(linestr, str)) != -1)

        {

        // create a new string without the trailing text

       SubString(newstr, linestr, 0, j);

 

        // replace this line with the new text

       PutLineText(line, newstr);

 

        // tally the truncation

        truncated++;

        }

   }

 

// report the results

if (truncated == 1)

   message("Results", "1 line was truncated");

else

   message("Results", truncated, " lines were truncated");

}

 

 


Delete lines that begin with a user-defined string


 

// deletes lines that begin with a user-defined string

 

macro DeleteLinesThatBeginWith()

{

int line, len;

string str, linestr;

int deleted = 0;

 

// get the string from the user

len = GetString("Delete lines that begin with:", str);

 

if (len == 0)

   return;

 

// loop on all lines in the file

for (line = 1; line <= LineCount(); line++)

   {

       // get the text of line 'line' into 'linestr'

       GetLineText(line, linestr);

           // does this line start with 'str'?

       if (strncmp(linestr, str, len) == 0)

               {

               DeleteLine(line);   // delete it

               deleted++;          // tally the deletion

               line--;             // stay here for next line

               }

       }

 

// report the results

if (deleted == 1)

   message("Results", "1 line was deleted");

else

   message("Results", deleted, " lines were deleted");

}

 


Delete lines that end with a user-defined string


 

// deletes lines that end with a user-defined string

 

macro DeleteLinesThatEndWith()

{

int line, len, linelen;

string str, linestr, str2;

int deleted = 0;

 

// get the string from the user

len = GetString("Delete lines that end with:", str);

 

if (len == 0)

   return;

 

// loop on all lines in the file

for (line = 1; line <= LineCount(); line++)

   {

   // get the text of line 'line' into 'linestr'

   linelen = GetLineText(line, linestr);

 

   // if the line is too short, do nothing

   if (linelen < len)

       {

       ;  

       }

   // does this line end with 'str' ?

   else

       {

       // isolate the tail of the line into a string

       SubString(str2, linestr, linelen - len, len);

       

       if (strcmp(str2, str) == 0)

           {

           DeleteLine(line);   // delete it

           deleted++;          // tally the deletion

           line--;             // stay here for next line

           }

       }

   }

 

// report the results

if (deleted == 1)

   message("Results", "1 line was deleted");

else

   message("Results", deleted, " lines were deleted");

}

 


Call MapQuest to show a map


 

// get an address from the user and call it up on MapQuest

 

macro CallMapQuest()

{

string city, state, address, country, url;

int zoom = 7;

 

// get information from the user

GetString("Enter street address:", address);

GetString("Enter city/town:",       city);

GetString("Enter state/province:", state);

GetString("Enter country:",         country);

 

// state level maps are better at zoom level 3

if (city == "")

   zoom = 3;

 

// country level maps are better at zoom level 1

if (state == "")

   zoom = 1;

 

// convert embedded spaces to plus signs

ChangeString(address, " ", "+");

ChangeString(city," ", "+");

ChangeString(state,   " ", "+");

ChangeString(country, " ", "+");

 

// build the URL that will be used                         

sprintf(url,

"http://www.mapquest.com/maps/map.adp?city=%s&state=%s&address=%s&country=%s&zoom=%d"    , city, state, address, country, zoom);

 

// send the URL to Windows so the default browser is run

OpenURL(url);

}

 


Convert British English punctuation to American English punctuation


 

// Convert British English punctuation to American English punctuation

// (in Britain, periods and commas are placed outside double quotes)

 

macro BritishPunctuation()

{

// notice that the double quote character must be escaped with a

// backslash when it appears within a string

 

// change ".  to  ."

ReplaceAll("\".",  ".\"");

 

// change ",  to  ,"

ReplaceAll("\"\,", ",\"");

}