Home

 

Examples

 

Technical

 TextMaestro"

 

2003 TextMaestro Technologies

 

Technical

1.

Introduction

2.

Main Toolbar

3.

Session Toolbar

4.

FTP Toolbar

5.

File Attributes

6.

Project Manager

7.

Account Manager

8.

Browse Remote
System

9.

Text Conversion Dialog

10.

Text Conversion Attributes

11.

Text Conversion Libraries

12.

Text Conversion Rules

13.

Text Conversion Batch Mode

14.

Text Conversion Command Line

15.

Report

16.

Diff-and-Merge

17.

Cross Listings

18.

Program Options

19.

Save Program Data

 

12. Text Conversion Rules

Find And Replace is the canonical form of conversion that we use in various text editors and integrated development environments. In TextMaestro, it attains a new level and thus incurs a small learning curve. It is so due to the power of wild-card and type-card usage. User defines a macro that consists of two parts - Find and Replace. The macro has certain attributes. This macro governs the conversion.

Here we discuss the following:

Usage

(1) Basic find-and-replace

(2) Use of wild-card

(2.1) Generic wild-card

(2.2) Special characteristics of wild-card

(2.2.1) Wild-card by itself

(2.2.2) Wild-card and line-break

(3) Use of type-card

Knobs

(1) Per-line search

(2) Compact construct

(3) Filter processed text

(4) Delimiter parse

Qualifiers

(a) Trim Argument

(b) Case Argument

(c) Clean Argument

(d) Align Argument

(e) Increment Argument

Comments

 

Usage         Top

(1) Basic find-and-replace:         Top

Consider the following input text:

Input

//---------------------------------------------------------

// Session info

//---------------------------------------------------------

CSession::CSession()

{

    m_CreateDir = "Yes";

    m_IsLoaded = "No";

}

Consider this macro:

Find:

//---------------------------------------------------------

// Session info

//---------------------------------------------------------

Replace:

/*

*  TextMaestro Technologies

*  Base constructor initialization of CSession

*/

With these definitions, we get the following output text:

Output

/*

*  TextMaestro Technologies

*  Base constructor initialization of CSession

*/

CSession::CSession()

{

    m_CreateDir = "Yes";

    m_IsLoaded = "No";

}

Definitions of Find and Replace may contain line breaks. Find can be case-insensitive.

 

(2) Use of wild-card:         Top

When you define a macro, either in Work Pad or Find-And-Replace Library, you may choose to check Use wild-card. If you do so, the scheme enters in a mode where wild-card and type-card dictate a 'grammar' based conversion.

 

(2.1) Generic wild-card:         Top

Concept of wild-card can be viewed as pattern-matching. Wild-card is a place holder for arbitrary text on the path of parsing. If the non-wild-card text combined with wild-card text is found in the input text, then the conversion recognizes it as a match. Consider the following input:

Input

void CSession::WriteSessionHeaderInfo(ofstream& temp_out, int s_ind)

{

    CString _t;

    temp_out << "SessionName="   <<  LPCTSTR(m_SessionName)<< ", ";

    temp_out << "Host="          <<  LPCTSTR(m_Host)       << ", ";

    temp_out << "HostType="      <<  LPCTSTR(m_HostType)   << ", ";

    temp_out << "User="          <<  LPCTSTR(m_User)       << ", ";

    temp_out << "RemoteDir="     <<  LPCTSTR(m_RemoteDir)  << ", ";

    temp_out << "LocalDir="      <<  LPCTSTR(m_LocalDir)   << ", ";

    temp_out << "SessionBox="    <<  LPCTSTR(m_SessionBox) << ", ";

    temp_out << "CreateDir="     <<  LPCTSTR(m_CreateDir)  << ", ";

}

Consider this macro:

Find:

"*="

Replace:

"*: "

With these definitions, we get the following output:

Output

void CSession::WriteSessionHeaderInfo(ofstream& temp_out, int s_ind)

{

    CString _t;

    temp_out << "SessionName: "   <<  LPCTSTR(m_SessionName)<< ", ";

    temp_out << "Host: "          <<  LPCTSTR(m_Host)       << ", ";

    temp_out << "HostType: "      <<  LPCTSTR(m_HostType)   << ", ";

    temp_out << "User: "          <<  LPCTSTR(m_User)       << ", ";

    temp_out << "RemoteDir: "     <<  LPCTSTR(m_RemoteDir)  << ", ";

    temp_out << "LocalDir: "      <<  LPCTSTR(m_LocalDir)   << ", ";

    temp_out << "SessionBox: "    <<  LPCTSTR(m_SessionBox) << ", ";

    temp_out << "CreateDir: "     <<  LPCTSTR(m_CreateDir)  << ", ";

}

 

