Macro Examples |
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, "&", "&"); numchanges += ChangeString(str, "<", "<"); numchanges += ChangeString(str, ">", ">"); numchanges += ChangeString(str, "\"", """);
// 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("\"\,", ",\""); }
|