Jump to content
Macro Express Forums

Processing text up to last line?


Recommended Posts

Suppose I have lines of text in (say) Notepad, like this:

 

ABC Line 1

Line 2

Line 3

etc

 

I want to change that to:

 

ABC Line 1 ABC Line 1

Line 2 Line 2

Line 3 Line 3

etc

 

i.e. the text is duplicated, separated by a space.

 

Here is a macro that does it for one line:

 

// Assumes cursor at start of first line

Text Type (Simulate Keystrokes): <SHIFT><END> // Selects text

Delay: 100 milliseconds

Clipboard Copy // Copies text to clipboard

Delay: 100 milliseconds

Text Type (Simulate Keystrokes): <END><SPACE> // Goes to end of text and inserts a space

Delay: 100 milliseconds

Clipboard Paste // Pastes a copy of text on same line

Text Type (Simulate Keystrokes): <ARROW DOWN><HOME> // Goes to next line and positions cursor at start of it

Delay: 100 milliseconds

 

And the code:

<COMMENT Value="Assumes cursor at start of first line"/>
<TEXT TYPE Action="0" Text="<SHIFT><END>" _COMMENT="Selects text"/>
<DELAY Flags="\x02" Time="100"/>
<CLIPBOARD COPY _COMMENT="Copies text to clipboard"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<END><SPACE>" _COMMENT="Goes to end of text and inserts a space"/>
<DELAY Flags="\x02" Time="100"/>
<CLIPBOARD PASTE _COMMENT="Pastes a copy of text on same line"/>
<TEXT TYPE Action="0" Text="<ARROW DOWN><HOME>" _COMMENT="Goes to next line and positions cursor at start of it"/>
<DELAY Flags="\x02" Time="100"/>

 

My question is: what is the simplest way to do that for all the lines please? So far I haven't found a tidy solution.

 

--

Terry, East Grinstead, UK

Link to comment
Share on other sites

Why not save the Notepad contents to a temporary file, process that file using MEP file processing and writing out the new contents to a new temporary file, replace the contents of Notepad with the contents of your new file, then delete both files?

Link to comment
Share on other sites

I built this macro for you, Terry. Tested it with 100% success.

 

I took your test text and saved it into a .txt file on my desktop. The file name: Lines.txt

 

I set each line of the process to variable %LineProcess[x]%. (Note that for this particular macro x will always be 1 - there are not Tabs to delimit)

 

I then set variable %ModifiedProcess% as: %LineProcess[1]% %LineProcess[1]%

 

At this point, I append the variable %ModifiedProcess% to a new text file (Line2.txt) with trailing CR/LF checked.

 

The process repeats until all lines have been processed.

 

I now copy file Lines2.txt to file Lines.txt (this effectively over-writes the original Lines.txt).

 

For my coup de grâce I delete Lines2.txt leaving my desktop as it was before I ran the macro. But with a new and improved Lines.txt

 

Here's the code:

ASCII File Begin Process: "C:\Documents and Settings\z051940\Desktop\Lines.txt" (Tab Delimited Text (.txt))
 Variable Set String %ModifiedProcess% to "%LineProcess[1]% %LineProcess[1]%"
 Variable Modify String: Append %ModifiedProcess% to text file, "C:\Documents and Settings\z051940\Desktop\Lines2.txt"
ASCII File End Process
Copy File/Files: "C:\Documents and Settings\z051940\Desktop\Lines2.txt" to "C:\Documents and Settings\z051940\Desktop\Lines.txt"
Delete File/Files: "C:\Documents and Settings\z051940\Desktop\Lines2.txt"

<ASCII FILE BEGIN PROCESS Filename="C:\\Documents and Settings\\z051940\\Desktop\\Lines.txt" Format="Tab" Start_Record="1" Process_All="TRUE" Records="1" Variable="%LineProcess%" Start_Index="1"/>
<VARIABLE SET STRING Option="\x00" Destination="%ModifiedProcess%" Value="%LineProcess[1]% %LineProcess[1]%"/>
<VARIABLE MODIFY STRING Option="\x12" Destination="%ModifiedProcess%" Filename="C:\\Documents and Settings\\z051940\\Desktop\\Lines2.txt" CRLF="TRUE"/>
<ASCII FILE END PROCESS/>
<COPY FILE/FILES Source="C:\\Documents and Settings\\z051940\\Desktop\\Lines2.txt" Dest="C:\\Documents and Settings\\z051940\\Desktop\\Lines.txt" Progress="FALSE" Recurse="FALSE"/>
<DELETE FILE/FILES Path="C:\\Documents and Settings\\z051940\\Desktop\\Lines2.txt" Progress="FALSE" Recurse="FALSE" Permanent="FALSE"/>