After a " is found, the search keeps assimilating characters until it finds =. What it finds on the way, becomes argument denoted by * in Replace. That is to say, you can use wild-card in Replace as a place-holder of the argument constructed during parsing.

Consider the following macro:

Find:

"*"*<<*LPCTSTR(*)*<<*

Replace:

"<*1>" + <*4> + <*6>

If you match the wild-cards in Find for a certain line, you will notice that first, fourth and sixth wild-card denote some tokens of interest. So we use those wild-cards in Replace in the form of <*n>. Thus, we get this output:

Output

void CSession::WriteSessionHeaderInfo(ofstream& temp_out, int s_ind)

{

    CString _t;

    temp_out << "SessionName=" + m_SessionName +  ", ";

    temp_out << "Host=" + m_Host +  ", ";

    temp_out << "HostType=" + m_HostType +  ", ";

    temp_out << "User=" + m_User +  ", ";

    temp_out << "RemoteDir=" + m_RemoteDir +  ", ";

    temp_out << "LocalDir=" + m_LocalDir +  ", ";

    temp_out << "SessionBox=" + m_SessionBox +  ", ";

    temp_out << "CreateDir=" + m_CreateDir +  ", ";

}

 

Sometimes user might need to use "*" in Find and/or Replace as non-wild-card in a wild-card mode search. In that case, some other character, for example "@", "~", "#", etc. can be used to denote wild-card. When you define a find-and-replace macro from Work Pad or Find And Replace Library you have the option to specify the wild-card character. For above example, if you had specified wild-card flag as "@", the macro would look like this:

Find:

"@"@<<@LPCTSTR(@)@<<@

Replace:

"<@1>" + <@4> + <@6>

Wild-card is @

 

Consider the following input:

Input

InfoTech_01_Program.htm      im_tech_sess_man01.gif

InfoTech_02_ToolbarMain.htm  im_tech_sess_man02.gif

InfoTech_03_TBSession.htm    im_tech_sess_man03.gif

InfoTech_04_TBFtp.htm        im_tech_sess_man04.gif

Now consider the following macro:

Find:

* *

Replace:

* contains *

Here is the output:

Output

InfoTech_01_Program.htm contains      im_tech_sess_man01.gif

InfoTech_02_ToolbarMain.htm contains  im_tech_sess_man02.gif

InfoTech_03_TBSession.htm contains    im_tech_sess_man03.gif

InfoTech_04_TBFtp.htm contains        im_tech_sess_man04.gif

Note that in Replace you can have wild-card in non-ordinal form. In that case wild-cards in Replace are resolved in the order they are found. I.e., the first wild-card stands for the first argument, and the second wild-card, for the second argument, and so on. It is recommended that you specify wild-cards in Replace in ordinal format (<*n>) for clarity.

 

(2.2) Special characteristics of wild-card:         Top

There are a few special characteristics of wild-card usage. If you are not familiar with them, you might find some of the wild-card effects unexpected. Once familiar, those special characteristics rather become handy.

 

(2.2.1) Wild-card by itself:         Top

Find consisting of single wild-card denotes the whole line. Consider the following input:

Input

void CTextCvt::SetCurrentIndex()

{

    m_dnLibInd_TP = CStaticLibraryDlg::m_nLibInd_TP;

    m_dnLibInd_FR = CStaticLibraryDlg::m_nLibInd_FR;

    m_dnLibInd_KL = CStaticLibraryDlg::m_nLibInd_KL;

}

Consider the following macro:

Find:

*

Replace:

// *

Here is the output:

Output

// void CTextCvt::SetCurrentIndex()

// {

//     m_dnLibInd_TP = CStaticLibraryDlg::m_nLibInd_TP;

//     m_dnLibInd_FR = CStaticLibraryDlg::m_nLibInd_FR;

//     m_dnLibInd_KL = CStaticLibraryDlg::m_nLibInd_KL;

// }

On the other hand, Find consisting of double wild-cards denotes the whole input. With the following macro:

Find:

@@

Replace:

/*

-------------------------------------------------------

@@

-------------------------------------------------------

*/

we get the following output from the above input:

Output

/*

-------------------------------------------------------

void CTextCvt::SetCurrentIndex()

{

    m_dnLibInd_TP = CStaticLibraryDlg::m_nLibInd_TP;

    m_dnLibInd_FR = CStaticLibraryDlg::m_nLibInd_FR;

    m_dnLibInd_KL = CStaticLibraryDlg::m_nLibInd_KL;

}

-------------------------------------------------------

*/

Note that we had to switch to "@" for wild-card, since we used "*" as non-wild-card in Replace.

 

