Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Selecting Text Until Specified Character Is Reached
#1
I edit fiction manuscripts and, while some publishers allow MS Word's Track Changes, others want in-line editing:

Example:
She almost felt dizzy at [delete ‘at’ replace with ‘from’] the flood of relief that [delete ‘that’] humans were not involved, but they had been [delete ‘had been’ replace with ‘were’] a target.

Using QM, I select a word or more than one and a macro copies the word or phrase, prompts me for the replacement and then writes what you see above. After QM macro finishes, I would like QM to be able to select all the text between and including the brackets [some text here].

Once selected, I can color the selected text red. One small caveat. After QM completes and I have: [delete ‘at’ replace with ‘from’], the cursor is on the right side, so I need to select from where I am, left to wherever the opening bracket is: [

Any help would be greatly appreciated.
#2
Macro Macro1809
Code:
Copy      Help
;Selects text right-to-left, until [ character.

;out
;act "Word"

spe 1 ;;makes faster
str s sPrev; int i j ;;variables
for i 0 1000000000 ;;repeat
,;key SL ;;Shift+Left. Select 1 character backwards.
,key CSL ;;Ctrl+Shift+Left. Select 1 word backwards. Faster.
,s.getsel ;;copy to s
,if(i and s.len<=sPrev.len) break; else sPrev=s ;;exit loop if does not select more
,j=findcr(s '[') ;;find [ character
,if j>=0 ;;if found
,,if(j>0) s.get(s j); for(i 0 j) key SR ;;if selected too far to the left; go back
,,break ;;exit loop

out s ;;show selected text
#3
Function SelectTextRightUntil
Code:
Copy      Help
;/
function~ $untilText [flags] ;;flags: 1 case insensitive, 2 regex, 4 ignore match at start position, 8 don't include untilText, 16 search in single line

;Selects text in the active window, forward from current position, until specified string.
;Returns the selected text.

;untilText - search for this string.

;REMARKS
;Works with all text editors that support standard keyboard shortcuts for text selection.
;How it works: Repeatedly selects more and more text using keys Ctrl+Shift+Right, gets selected text and searches for untilText. When found, stops and optionally unselects extra text.
;If untilText not found, presses L to unselect text and returns null. In some editors (Word, QM) it sets text cursor to the initial position, however in others (Notepad, OpenOffice) the behavior is different.

;EXAMPLE
;str s=SelectTextRightUntil("]" 0)
;out s


spe 1
str s sPrev
int found i j L(len(untilText)) from

rep
,;select word and get selected text
,key CSR
,s.getsel
,if(s.len<=sPrev.len) break; else sPrev=s ;;exit loop if does not select more
,;find untilText
,;g1
,if(flags&2) j=findrx(s untilText from flags&1 L); else j=find(s untilText from flags&1)
,if(j<0) goto gNext
,;flag 4
,if(flags&4 and j=0) flags~4; from=L; goto g1
,;if selected too far, go back
,j=s.len-j-L
,if(j>0) ST_GoBack(0 j s); s.fix(s.len-j)
,;flag 8
,if(flags&8) ST_GoBack(0 L s); s.fix(s.len-L)
,;found
,found=1
,break
,;gNext
,if(flags&16 and findc(s 10)>=0) break

if(found) ret s

if(sPrev.len) key L

Function SelectTextLeftUntil
Code:
Copy      Help
;/
function~ $untilText [flags] ;;flags: 1 case insensitive, 2 regex, 4 ignore match at start position, 8 don't include untilText, 16 search in single line

;Selects text in the active window, backward from current position, until specified string.
;Returns the selected text.

;untilText - search for this string.

;See also: <SelectTextRightUntil>


spe 1
str s sPrev sQE
int found i j L
if(flags&2=0) untilText=sQE.from("\Q" untilText "\E")

rep
,;select word and get selected text
,key CSL
,s.getsel
,if(s.len<=sPrev.len) break; else sPrev=s ;;exit loop if does not select more
,;find untilText, last match
,FINDRX fr.ito=s.len
,;g1
,ARRAY(CHARRANGE) a
,if(!findrx(s untilText fr flags&1|4|16 a)) goto gNext
,j=a[0 a.ubound].cpMin; L=a[0 a.ubound].cpMax-j
,;flag 4
,if(flags&4 and j+L=s.len) flags~4; fr.ito=j; goto g1
,;if selected too far, go back
,if(j>0) ST_GoBack(1 j s); s.get(s j)
,;flag 8
,if(flags&8) ST_GoBack(1 L s); s.get(s L)
,;found
,found=1
,break
,;gNext
,if(flags&16 and findc(s 10)>=0) break

if(found) ret s

if(sPrev.len) key R

Function ST_GoBack
Code:
Copy      Help
;/
function toRight n str&s ;;private

;Sends Shift+Left/Right to move caret by n positions depending on s.
;Properly handles newlines and Unicode.


if(toRight) _s.left(s n); else _s.right(s n)
_s.findreplace("[]" "[10]")
BSTR b=_s; n=b.len

#if QMVER>=0x02030307
if(toRight) key SR(#n); else key SL(#n)
#else
rep(n) if(toRight) key SR; else key SL
#endif
#4
Many thanks for this, it works perfectly! I could not have accomplished this on my own.
#5
Is it possible with this code to retrieve "DEF" from the below 3 cases (in each case the caret is at a different position, caret is represented by a pipe symbol.)

Code:
Copy      Help
ABC DE|F GHI
ABC |DEF GHI
ABC DEF| GHI

I tried to use regex wordboundry \b but I could not get the syntax right:

Macro Macro35
Code:
Copy      Help
2
;test in the below line (retrieve "DEF")
;ABC DEF GHI

str rgx="\b"
str s
s=SelectTextRightUntil(rgx 16|2)
out s
s=SelectTextLeftUntil(rgx 16|2)
out s

I put the caret at the 3 positions (left of string, in the string and on the right of the string) and then run the above code.
But it does not retrieve "DEF".

(the goal is to get the text at caret position)
#6
I am wondering : which is the best method to deselect each word, after saved in string variable "s" (s.getsel), before selecting next word. Many thanks for any suggestion.


Forum Jump:


Users browsing this thread: 1 Guest(s)