| 
       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("\"\,", ",\""); } 
  |