(2.2.2) Wild-card and line-break:         Top

Wild-card at the beginning of Find denotes text from the previous line-break. Consider the following macro.

Find:

*=

Replace:

// *=

From the same input above we get the following output:

Output

void CTextCvt::SetCurrentIndex()

{

//     m_dnLibInd_TP = CStaticLibraryDlg::m_nLibInd_TP;

//     m_dnLibInd_FR = CStaticLibraryDlg::m_nLibInd_FR;

//     m_dnLibInd_KL = CStaticLibraryDlg::m_nLibInd_KL;

}

 

In similar fashion, wild-card at the end of Find denotes text to the next line-break. Consider the following macro:

Find:

=*

Replace:

= 0; // *

which creates this output:

Output

void CTextCvt::SetCurrentIndex()

{

    m_dnLibInd_TP = 0; //  CStaticLibraryDlg::m_nLibInd_TP;

    m_dnLibInd_FR = 0; //  CStaticLibraryDlg::m_nLibInd_FR;

    m_dnLibInd_KL = 0; //  CStaticLibraryDlg::m_nLibInd_KL;

}

 

 

(3) Use of type-card:         Top

Similar to wild-card, there is a parallel concept of type-card. Type-card can be used only when Use wild-card is checked. Let us begin with an example. Consider the following input:

Input

Each  macro    you  define  can be     stored  in     a  library.

When    you    click  on   the convert   button from    the library

panel,   you  basically   execute   the  active  macros   of the

library   sequentially.    Using   a library   of macros  on an

input   is   a   whole    new   level   of    muscle  to  flex.

 

Note the occurrences of multiple blanks, which ideally should be just one blank. One or many consecutive blanks are denoted by ^b type-card. Consider the following macro:

Find:

^b

Replace:

(blank)

which gives the following output:

Output

Each macro you define can be stored in a library.

When you click on the convert button from the library

panel, you basically execute the active macros of the

library sequentially. Using a library of macros on an

input is a whole new level of muscle to flex.

 

By default, there are six kinds of type-cards per library:

 

When used in wild-card mode denotes:

 

^b

one or many consecutive blank spaces (' ' and/or tabs).

(Blank)

^n

one or many consecutive line-breaks (accepting blanks on the way).

(\n)

^a

one or many consecutive characters from a-z and A-Z sets.

(Alpha)

^d

one or many consecutive characters from 0-9 sets.

(Digit)

^m

one or many consecutive math operators: + - * / < > { } [ ] ( ) =

(math)

^p

one or more consecutive punctuation operators: , . : ; " '

(punctuation)

User can define his own set of type-cards using Wild-card Manager. See more.

Here are some examples. Consider the following input:

Input

Box05-Ses25-Get-Bld-92903.txt  10

Box05-Ses26-Importedtest.jpg  10

Box05-Ses27-Hypnos.gif  10

Box05-Ses28-Hypnos-Part.txt  11

Box05-Ses29-Hypnos-Linux-Build.txt 11

Box06-Ses30-Text-Pos.txt  12

Box07-Ses31-Inter-Dev.com  12

Box07-Ses32-Inter-Port.txt  12

Box07-Ses33-Test-Suit.txt  13

Box07-Ses34-Test-Match.bmp  14

Box07-Ses35-Test-New.txt  15

Consider this macro:

Find:

^a^d^m^a^d^m*.^a*^d

Replace:

   *.<^a3><a=30><^d3>

which gives the following output:

Output

   Get-Bld-92903.txt         10

   Importedtest.jpg          10

   Hypnos.gif                10

   Hypnos-Part.txt           11

   Hypnos-Linux-Build.txt    11

   Text-Pos.txt              12

   Inter-Dev.com             12

   Inter-Port.txt            12

   Test-Suit.txt             13

   Test-Match.bmp            14

   Test-New.txt              15

 

Compare the color high-lighting of the first line of Input with that of Find.

Find:

^a^d^m^a^d^m*.^a^b^d

First line:

Box05-Ses25-Get-Bld-92903.txt  10

            +-----------+

                  *

Notice how * stands for Get-Bld-92903, 3rd <^a> for txt and 3rd <^d> for 10. In Replace we accessed 3rd <^a> by <^a3>, and 3rd <^d> by <^d3>. That is to say, type-cards can be accessed by their ordinals, just like the wild-cards.

As an exercise, now consider the following macro:

Find:

^a^d^m^a^d^m*.^a*^d

Replace:

*.<^a3><a=30?.><^a1> <^d1><a=45?.><^a2> <^d2><a=60?.><^d3>

which gives the following output:

Output

Get-Bld-92903.txt............Box 05.........Ses 25.........10

Importedtest.jpg.............Box 05.........Ses 26.........10

