about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/models/status.rb94
1 files changed, 71 insertions, 23 deletions
diff --git a/app/models/status.rb b/app/models/status.rb
index ae0ac4262..f5cefbf5c 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -578,42 +578,90 @@ class Status < ApplicationRecord
     return if text&.nil?
     return unless '#!'.in?(text)
     chunks = []
-    text.split(/(#!(?:[\w:-]+|{[\w:-]+}))/).each do |chunk|
+    tf_command = nil
+
+    text.split(/(#!(?:[\w:-]+|{.*?}))/).each do |chunk|
       if chunk.start_with?("#!")
         chunk.sub!(/{(.*)}$/, '\1')
-        case chunk[2..-1].downcase
+        command = chunk[2..-1].split(':')
+        next if command.blank?
+
+        case command[0]
+        when 'tf'
+          tf_command = command[1..-1]
+        when 'end', 'stop'
+          tf_command = nil
+        when 'char'
+          charmap = {
+            'zws': "\u200c"
+          }
+          command[1..-1].each do |c|
+            next if c.nil?
+            if c.in?(charmap)
+              chunks << charmap[command[1]]
+            elsif (/^\h{1,5}$/ =~ c) && c.to_i(16) > 0
+              begin
+                chunks << [c.to_i(16)].pack('U*')
+              rescue
+                chunks << '?'
+              end
+            end
+          end
         when 'permalink'
           chunks << TagManager.instance.url_for(self)
         when 'cloudroot'
           chunks << "https://monsterpit.cloud/~/#{account.username}"
         when 'blogroot'
           chunks << "https://monsterpit.blog/~/#{account.username}"
-        when 'ping:admins'
-          mentions = User.admins.map { |u| "@#{u.account.username}" }
-          mentions.sort!
-          chunks << mentions.join(' ')
-        when 'ping:mods'
-          mentions = User.moderators.map { |u| "@#{u.account.username}" }
-          mentions.sort!
-          chunks << mentions.join(' ')
-        when 'ping:staff'
-          mentions = User.admins.map { |u| "@#{u.account.username}" }
-          mentions += User.moderators.map { |u| "@#{u.account.username}" }
-          mentions.uniq!
-          mentions.sort!
-          chunks << mentions.join(' ')
-        when 'thread:reall'
-          if conversation_id.present?
-            mention_ids = Status.where(conversation_id: conversation_id).flat_map { |s| s.mentions.pluck(:account_id) }
-            mention_ids.uniq!
-            mentions = Account.where(id: mention_ids).map { |a| "@#{a.username}" }
+        when 'ping'
+          case command[1]
+          when 'admins'
+            mentions = User.admins.map { |u| "@#{u.account.username}" }
+            mentions.sort!
+            chunks << mentions.join(' ')
+          when 'mods'
+            mentions = User.moderators.map { |u| "@#{u.account.username}" }
+            mentions.sort!
+            chunks << mentions.join(' ')
+          when 'staff'
+            mentions = User.admins.map { |u| "@#{u.account.username}" }
+            mentions += User.moderators.map { |u| "@#{u.account.username}" }
+            mentions.uniq!
+            mentions.sort!
             chunks << mentions.join(' ')
           end
-        when 'char:zws'
-          chunks << "\u200c"
+        when 'thread'
+          case command[1]
+          when 'reall'
+            if conversation_id.present?
+              mention_ids = Status.where(conversation_id: conversation_id).flat_map { |s| s.mentions.pluck(:account_id) }
+              mention_ids.uniq!
+              mentions = Account.where(id: mention_ids).map { |a| "@#{a.username}" }
+              chunks << mentions.join(' ')
+            end
+          end
         else
           chunks << chunk
         end
+      elsif tf_command.present?
+        case tf_command[0]
+        when 'replace', 'sub', 's'
+          tf_command[1..-1].in_groups_of(2) do |args|
+            if args.all?
+              chunks << chunk.sub(*args)
+            else
+              chunks << chunk
+            end
+          end
+        when 'replaceall', 'gsub', 'gs'
+          tf_command[1..-1].in_groups_of(2) do |args|
+            if args.all?
+              chunks << chunk.gsub(*args)
+            else
+              chunks << chunk
+            end
+          end
+        end
       else
         chunks << chunk
       end