Link to comment
Share on other sites

If you need to parse the content of each line into separate elements of an array use the ASCII File Begin/End Process commands. However, if, as seems to be the case here, you want each complete line, use the Text File Begin/End Process command. This would change Steve's macro to something like this (untested):

Text File Begin Process: "C:\Documents and Settings\z051940\Desktop\Lines.txt" (Tab Delimited Text (.txt))
 Variable Set String %ModifiedProcess% to "%LineProcess% %LineProcess%"
 Variable Modify String: Append %ModifiedProcess% to text file, "C:\Documents and Settings\z051940\Desktop\Lines2.txt"
Text File End Process
Copy File/Files: "C:\Documents and Settings\z051940\Desktop\Lines2.txt" to "C:\Documents and Settings\z051940\Desktop\Lines.txt"
Delete File/Files: "C:\Documents and Settings\z051940\Desktop\Lines2.txt"

Link to comment
Share on other sites

If you need to parse the content of each line into separate elements of an array use the ASCII File Begin/End Process commands. However, if, as seems to be the case here, you want each complete line, use the Text File Begin/End Process command. This would change Steve's macro to something like this (untested):
Text File Begin Process: "C:\Documents and Settings\z051940\Desktop\Lines.txt" (Tab Delimited Text (.txt))
 Variable Set String %ModifiedProcess% to "%LineProcess% %LineProcess%"
 Variable Modify String: Append %ModifiedProcess% to text file, "C:\Documents and Settings\z051940\Desktop\Lines2.txt"
Text File End Process
Copy File/Files: "C:\Documents and Settings\z051940\Desktop\Lines2.txt" to "C:\Documents and Settings\z051940\Desktop\Lines.txt"
Delete File/Files: "C:\Documents and Settings\z051940\Desktop\Lines2.txt"

Yep, definitely better. I went with ASCII because I use it a lot, but Text File process is definitely better for a simple text file like this, i.e. no tabs to delimit.

 

The primary difference is that there aren't any arrays to handle, so rather than worrying about %LineProcess[x]%, you just have %LineProcess%.

 

Definitely prettier.

 

I adjusted my macro to reflect Kevin's observation, and it tests true.

 

<TEXT FILE BEGIN PROCESS Filename="C:\\Documents and Settings\\z051940\\Desktop\\Lines.txt" Start_Record="1" Process_All="TRUE" Records="1" Variable="%LineProcess%"/>
<VARIABLE SET STRING Option="\x00" Destination="%ModifiedProcess%" Value="%LineProcess% %LineProcess%"/>
<VARIABLE MODIFY STRING Option="\x12" Destination="%ModifiedProcess%" Filename="C:\\Documents and Settings\\z051940\\Desktop\\Lines2.txt" CRLF="TRUE"/>
<TEXT FILE END PROCESS/>
<COPY FILE/FILES Source="C:\\Documents and Settings\\z051940\\Desktop\\Lines2.txt" Dest="C:\\Documents and Settings\\z051940\\Desktop\\Lines.txt" Progress="FALSE" Recurse="FALSE"/>
<DELETE FILE/FILES Path="C:\\Documents and Settings\\z051940\\Desktop\\Lines2.txt" Progress="FALSE" Recurse="FALSE" Permanent="FALSE"/>

Link to comment
Share on other sites

Thanks both, looks good, I'll try soon and report back.

 

Edit 25 June 2009, 20:32 UK time:

 

Thanks guys. That final version from Steve works fine as it comes. As you've probably guessed, I now need to try using the technique to tidy up the macro I described in the other thread

Editing strings with percent signs. Given that I've got my (cumbersome) method working, that exercise might now wait a while. But it's made me focus on the Text Processing command which I never seem to have really used in earnest, thank you.

 

 

--

Terry, East Grinstead, UK

Link to comment
Share on other sites

I would copy the entire thing to a var and do it all in memory. Splitting into an array sounds like a good idea but one doesn't know how many elements one would have. And we would still need a loop to reassemble output so we might as well chew away at it. See the attached file.

 