Hypnos.gif...................Box 05.........Ses 27.........10

Hypnos-Part.txt..............Box 05.........Ses 28.........11

Hypnos-Linux-Build.txt.......Box 05.........Ses 29.........11

Text-Pos.txt.................Box 06.........Ses 30.........12

Inter-Dev.com................Box 07.........Ses 31.........12

Inter-Port.txt...............Box 07.........Ses 32.........12

Test-Suit.txt................Box 07.........Ses 33.........13

Test-Match.bmp...............Box 07.........Ses 34.........14

Test-New.txt.................Box 07.........Ses 35.........15

It is apparent that various type-cards are used in Replace to generate various columns above. What might not be so obvious is the use of qualifier <a=m>. There are four types of qualifiers. We will discuss them here.

 

Comments: (a) User can configure (define) his own set of type-cards by using Wild-Card Manager which is found under Work-Pad and Find-Replace library.

(b) Unlike wild-card, rules behind type-cards are simple. However, there is one note-worthy similarity -- the concept of arguments to re-arrange wild-cards holds for type-cards.

(c) Type-cards are available only in Find-and-replace scheme.

 

Knobs         Top

(1) Per-line search:         Top

Recall, wild-card search continues parsing arbitrary text until it matches non-wild text. This search continues even if a line-break is encountered on the way. There comes time when a wild-card search spilling over a line-break becomes undesirable. Consider the following input:

Input

   1. m_tech_cvt_batch_01.gif

   2. m_tech_sch_batch_01.gif

   3. m_tech_cvt_batch_02.htm

   4. m_tech_sch_batch_02.gif

   5. m_tech_cvt_qhelp_01.gif

   6. m_tech_sch_qhelp_01.gif

   7. m_tech_cvt_qhelp_03.htm

   8. m_tech_sch_qhelp_04.gif

   9. m_tech_cvt_scheme_01.htm

  10. m_tech_sch_scheme_01.htm

Suppose we want to get handle of the files that have cvt and htm. One might think cvt*htm would do the job. Not quite. The parsing finds cvt in line 1, then it keeps marching until it finds htm, which happens in line 3. Thereby, all the text from cvt to htm spanning over line 1, 2 and 3 becomes the found text. Note the color code in input shown below:

Color high-light of input

   1. m_tech_cvt_batch_01.gif

   2. m_tech_sch_batch_01.gif

   3. m_tech_cvt_batch_02.htm

   4. m_tech_sch_batch_02.gif

   5. m_tech_cvt_qhelp_01.gif

   6. m_tech_sch_qhelp_01.gif

   7. m_tech_cvt_qhelp_03.htm

   8. m_tech_sch_qhelp_04.gif

   9. m_tech_cvt_scheme_01.htm

  10. m_tech_sch_scheme_01.htm

Certainly, using cvt*htm will not give you the desired result. Although sometimes it is feasible to define Find so that the parsing remains within a line, bear in mind that it will become unnecessarily complicated, when you have a choice of forcing the wild-card search to become per-line search. When you define a macro in Work Pad or Find And Replace Library, check on Per-line search. In that mode, parsing that is about to spill to the next line is discontinued and a new search begins from the next line. In other words, when cvt*htm is not found in line 1, the current search will be discontinued, and it will resume from line 2. In line 2, cvt*htm is an immediate miss. So it will discontinue this search as well and begin another from line 3. And there it will be a hit.

In summary, use Per-line search as appropriate and it will keep you out of messy run-through problem.

Consider this macro:

Find:

*cvt*htm

Replace:

Found file is: *cvt*htm

Per-line search - not checked

The output, albeit undesirable is this:

Output

Found file is:    1. m_tech_cvt_batch_01.gif

   2. m_tech_sch_batch_01.gif

   3. m_tech_cvt_batch_02.htm

   4. m_tech_sch_batch_02.gif

Found file is:    5. m_tech_cvt_qhelp_01.gif

   6. m_tech_sch_qhelp_01.gif

   7. m_tech_cvt_qhelp_03.htm

   8. m_tech_sch_qhelp_04.gif

Found file is:    9. m_tech_cvt_scheme_01.htm

  10. m_tech_sch_scheme_01.htm

Consider this macro:

Find:

*cvt*htm

Replace:

Found file is: *cvt*htm

Per-line search - checked

The output is:

Output

   1. m_tech_cvt_batch_01.gif

   2. m_tech_sch_batch_01.gif

Found file is:    3. m_tech_cvt_batch_02.htm

   4. m_tech_sch_batch_02.gif

   5. m_tech_cvt_qhelp_01.gif

   6. m_tech_sch_qhelp_01.gif

