Multiline regex

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
dragoonEarth
Posts: 1
Joined: 09 May 2022, 02:28

Multiline regex

Post by dragoonEarth » 09 May 2022, 02:44

Hi, I hope everyone is well. This is my first post.

I have this script here that will take some text copied from the clipboard, and uses some regex to put it into proper format.

Specifically, if I press Win+V over any word in "This is a question" it will fire the script.

Code: Select all

- [ ] This is a question #tag1
    - [ ] This is an answer
- [ ] This is another question #tag2
And place it into a file of my choosing (prompts me), in this format:
START
Basic
This is a question
Back:
This is an answer.
Tags: tag1

But suppose I wanted to start including everything in between.

For example,

Code: Select all

- [ ] What is a join in SQL? #dbms #sql 
	- [ ] A join is one of the SQL statements which is used to join the data or the Rose from two or more tables on the basis of a common field or column among them. There are INNER, LEFT, RIGHT, or FULL joins.
	
	```sql
	SELECT column1, column2, ...
	FROM martian
	_____ JOIN base
	ON martian.base_id = base.base_id
	WHERE condition(s)
	ORDER BY value;
	
	
	SELECT v.first_name AS visitor_fn, v.last_name AS visitor_ln
	FROM visitor AS v
	LEFT JOIN martian AS m
	ON v.host_id = m.martian_id;
	```

![](Pasted%20image%2020220503214809.png)

- [ ] What is RDBMS? #dbms
	- [ ] RDBMS is the relational database management system which contains data in the form of tables and data is accessed on the basis of common fields among the tables. MySQL or RDS.
I'd like the output to be like this:

START
Basic
What is a join in SQL?
Back:
A join is one of the SQL statements which is used to join the data or the Rose from two or more tables on the basis of a common field or column among them. There are INNER, LEFT, RIGHT, or FULL joins.

```sql
SELECT column1, column2, ...
FROM martian
_____ JOIN base
ON martian.base_id = base.base_id
WHERE condition(s)
ORDER BY value;


SELECT v.first_name AS visitor_fn, v.last_name AS visitor_ln
FROM visitor AS v
LEFT JOIN martian AS m
ON v.host_id = m.martian_id;
```

![](Pasted%20image%2020220503214809.png)
Tags: dbms

So I'd either need a regex to ignore "- [ ]" for each line or loop through some list using my current regex.

Here's the critical piece, I've commented out where I'm able to copy everything into the clipboard (but it retains the checkboxes):

Code: Select all

} else {
  SetKeyDelay, 100
  Send $j
  sleep, 500
  ;Send +v
  ;Send /\n\- \[{Enter}
  
  clipboard=
  sleep, 500
  Send yy
  ClipWait

  clipboardAnswer := clipboard
  FoundAnswer := RegExMatch(clipboardAnswer, "O)\[(?:\s|x|>|<|\*)]\s*([^#]*[^#\s])",outputanswer)
  newLine := "`r`n"
  ;ruledStyle := "----"
  questionAnswer := "START" newLine "Basic" newLine outputquestion[1] newLine "Back: " newLine outputanswer[1]
  }


Full code:

Code: Select all

; Zim Inbox txt file
FileEncoding, UTF-8

InputBox, UserInput, Flash Card File, Please enter the name of the flashcard set for this card., , 640, 480
if ErrorLevel {
    MsgBox, CANCEL was pressed.
    ExitApp
} else {
    dir := "C:\Users\Vic\Documents\OBSIDIAN\COMPSCI\compsci\FlashCards"
    File := dir . "\" . UserInput . ".md"
    ;MsgBox, Full Path is "%File%"
}


;;Highlight line and copy
#IfWinActive ahk_exe Obsidian.exe
{

RxMatches(hayStack, Needle){
    Result := [] ;new MatchCollection()
    start = 1
    loop
    {
        if(!RegexMatch(haystack, needle, M, start)) 
            break

        Result.Insert(M)
        start := M.Pos + M.Len
    }

    return Result
}

clipboard=
; sleep is necessary
sleep, 500
Send yy
ClipWait
clipboardQuestion := clipboard
FoundQuestion := RegExMatch(clipboardQuestion, "O)\[(?:\s|x|>|<|\*)]\s*([^#]*[^#\s])",outputquestion)

braces := "[{}]"
if (RegExMatch(clipboardQuestion, braces)) {
  clozeQuestion := outputquestion[1]
  regexNeedle := "O)(?<=#)(\w+)"
  ;; First count how many object inside, then add tags correctly
  for i,m in RxMatches(clipboardQuestion, regexNeedle)   ; i is 1..n, m is a Match object
    count += 1
  ;     i, m.Value, m.Pos, m.Len, m[1], m["groupName"]

  for i,m in RxMatches(clipboardQuestion, regexNeedle)   ; i is 1..n, m is a Match object
    if(i = count) {
     tags .= m.Value
    } else {
      tags .= m.Value " "
    }
  sleep, 500

  Fileappend, `n%clozeQuestion%`nTags: %tags%`n`n, %File%
  ExitApp
} else {
  SetKeyDelay, 100
  Send $j
  sleep, 500
  ;Send +v
  ;Send /\n\- \[{Enter}
  
  clipboard=
  sleep, 500
  Send yy
  ClipWait

  clipboardAnswer := clipboard
  FoundAnswer := RegExMatch(clipboardAnswer, "O)\[(?:\s|x|>|<|\*)]\s*([^#]*[^#\s])",outputanswer)
  newLine := "`r`n"
  ;ruledStyle := "----"
  questionAnswer := "START" newLine "Basic" newLine outputquestion[1] newLine "Back: " newLine outputanswer[1]
  }
  
  regexNeedle := "O)(?<=#)(\w+)"
  ;; First count how many object inside, then add tags correctly
  for i,m in RxMatches(clipboardQuestion, regexNeedle)   ; i is 1..n, m is a Match object
    count += 1
  ;     i, m.Value, m.Pos, m.Len, m[1], m["groupName"]
  
  for i,m in RxMatches(clipboardQuestion, regexNeedle)   ; i is 1..n, m is a Match object
    if(i = count) {
      questiontags .= m.Value
    } else {
      questiontags .= m.Value " "
    }

  for i,m in RxMatches(clipboardAnswer, regexNeedle)   ; i is 1..n, m is a Match object
    count += 1
  ;     i, m.Value, m.Pos, m.Len, m[1], m["groupName"]
  
  for i,m in RxMatches(clipboardAnswer, regexNeedle)   ; i is 1..n, m is a Match object
    if(i = count) {
      answertags .= m.Value
    } else {
      answertags .= m.Value " "
    }

  tags := questiontags " " answertags
  For i, value in StrSplit(tags , A_space), uniques := {}, tagsNoDups := ""
	  if !uniques.HasKey(value)
	  	tagsNoDups .= value . A_space , uniques[value] := true

  sleep, 500
  Fileappend, `n%questionAnswer%`nTags: %tagsNoDups%`nEND`n`n`n, %File%
  ExitApp
}

Return to “Ask for Help (v1)”