Skip block quotes and code blocks

Skip block quotes and code blocks

diff --git a/lib/checklist_syntax_migrator.rb b/lib/checklist_syntax_migrator.rb
index a215353..b5c798b 100644
--- a/lib/checklist_syntax_migrator.rb
+++ b/lib/checklist_syntax_migrator.rb
@@ -1,14 +1,36 @@
 # frozen_string_literal: true
 
 class ChecklistSyntaxMigrator
-  REGEX = /^( {0,3})\[(_|-|\*|\\\*)\]/
+  CHECKBOX_REGEX = /^( {0,3})\[(_|-|\*|\\\*)\]/
+  CODE_BLOCK_REGEX = /^ {0,3}`‍``/
+  QUOTE_START_REGEX = /^ {0,3}\[quote\=/
+  QUOTE_END_REGEX = /^ {0,3}\[\/quote\]/
 
   def initialize(post)
     @post = post
   end
 
   def update_syntax!
-    @post.raw = @post.raw.gsub(REGEX) { "#{$1}[x]" }
+    lines = @post.raw.split("\n")
+    in_code = false
+    in_quote = false
+    lines.each_with_index do |line, index|
+      if line.match(CODE_BLOCK_REGEX)
+        in_code = !in_code
+      elsif line.match(QUOTE_START_REGEX)
+        in_quote = true
+      elsif line.match(QUOTE_END_REGEX)
+        in_quote = false
+      else
+        next if in_code || in_quote
+
+        lines[index] = line.gsub(CHECKBOX_REGEX) { "#{$1}[x]" }
+      end
+    end
+    new_raw = lines.join("\n")
+
+    return if new_raw == @post.raw
+    @post.raw = new_raw
     @post.save!
   end
 end
diff --git a/spec/lib/checklist_syntax_migrator_spec.rb b/spec/lib/checklist_syntax_migrator_spec.rb
index de6d61e..dbf5534 100644
--- a/spec/lib/checklist_syntax_migrator_spec.rb
+++ b/spec/lib/checklist_syntax_migrator_spec.rb
@@ -29,6 +29,7 @@ describe ChecklistSyntaxMigrator do
   it "does not replace if more than 3 spaces are before a checkbox" do
     body = "    [\*]\n      [-]"
     post = post_with_body(body)
+    post.save
 
     ChecklistSyntaxMigrator.new(post).update_syntax!
     expect(post.reload.raw).to eq(body)
@@ -37,6 +38,7 @@ describe ChecklistSyntaxMigrator do
   it "does not replace checkboxes after text" do
     body = "what about this? [\*]"
     post = post_with_body(body)
+    post.save
 
     ChecklistSyntaxMigrator.new(post).update_syntax!
     expect(post.reload.raw).to eq(body)
@@ -61,4 +63,56 @@ describe ChecklistSyntaxMigrator do
     expected = "[x] 0 spaces\n [x] 1 space\n  [x] 2 spaces\n   [x] 3 spaces\n    [-] 4 spaces"
     expect(post.reload.raw).to eq(expected)
   end
+
+  it "does not convert checkboxes in code blocks" do
+    body = [
+      "`‍``",
+      "[\*] This won't be converted",
+      "`‍``",
+      "[\*] That will",
+      "`‍``",
+      "[\*] Again this won't",
+      "`‍``"
+    ].join("\n")
+    post = post_with_body(body)
+
+    ChecklistSyntaxMigrator.new(post).update_syntax!
+
+    expected = [
+      "`‍``",
+      "[\*] This won't be converted",
+      "`‍``",
+      "[x] That will",
+      "`‍``",
+      "[\*] Again this won't",
+      "`‍``"
+    ].join("\n")
+    expect(post.reload.raw).to eq(expected)
+  end
+
+  it "does not convert checkboxes in block quotes" do
+    body = [
+      '[quote="markvanlan, post:10, topic:10"]',
+      "[\*] This won't be converted",
+      "[/quote]",
+      "[\*] That will",
+      '[quote="markvanlan, post:11, topic:10"]',
+      "[\*] Again this won't",
+      "[/quote]"
+    ].join("\n")
+    post = post_with_body(body)
+
+    ChecklistSyntaxMigrator.new(post).update_syntax!
+
+    expected = [
+      '[quote="markvanlan, post:10, topic:10"]',
+      "[\*] This won't be converted",
+      "[/quote]",
+      "[x] That will",
+      '[quote="markvanlan, post:11, topic:10"]',
+      "[\*] Again this won't",
+      "[/quote]"
+    ].join("\n")
+    expect(post.reload.raw).to eq(expected)
+  end
 end

GitHub sha: ab526fe8

  1. The equals character isn’t required in [quote] bbcode
  2. I don’t know if we care about this edge case but unclosed quote isn’t a quote so checkboxes after a lone[quote] tag are possible :sweat_smile:
1 Like