Found file is:    7. m_tech_cvt_qhelp_03.htm

   8. m_tech_sch_qhelp_04.gif

Found file is:    9. m_tech_cvt_scheme_01.htm

  10. m_tech_sch_scheme_01.htm

 

(2) Compact construct:         Top

Use of Compact construct is somewhat similar to Per-line search where you over-ride the blind pattern matching. The difference between Per-line search and Compact construct is: while effect of the former reflects on line by line, that of the latter is on block by block. Consider the following input:

Input

Begin

   line 1

   line 2

End

Begin

   line 1

   999

   line 2

End

Suppose we want to get handle of the second block using the text 999. One might think Begin*999*End would do the job. Not really. The parsing finds Begin in line 1, then it keeps marching until it finds 999, and then it goes on to look for the following End. Thus parsing returns both block one and block two for Begin*999*End. That is the case when you do not check on Compact construct.

 

However, with Compact construct checked, parsing will return the second block only. In that case, search handle is advanced to determine if a match can be obtained within the current match. If so, parsing returns the match of shorter span. Otherwise, the original match remains effective. In other words, Compact construct advances search handle to make Find of minimal span.

This is the color-highlighting of parsing for Begin*999*End when Compact construct is not checked.

Colored input

Begin

   line 1

   line 2

End

Begin

   line 1

   999

   line 2

End

This is the color-highlighting of parsing for Begin*999*End when Compact construct is checked.

Colored input

Begin

   line 1

   line 2

End

Begin

   line 1

   999

   line 2

End

 

Comments: There are subtleties between Per-line search and Compact construct. There are cases where both will render exactly the same effect. For example, if you use Compact construct instead of Per-line search (or both) on the input text in (4) above, you will get the same results. It is so, because the work of Compact construct there contains within each line. Whenever definition of Find encompasses line-breaks, you should use Compact construct, not Per-line search. For the converse, you should prefer Per-line search, although both are equivalent.

 

(3) Filter processed text:         Top

When you define a macro in Work Pad or Find And Replace Library, you can check on this option in order to extract text of interest. If checked, the conversion process will keep only the found-and-replaced text and discard the rest of input. This option is also referred to as filtering text. It is useful when you want to excerpt text of interest from a large amount of text. For example, consider the following macro:

Find:

*cvt*htm

Replace:

Found file is: *cvt*htm

Per-line search - checked

Keep found-and-replaced text Only- checked

Here is the output:

Output

Found file is:    3. m_tech_cvt_batch_02.htm

Found file is:    7. m_tech_cvt_qhelp_03.htm

Found file is:    9. m_tech_cvt_scheme_01.htm

 

(4) Delimiter parse:         Top

When you define a macro in Work Pad or Find And Replace Library, you can check on this option in order to force the parsing to grab a block of text delimited by a pair delimiters. Here is how it works:

  • Typically you enter pair delimiters such as {}, (), [], Begin End or what ever you choose in Delimiter List. No single delimiter is allowed for this option, neither it makes sense. You can access Delimiter List only if you check Use Wild card option under Find.

  • Then the scheme uses the delimiters in the order they are listed and construct all blocks.

  • Next it checks which of the blocks contain Find, which can be defined by wild-cards, type-cards, and explicit string.

  • The blocks that contain such Find are replaced by the Replace string, which can be constructed by wild-card, type-card and explicit string.

Keep in mind that the whole block of text identified by the pair of delimiters is replaced by Replace string, no matter what it is.

Consider the following input and Find and Replace:

Input

Begin

   line 1

   line 2

   Begin

      line 3

      line 4

      load "C:\temp\foo.txt"

   End

   line 5

   line 6

End

Begin

   line 1

   line 2

End

 

Find:

load "*"

Replace:

// File: *

Delimiter parse - checked

Delimiter list contains - Begin End

 

For having Delimiter parse checked and a pair delimiter Begin End in the Delimiter List, the red colored block above will be marked as a matched block, since it contains load. Furthermore, * will be composed as "C:\temp\foo.txt". On the other hand, the second block of text does not have any load, and thus it is not a hit. Therefore, we obtain the following output:

Input

// File: C:\temp\foo.txt

Begin

   line 1

   line 2

End

 

 

 

 

 

Comments: It is interesting to note what happens if we do not have Delimiter parse checked.

Input

Begin

   line 1

   line 2

   Begin

      line 3

      line 4

      // File: C:\temp\foo.txt

   End

   line 5

   line 6

End

Begin

   line 1

   line 2

End

 

Find:

load "*"

Replace:

// File: *

Delimiter parse - not checked

 

In this case only Find is replaced by Replace string. Again, for Delimiter parse case the whole text block (if it is a hit) is replaced by the Replace string.

 

 

