VS Macro for Pasting Long Text as String
- 05 Jan 2006 16:07
Did you ever want to write very long string constant in your source code? You surely did if you wanted to display longer text in message box, for example. Or you wanted to create a macro which generates some longer source code. In this case you needed the code template stored in a string if you didn't want to read it from a file.
Then you know it is not the easiest thing. You cannot simply paste the text into source code. What if the string text contains 1000 words and newlines? I will discuss a macro which generates VB version of long string here. But hey, non-VB people, don't go away! You already know that VB is a language of VS macros so it can be useful to you too. And you can easily modify the macro to produce string in other languages.
Let's say we want a string with the following text:
This is long
several lines and
"some words in quotes".
The VB code for such string could look like:
Dim str as String = "This is long" + vbCrLf + "text with" + _ "several lines and" + vbCrLf + """some words in quotes""."
As you can see, we cannot simply paste original text to the code. We need to replace newlines with vbCrLf and escape " with "". This could be enough but we also don't want very long lines. So we split the line with standard VB line continuation sequence ' _'. That's all. Those of us who don't have free few hours to do it manually will use the following macro.
The macro takes text from clipboard, performs the string manipulation and pastes the result to the current cursor position.
Create pasteLongTextToCode macro:
Dim cliptext As String '''<summary>Pastes the text from clipboard as the string definition in source '''code.</summary> '''<remarks>The text is enclosed within double quotes. Double quotes in the text '''are escaped by "". New lines are escaped as well. If the text is too '''long, the expression is splitted to multiple lines using "+ '''_".</remarks> Sub pasteLongTextToCode() Dim lineLimit As Integer = 80 Dim text As String Dim ClipBoardThread As System.Threading.Thread = New System.Threading.Thread(AddressOf getStringFromClipboard) With ClipBoardThread .ApartmentState = System.Threading.ApartmentState.STA .IsBackground = True .Start() '-- Wait .Join() End With ClipBoardThread = Nothing text = cliptext Dim newText As String Dim line As String Dim lines As New Collection() ' escape " newText = text.Replace("""", """""") ' crlf -> cr, not to be splitted in the next step newText = newText.Replace(vbCrLf, vbCr) ' wrap text to collection of lines While newText.Length> 0 If newText.Length <= lineLimit Then line = newText newText = "" Else line = newText.Substring(0, lineLimit) newText = newText.Remove(0, 80) End If lines.Add(line) End While ' escape newlines and build final text newText = "" Dim i As Integer For i = 1 To lines.Count line = lines.Item(i) newText += """" + line.Replace(vbCr, """ + vbCrLf + """) + """" If i <lines.Count Then newText += " + _" + vbCrLf End If Next ' paste the result DTE.UndoContext.Open("PasteTextAsString") Dim txt As TextSelection txt = DTE.ActiveDocument.Selection txt.Insert(newText, _ vsInsertFlags.vsInsertFlagsInsertAtEnd) txt.SmartFormat() DTE.UndoContext.Close() End Sub Sub getStringFromClipboard() Dim dataObject As System.Windows.Forms.IDataObject = System.Windows.Forms.Clipboard.GetDataObject() cliptext = (CType(dataObject.GetData(System.Windows.Forms.DataFormats.Text), String)) End Sub
You can learn three important things from this macro:
- How to insert the text into current document.
- How to retrieve the data from clipboard. You cannot do this directly. You must create a separate thread for this operation in macro.
- How to handle Undo.