@@ -6,6 +6,8 @@ defmodule DprintMarkdownFormatter.PatchBuilder do
66 replacements, supporting both simple strings and heredoc formats.
77 """
88
9+ @ single_char_delimiters [ "\" " , "'" , "/" , "|" , "(" , "[" , "{" , "<" ]
10+
911 @ doc """
1012 Builds a replacement string for formatted content based on the original
1113 delimiter.
@@ -76,4 +78,68 @@ defmodule DprintMarkdownFormatter.PatchBuilder do
7678 # Heredoc format - preserve as heredoc
7779 "\" \" \" \n #{ formatted } \n \" \" \" "
7880 end
81+
82+ @ doc """
83+ Builds a replacement string for sigil content, preserving the original sigil
84+ type and delimiter.
85+
86+ Handles all supported sigil delimiters and maintains proper formatting for both
87+ simple and heredoc-style sigils.
88+
89+ ## Examples
90+
91+ iex> DprintMarkdownFormatter.PatchBuilder.build_replacement_sigil_string("Hello", "~S", "\\ "")
92+ "~S\\ "Hello\\ ""
93+
94+ iex> DprintMarkdownFormatter.PatchBuilder.build_replacement_sigil_string("Hello\\ nWorld", "~S", "\\ "\\ "\\ \" ")
95+ "~S\\ "\\ "\\ \" \\ nHello\\ nWorld\\ n\\ "\\ "\\ ""
96+
97+ iex> DprintMarkdownFormatter.PatchBuilder.build_replacement_sigil_string("Hello", "~s", "/")
98+ "~s/Hello/"
99+ """
100+ @ spec build_replacement_sigil_string ( String . t ( ) , String . t ( ) , String . t ( ) ) :: String . t ( )
101+ def build_replacement_sigil_string ( formatted , sigil_prefix , delimiter ) do
102+ case delimiter do
103+ "\" \" \" " ->
104+ # Heredoc sigil - format exactly like regular heredocs
105+ "#{ sigil_prefix } \" \" \" \n #{ formatted } \n \" \" \" \n "
106+
107+ "'''" ->
108+ # Triple single quote heredoc - same as triple double quotes
109+ "#{ sigil_prefix } '''\n #{ formatted } \n '''\n "
110+
111+ single_delimiter when single_delimiter in @ single_char_delimiters ->
112+ # Single character delimiters - preserve original delimiter structure
113+ closing_delimiter = get_closing_delimiter ( single_delimiter )
114+
115+ # For simple delimiters, match the expected format precisely
116+ # Single-line sigils should not have trailing newline
117+ # Multi-line sigils should have newline after closing delimiter
118+ has_newlines = String . contains? ( formatted , "\n " )
119+
120+ if has_newlines do
121+ # Multi-line content needs newline after closing delimiter
122+ "#{ sigil_prefix } #{ single_delimiter } \n #{ formatted } \n #{ closing_delimiter } \n "
123+ else
124+ # Single-line content - no trailing newline
125+ "#{ sigil_prefix } #{ single_delimiter } #{ formatted } #{ closing_delimiter } "
126+ end
127+
128+ _unknown_delimiter ->
129+ # Fallback to heredoc for unknown delimiters
130+ "#{ sigil_prefix } \" \" \" \n #{ formatted } \n \" \" \" \n "
131+ end
132+ end
133+
134+ # Private helper to get the closing delimiter for bracket-style delimiters
135+ defp get_closing_delimiter ( opening ) do
136+ case opening do
137+ "(" -> ")"
138+ "[" -> "]"
139+ "{" -> "}"
140+ "<" -> ">"
141+ # For quotes, slashes, pipes - closing is same as opening
142+ other -> other
143+ end
144+ end
79145end
0 commit comments