Qualifiers         Top

Like other conversion schemes, Find And Replace has the following qualifiers.

(a) Trim Argument         Top

Using qualifier of the form <*n:s>, where n is the argument number, you can keep at most left s characters of the n-th argument. Similarly the qualifier <*n:-s> allows you to keep at most right s characters of the n-th argument. For example, consider the following input:

Input

IM_TECH_CVT_SCH_01.GIF

IM_TECH_CVT_SCH_02.GIF

IM_TECH_CVT_SCH_03.GIF

IM_TECH_CVT_SCH_04.GIF

IM_TECH_CVT_SCH_05.GIF

With the following macro definition

Find:

*

Replace:

<*1:2>__<*1:-6>

we obtain the following output, where the arguments are trimmed based on the specifications:

Output

IM__01.GIF

IM__02.GIF

IM__03.GIF

IM__04.GIF

IM__05.GIF

 

(b) Case Argument         Top

Using qualifier such as <*nl>, <*nu> and <*np>, where n is argument number, you can change the case of the arguments to lower, upper and proper case, respectively. Consider this input:

Input

IM_TECH_CVT_SCH_01.GIF

IM_TECH_CVT_SCH_02.GIF

IM_TECH_CVT_SCH_03.GIF

IM_TECH_CVT_SCH_04.GIF

IM_TECH_CVT_SCH_05.GIF

With the following macro:

Find:

*_*_*_*.*

Replace:

mv *_*_*_*.* <*1p>-<*2l>-<*3p>-<*4u>.<*5l>

we obtain the following output, where the arguments are changed to lower and proper case:

Output

mv IM_TECH_CVT_sch_01.GIF Im-tech-Cvt-SCH_01.gif

mv IM_TECH_CVT_sch_02.GIF Im-tech-Cvt-SCH_02.gif

mv IM_TECH_CVT_sch_03.GIF Im-tech-Cvt-SCH_03.gif

mv IM_TECH_CVT_sch_04.GIF Im-tech-Cvt-SCH_04.gif

mv IM_TECH_CVT_sch_05.GIF Im-tech-Cvt-SCH_05.gif

 

(c) Clean Argument         Top

Using qualifier of the form <*n?find=rep> you can perform inline find-and-replace to clean an argument. Consider this input:

Input

IM_TECH_CVT_SCH_01.GIF

IM_TECH_CVT_SCH_02.GIF

IM_TECH_CVT_SCH_03.GIF

IM_TECH_CVT_SCH_04.GIF

IM_TECH_CVT_SCH_05.GIF

With the following macro:

Find:

*

Replace:

mv <*1> <*1l?IM_TECH=__i?CVT_?sch=ScHeMe>

Match case - not checked

we obtain the following output:

Output

mv IM_TECH_CVT_SCH_01.GIF __i_scheme_01.gif

mv IM_TECH_CVT_SCH_02.GIF __i_scheme_02.gif

mv IM_TECH_CVT_SCH_03.GIF __i_scheme_03.gif

mv IM_TECH_CVT_SCH_04.GIF __i_scheme_04.gif

mv IM_TECH_CVT_SCH_05.GIF __i_scheme_05.gif

 

Note the elaborate argument cleansing qualifier here. The interpretation of this definition is as follows:

From the first argument (denoted by <$1l...>)

Find IM_TECH and replace it by __i.

Find CVT_ and simply drop it off, since no =rep is present.

Find sch and replace it by ScHeMe, since Match case is ignored.

Finally due to case changing flag "l" in <$1l...>, set this argument-output in lowercase.

This inline find-and-replace in argument cleansing is case-sensitive, and takes place in the order of listing.

 

This qualifier is indeed very powerful. It is so because you can use wild-card and type-card features within the arguments as next round of find-and-replace for the arguments. That goes on to say, if needed one can have nested find-and-replace scheme, which can also relate to the equivalence of using multiple macros from a library.

One of the classical examples in this regard is converting C-style comments to C++ style. Consider the following input:

Input

/*

=====================================================================

TextMaestro Technologies TM

All rights reserved.

=====================================================================

*/

/*

* This module determines the insert location of text

* for right-append feature.

*

*/

int  CTextCvt::M_GetInsertLoc(CString &temp)

{

    int len = temp.GetLength();

    int n=0;

    n = temp.ReverseFind(' ');   /* "23423423423234234" case, no blank */

    if (n<0) return 0;

    if (n==len-1){      /* "123213  23423    " case, trailing blanks */

        while(1){

            if (temp.GetAt(n)==' ') n--;  /* clip tail blanks */

            else break;

        }

        temp = temp.Mid(0, n);

    }

    n = temp.ReverseFind(' ');   /* "231234  23234" case, get pre blank. */

    if (n<0) n = 0;           /* needed for "12312312   " case. */

    return n;

}