Variable Set to ASCII Char 10 to %LF% // Create a carrige return variable
Variable Set to ASCII Char 13 to %CR% // Create a Line Feed varaible
Text Box Display: Howdy! // Warn/prompt  user
Variable Set String %Clip% from the clipboard contents // Get our source data from the clipboard
Variable Set Integer %Position% to the position of "%CR%" in %Clip% // Find the first End of Line character (CR)
Repeat Until %Position% Equals "0" // Repeat until there are no more EoLs.
I get the positon of the next CR at the end of the loop. If there are none it will be zero and this controls the exit.
 Variable Modify Integer %Position%: Decrement // Move back one space so I don't copy the CR out
 Variable Modify String: Copy a substring in %Clip%, starting at 1 and %Position% characters long to %Chunk% // Copy out the first line w/o EoL
 Variable Modify Integer: %Position% = %Position% + 2 // Mov the pointer to the last EoL character
 Variable Modify String %Clip%: Delete a substring starting at 1 and %Position% characters long // Delete the entire line inclusing EoL
 Variable Set Integer %Position% to the position of "%CR%" in %Clip% // Get the position of the first EoL char.
I put it here instead of the beginning to control the loop.
 Variable Modify String %Output%: Append Text (%Chunk% %Chunk%%CR%%LF%) // Append my outpur var with the chunks and an EoL
End Repeat
Variable Modify String: Save %Output% to the clipboard // Push output to the clipboard
Text Box Display: Yup!

Duplicate_duplicate.mex

Link to comment
Share on other sites

I would copy the entire thing to a var and do it all in memory. Splitting into an array sounds like a good idea but one doesn't know how many elements one would have. And we would still need a loop to reassemble output so we might as well chew away at it. See the attached file.

 

Variable Set to ASCII Char 10 to %LF% // Create a carrige return variable
Variable Set to ASCII Char 13 to %CR% // Create a Line Feed varaible
Text Box Display: Howdy! // Warn/prompt  user
Variable Set String %Clip% from the clipboard contents // Get our source data from the clipboard
Variable Set Integer %Position% to the position of "%CR%" in %Clip% // Find the first End of Line character (CR)
Repeat Until %Position% Equals "0" // Repeat until there are no more EoLs.
I get the positon of the next CR at the end of the loop. If there are none it will be zero and this controls the exit.
 Variable Modify Integer %Position%: Decrement // Move back one space so I don't copy the CR out
 Variable Modify String: Copy a substring in %Clip%, starting at 1 and %Position% characters long to %Chunk% // Copy out the first line w/o EoL
 Variable Modify Integer: %Position% = %Position% + 2 // Mov the pointer to the last EoL character
 Variable Modify String %Clip%: Delete a substring starting at 1 and %Position% characters long // Delete the entire line inclusing EoL
 Variable Set Integer %Position% to the position of "%CR%" in %Clip% // Get the position of the first EoL char.
I put it here instead of the beginning to control the loop.
 Variable Modify String %Output%: Append Text (%Chunk% %Chunk%%CR%%LF%) // Append my outpur var with the chunks and an EoL
End Repeat
Variable Modify String: Save %Output% to the clipboard // Push output to the clipboard
Text Box Display: Yup!

I just tried this one, too, since it performs more exactly what Terry originally requested (creating files was offered by Paul and I, whereas Terry just wanted to modify a "live" notepad).

 

I discovered a problem, however, that requires additional commands to rectify.

 

This code assumes the text being copied ends with a line-break. If it does not, the macro will stop processing on the pen-ultimate line, and the last line will not be appended to the %Output% variable.

 

The simple fix is to add this simple line just after setting the %Clip% variable from the clipboard contents.

 

Variable Modify String %Clip%: Append Text (%CR%%LF%)

 

This will ensure that the macro continues until all lines have been duplicated and placed in the Output variable.

 

At this point you may want to add one or two more lines of code after the End Repeat command, depending on what you want.

 

If the text copied did end with a CR/LF, then you'll end up with an extra one placed in your clipboard when the %Output% variable gets pushed.

 

So you simply need to Trim the Output variable.

 

This will get rid of all the ending line-breaks. At this point you might want to append one more %CR%%LF% to the Output variable (if you do want a final line-break).

Link to comment
Share on other sites

Thanks Steve, it's kind of you and Cory to take that trouble. I haven't yet studied the detail of your suggestions thoroughly, but hope to do so soon.

 

But in case you hadn't seen my comment to Paul, note that the specific application is as shown in post #4 of the thread Editing strings with percent signs at

http://pgmacros.invisionzone.com/index.php?showtopic=3939

 

I was having two separate problems:

- Unsure how to handle strings bracketed by percent signs

- Unsure how to process all lines

 

I solved the first myself as described, although I'd still like to hear any alternative methods.

 