Consider the following macro:

Find:

/*@*/

Replace:

<@1?@=//@>

Wild-card is @

Here is the output: (Yes, you can align the in-line C++-style comments. See example.)

Output

//

//=====================================================================

//TextMaestro Technologies TM

//All rights reserved.

//=====================================================================

//

//

//* This module determines the insert location of text

//* for right-append feature.

//*

//

int  CTextCvt::M_GetInsertLoc(CString &temp)

{

    int len = temp.GetLength();

    int n=0;

    n = temp.ReverseFind(' ');   // "23423423423234234" case, no blank

    if (n<0) return 0;

    if (n==len-1){      // "123213  23423    " case, trailing blanks

        while(1){

            if (temp.GetAt(n)==' ') n--;  // clip tail blanks

            else break;

        }

        temp = temp.Mid(0, n);

    }

    n = temp.ReverseFind(' ');   // "231234  23234" case, get pre blank.

    if (n<0) n = 0;           // needed for "12312312   " case.

    return n;

}

Note that text within /* and */ is to be transformed. Since * needs to be a non-wild token in Find, we could not use it as a wild-card. Thereby, we selected @ as wild-card for Find (you can select something else.) By defining Find as /*@*/ we are basically getting hold of a block of C-style comment, which may consist of multiple lines. Once that text is assimilated, we clean it by ?@=//@ qualifier.

Recall, a singleton wild-card denotes one line of the input text. Therefore, the ?@=//@ qualifier grabs each line of the comment text and inserts // in the beginning of the line. Once again, this qualifier is cleansing the argument which is holding the comment text at the moment, and it has no effect outside of the comment block.

 

(d) Align Argument         Top

Using qualifier of the form <a=m> you can align text at m-th column. Consider the following input:

Input

InfoContact.htm   TextCvt

InfoDownload.htm   TextCvt

InfoExamplesRoot.htm   TextCvt

InfoMessageBoard.htm   FtpSupport

InfoPolicy.htm   FtpSupport

InfoService.htm   FtpSupport

InfoServiceMore.htm   WorkSpace

InfoServiceMoreOrg.htm   WorkSpace

Using the following macro:

Find:

*^b*

Replace:

   Project: <*2> <a=30> Module: <*1>

we get this:

Output                                    Column 30

                              |

   Project: TextCvt           Module: InfoContact.htm

   Project: TextCvt           Module: InfoDownload.htm

   Project: TextCvt           Module: InfoExamplesRoot.htm

   Project: FtpSupport        Module: InfoMessageBoard.htm

   Project: FtpSupport        Module: InfoPolicy.htm

   Project: FtpSupport        Module: InfoService.htm

   Project: WorkSpace         Module: InfoServiceMore.htm

   Project: WorkSpace         Module: InfoServiceMoreOrg.htm

 

You can have multiple alignment qualifiers. In that case behavior of the alignment qualifier can be tricky. As a rule of thumb, alignment qualifier means move the current cursor position to m-th column from the previous line break. Here is another example with multiple alignment qualifiers in multi-line definition:

Consider the above input and the following macro definition:

Find:

*^b*

Replace:

#<a=67?.>

Reserve <*1> <a=33> /project=<*2> <a=55> /nooutput

Replace <*1> <a=33> "08-Jan-2004" <a=55> /user=admin

This generates the following output:

Output

#.................................................................

Reserve InfoContact.htm          /project=TextCvt      /nooutput

Replace InfoContact.htm          "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoDownload.htm         /project=TextCvt      /nooutput

Replace InfoDownload.htm         "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoExamplesRoot.htm     /project=TextCvt      /nooutput

Replace InfoExamplesRoot.htm     "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoMessageBoard.htm     /project=FtpSupport   /nooutput

Replace InfoMessageBoard.htm     "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoPolicy.htm           /project=FtpSupport   /nooutput

Replace InfoPolicy.htm           "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoService.htm          /project=FtpSupport   /nooutput

Replace InfoService.htm          "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoServiceMore.htm      /project=WorkSpace    /nooutput

Replace InfoServiceMore.htm      "08-Jan-2004"         /user=admin

#.................................................................

Reserve InfoServiceMoreOrg.htm   /project=WorkSpace    /nooutput

Replace InfoServiceMoreOrg.htm   "08-Jan-2004"         /user=admin

Note the use of <a=67?.> What it means is, move the cursor at column 67 from the previous line break, and while doing so insert "." as the filling character.

 

Similar to the <a=m> qualifier, there exists another option, in particular <A=m>. While <a=m> performs a left-justify effect for the next token, <A=m> performs a right-justify effect for the previous token. For example, <*n> <A=40> <$n+1> means insert filling character (default is blank) before n-th token such that end of it is aligned at 40-th column. Consider the same input and the following macro definition:

Find:

*^b*

Replace:

<*2><A=30?~> <*1><a=60?.>10

This generates the following output:

Output

~~~~~~~~~~~~~~~~~~~~~~TextCvt InfoContact.htm..............10

~~~~~~~~~~~~~~~~~~~~~~TextCvt InfoDownload.htm.............10

~~~~~~~~~~~~~~~~~~~~~~TextCvt InfoExamplesRoot.htm.........10

~~~~~~~~~~~~~~~~~~~FtpSupport InfoMessageBoard.htm.........10

~~~~~~~~~~~~~~~~~~~FtpSupport InfoPolicy.htm...............10

~~~~~~~~~~~~~~~~~~~FtpSupport InfoService.htm..............10

~~~~~~~~~~~~~~~~~~~~WorkSpace InfoServiceMore.htm..........10

Note that the qualifier <A=30?~> placed "~" before the token such that the end of the token is aligned with 30-th column, giving it a right-justify look. The qualifier <a=60?.> on the other hand placed dots at the current position such that last dots in each line are aligned with column 60, which led to the right-justified look for token "10".

In addition, <a=-m?C> allows you to place the cursor at next tab, where tab-width is of m characters, using the filling character C. This is commonly used to replace tab (\t) with blank spaces.

 

(e) Increment Argument         Top

Using qualifier of the form <i=b> allows to place a numerical starting with base b. Consider the following input:

Input

InfoTech_01_Program.htm

InfoTech_02_ToolbarMain.htm

InfoTech_03_TBSession.htm

InfoTech_04_TBFtp.htm

InfoTech_05_TBCvt.htm

InfoTech_06_SessMan.htm

InfoTech_07_FTPman.htm

InfoTech_08_FileAttr.htm

InfoTech_09_BrowseRm.htm

InfoTech_10_WorlPad.htm

InfoTech_11_CvtScheme.htm

With the following macro definition:

Find:

*^d_*

Replace:

  <i=1>. <A=8><*2> <a=45?.><i=10?5>

we get the following output:

Output

    1. Program.htm .........................10

    2. ToolbarMain.htm .....................15

    3. TBSession.htm .......................20

    4. TBFtp.htm ...........................25

    5. TBCvt.htm ...........................30

    6. SessMan.htm .........................35

    7. FTPman.htm ..........................40

    8. FileAttr.htm ........................45

    9. BrowseRm.htm ........................50

   10. WorlPad.htm .........................55

   11. CvtScheme.htm .......................60

Note that the increment offset is by default 1. A qualifier of the form <i=b?N> can be used where N denotes the offset. Above, the offset is 5 in <i=10?5>.

 

A qualifier of the form <i=b#N> can be used where N denotes the width of the incremented value. Consider the following definition:

Find:

*^d_*

Replace:

  <i=1#2>. <*2> <a=45?.><i=10?5#4>

Here is the output:

Output

  01. Program.htm ..........................0010

  02. ToolbarMain.htm ......................0015

  03. TBSession.htm ........................0020

  04. TBFtp.htm ............................0025

  05. TBCvt.htm ............................0030

  06. SessMan.htm ..........................0035

  07. FTPman.htm ...........................0040

  08. FileAttr.htm .........................0045

  09. BrowseRm.htm .........................0050

  10. WorlPad.htm ..........................0055

  11. CvtScheme.htm ........................0060

Note the padding of 0's to make incremented values of 2 digits and 4 digits.

 

 

Comments:         Top

(1) Use Match case: It is strongly recommended to have Match case checked for a macro. A case-sensitive search can be as much as 100 times faster than a non-case-sensitive search.

(2) Caution on multi-line Find: Find may consist of multiple lines. At the same time one can have Search line-by-line checked. But that is contradictory. A Find containing line-break will never be found if Search line-by-line is checked. Because with Search line-by-line option checked, the parsing restarts whenever a line-break is encountered. Therefore, you do not want to have multi-line Find when Search line-by-line is checked.

(3) Caution on using <i=b> and <a=m> flags: If the input has any text of the form <i=b> and <a=m>, then using these flags in Replace might not generate expected results all the time.

(4) Using library of macros: Each macro you define can be stored in a library. When you click on the convert button from the library panel, you basically execute the active macros of the library sequentially. Using a library of macros on an input is a whole new level of muscle to flex.

(5) Delimiters: The delimiter list may have only double delimiters. A double delimiter is one that has begin and end parts.

Top