I kludged the second, as described. And posted this thread (with a simplified example) to seek better solutions, which Paul, Cory and you have now suggested, thanks.

 

It's been an interesting exercise, not least because the macro operates on ME Pro itself. Something I can't do in Stiletto.

 

Bottom line is that I have a working macro - just not a very tidy one! :rolleyes:

 

--

Terry, East Grinstead, UK

Link to comment
Share on other sites

Your are correct Steve but my ego compels me to explain that I left out that bit on purpose. I often have a lot of checks and handling in my code for things like this but I often omit them for clarity so the audience can more easily grasp the essence of what I am suggesting. However your suggestion is one I had not considered before so I'll have to bear that in mind for the future. Usually I use some combined logic.

Link to comment
Share on other sites

Your are correct Steve but my ego compels me to explain that I left out that bit on purpose. I often have a lot of checks and handling in my code for things like this but I often omit them for clarity so the audience can more easily grasp the essence of what I am suggesting. However your suggestion is one I had not considered before so I'll have to bear that in mind for the future. Usually I use some combined logic.

I don't begrudge you your ego, as far as ME is concerned, I think you've earned it. Frankly, I was a little doubtful that I had discovered an actual flaw in your code. In fact, I didn't think it was a flaw, so much as a simplified version of what would actually be needed. Which you have just pointed out, in a sense, that it was.

 

Your code was also much more in line with what Terry was actually trying to accomplish, so you offered up a more appropriate nugget to work with than Paul or I had.

 

How's that for feeding your ego? Maybe I should stop encouraging you ;)

Link to comment
Share on other sites

Yeah my ego needs no help:)

 

OT alert

 

I know it sounds like false modesty but I really don't think I'm that good. If I had to rank myself I would consider myself a mediocre macro writer. It's just that when a do learn a new nugget and see people struggling with the same problem I feel compelled to share it. Some odd personal failing I suppose.

 

And just to assure you there's no inflated ego I recently decided to learn to program again since my last programming class was Pascal in 1987. I was told VB was for beginners and easy to learn yet fairly powerful and is very similar to VBA and VBScript as well as being a good primer for Powershell which are all tools I want to learn. So I downloaded the free Visual Studio with VB.Net and got a book. OMFG! When I was a young gun racing cars I thought I had a pretty cool tool set in my small Craftsman toolbox. Then when I went to California and my first job was at a general aviation mod shop and there I saw a real mechanic's toolbox the size of a hot dog stand filled with expensive specialized aircraft tools I couldn't even identify. This is how I feel now.

 

I was always very comfortable with ME because it's scripting is a procedural language like what I learned in college but now that I've had a look under the hood of an event driven, object oriented programming language I'm really awed. The first problem I have is just bending my brain to accept the OOP paradigm but also I'm overwhelmed by all the available objects out there and all there parameters, methods, events and so on. And this is supposedly the easy language!

Link to comment
Share on other sites

Your code was also much more in line with what Terry was actually trying to accomplish, so you offered up a more appropriate nugget to work with than Paul or I had.

How's that for feeding your ego?

But now, Scasper, you're damaging and starving my ego! How are you going to make amends for that?

Link to comment
Share on other sites

But now, Scasper, you're damaging and starving my ego! How are you going to make amends for that?

 

I'm a sucky lick-spittle, what can I say.

 

Hmmm... You were quicker on the draw than I was (in fact I've noticed you to be quicker than me on a number of occasions) at the beginning of this thread. And after Cory's recent embarrassing admissions, I would dare-say you are now king of Macro Express.

 

How's that?

 

Probably too much sarcasm... I don't actually find Cory's admissions embarrassing. I could barely follow them. So if you at least could empathize with Cory on how overwhelming learning VB is/can be, then you are doing better than me.

 

I believe VB stands for Visual Basic, but I honestly thought VB, VBA and VBScript were all just terms for the same basic thing.

 

And PASCAL? Seriously? I mean, I learned a smattering of BASIC to make silly little Zork-style programs on my family's TI (closest thing we had to a home computer until the mid '90s) when I was 8 or 9 (Note: I had no idea what Zork was at that time). Then in Jr. Highschool I took a computer programming class (this was '89-'90) where we re-hashed the BASIC I already knew and nothing more, though I did learn about pixels and how to program frighteningly-archaic pictures by coloring pixels in specific points - Let's just say that PacMan had better graphics than anything I could have programmed at that point.

 

Anyway, I figure if nothing else, everybody's ego can be boosted by comparing their skills to my remedial programming expertise.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...