Shreeram Modi  Home  Posts  About  Resume  
    
    
    
    
    
  
________________________________________________________________________________


[2025-01-23] Verbatim Scripts
________________________________________________________________________________

* Overview .............................................................. [001]
* Installation Instructions ............................................. [002]
* Scripts ............................................................... [003]
  * Send Doc ............................................................ [004]
  * Zap Doc  ............................................................ [005]
  * For Reference ....................................................... [006]
  * Highlight to Fill ................................................... [007]


[001] Overview
________________________________________________________________________________

This post is a collection of advanced Verbatim scripts to provide additional
functions that are useful for debate. The motivation is to make available
the best versions of various scripts that I know of in a way that doesn't
require debaters to install a separate version of Verbatim, which can often
cause issues with permissions and antivirus.

Note that the work is not entirely my own and large amounts of inspiration and
certain functions have been taken from other people's implementations of these
macros.

A few disclaimers:

Steps should be followed *exactly* in the order they're presented.

You should generally have an idea of how your computer works before installing
these scripts. I've comprehensively tested the scripts on my computer, and
they have been successfully installed on other peoples' computers as well.
While my instructions are thorough, as a rule of thumb you should understand
what you're doing to your machine and not blindly follow instructions.

[002] Installation Instructions
________________________________________________________________________________

To install scripts in Word you need to add them as a Module in the Visual Basic
section of the existing MS Word template that you want them to be available in.
For Verbatim scripts, this is the Debate.dotm template.

Mac:
+------------------------------------------------------------------------------+
|                                                                              |
| Go to the menu bar > Tools > Macro > Visual Basic Editor                     |
|                                                                              |
+------------------------------------------------------------------------------+

Windows:

First, you will need to enable the developer tab. To do this,
+------------------------------------------------------------------------------+
|                                                                              |
| Go to the Word home menu > options (bottom) > customize ribbon >             |
| in "Main Tabs" check "developer"                                             |
|                                                                              |
+------------------------------------------------------------------------------+

You'll now have a Developer tab in the Word ribbon. Then,
+------------------------------------------------------------------------------+
|                                                                              |
| Go to Developer > Visual Basic                                               |
|                                                                              |
+------------------------------------------------------------------------------+

I would recommend adding macros to a new module. You can do this by going to
the left sidebar, expanding Verbatim, and right clicking Modules > Insert >
Module. Then, you can paste all the scripts below into that new module for the
sake of organization.

After adding the macros below, you also need to add keybindings to trigger them.

To do this in Mac:
+------------------------------------------------------------------------------+
|                                                                              |
| 1. Go to the menu bar > Tools > Customize Keyboard                           |
| 2. Make sure you set "Save changes in" to "Debate.dotm"                      |
| 3. In "Categories" scroll down and click "Macros" then find the macro you    |
|    want to bind                                                              |
| 4. Add the keyboard shortcut, then click "Save"                              |
|                                                                              |
+------------------------------------------------------------------------------+

To do this in Windows, follow this guide[0]

You should also add the following two styles to your Verbatim template:
- Analytic[1]: for analytic arguments that you want deleted from the doc you
               send to your opponent
- Undertag: for brief notes that go below tags which you want deleted from the
            doc you send to your opponent

To add styles to your template:
+------------------------------------------------------------------------------+
|                                                                              |
| 1. Open the styles pane                                                      |
| 2. Click "New Style"                                                         |
| 3. Use the following settings:                                               |
|    - Name: either Analytic or Undertag                                       |
|    - Style type: Paragraph                                                   |
|    - Style based on: Tag                                                     |
|    - Style for following paragraph: Normal                                   |
| 5. Aestheticize the style as you wish using the following options:           |
|    - Color, size, italics[2]                                                 |
| 4. Check "Add to template"                                                   |
|                                                                              |
+------------------------------------------------------------------------------+


Couple of other things

[003] Scripts
________________________________________________________________________________

Each of these scripts can be copied and pasted from the snippet here, or
downloaded by clicking the hyperlink in the title and then copied from that
file.

A disclaimer for the SendDoc and CreateZappedDoc scripts below is that they must
only be used on documents saved to your local computer. If you attempt to run
them on documents saved in an online filestorage (e.g. iCloud, Dropbox, etc.)
they will fail due to a file permission error.

--[004] Send Doc----------------------------------------------------------------

  Provides the SendDoc function, which creates a document in the same folder as
  the current document, which has the same title as the current document just
  with a "[S]" prepended. The send document has all Analytics and Undertags
  omitted, leaving just cards/tags/headers. The title of the macro is "SendDoc"


Sub SendDoc()
    Dim originalDoc As Document
    Set originalDoc = ActiveDocument

    ' Disable screen updating for faster execution
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    ' Extract the folder path from the original document's file path
    Dim originalFolderPath As String
    Dim originalFilePath As String
    originalFolderPath = Left(originalDoc.FullName, InStrRev(originalDoc.FullName, Application.PathSeparator))
    originalFilePath = originalDoc.FullName

    ' Check if doc has previously been saved
    If ActiveDocument.Path = "" Then
        ' If not previously saved
        MsgBox "The current document must be saved at least once."
        Exit Sub
    End If

    ' If previously saved, create a copy
    Dim sendDoc As Document
    Set sendDoc = Documents.Add(ActiveDocument.FullName)

    Selection.WholeStory
    Selection.Find.ClearFormatting
    Selection.Find.Style = ActiveDocument.Styles("Analytic")
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = ""
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll

    Selection.WholeStory
    Selection.Find.ClearFormatting
    Selection.Find.Style = ActiveDocument.Styles("Undertag")
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = ""
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll


    Dim savePath As String
    savePath = originalFolderPath & "[S] " & originalDoc.Name
    ActiveDocument.SaveAs2 Filename:=savePath, FileFormat:=wdFormatDocumentDefault
End Sub


--[005] Zap Doc-----------------------------------------------------------------

  Provides Zap, CondenseZap, and CreateZappedDoc.

  Zap deletes all text from card bodies in the current document that is not
  highlighted, i.e. any text that is not to be read in a speech.

  CondenseZap formats the Zapped document properly, removing unnecessary
  line breaks in the card bodies due to the way Zap works.

  CreateZappedDoc creates a document in the same folder as the current
  document that is named the same, just with a "[R]" prepended. It then runs
  Zap and CondenseZap on that document.


Sub Zap(Optional targetDoc As Document = Nothing)
    ' If targetDoc is not passed, use ActiveDocument
    If targetDoc Is Nothing Then
        Set targetDoc = ActiveDocument
    End If

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Tag"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Cite"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Pocket"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Hat"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Block"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Analytic"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Undertag"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = True
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Selection.Find.ClearFormatting
    Selection.Find.Highlight = False
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = ""
        .Replacement.Text = "^p"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting    ' If targetDoc is not passed, use ActiveDocument
        If targetDoc Is Nothing Then
            Set targetDoc = ActiveDocument
        End If
        .Style = "Tag"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Cite"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Block"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Pocket"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Hat"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Analytic"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Application.ScreenUpdating = False
    Options.DefaultHighlightColorIndex = wdTurquoise
    With targetDoc.Content.Find
        .ClearFormatting
        .Style = "Undertag"
        With .Replacement
            .Text = "^&"
            .ClearFormatting
            .Highlight = False
        End With
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

    Selection.HomeKey Unit:=wdStory
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = " ^p"
        .Replacement.Text = "^p"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchWholeWord = False
        .MatchWildcards = False
    End With
    Selection.Find.Execute
    While Selection.Find.Found
        Selection.HomeKey Unit:=wdStory
        Selection.Find.Execute Replace:=wdReplaceAll
        Selection.Find.Execute
    Wend

    Selection.Find.Text = " ^l"
    Selection.Find.Replacement.Text = "^l"
    Selection.Find.Execute
    While Selection.Find.Found
        Selection.HomeKey Unit:=wdStory
        Selection.Find.Execute Replace:=wdReplaceAll
        Selection.Find.Execute
    Wend

End Sub

Sub CondenseZap(Optional targetDoc As Document = Nothing)
    ' If targetDoc is not passed, use ActiveDocument
    If targetDoc Is Nothing Then
        Set targetDoc = ActiveDocument
    End If

    Dim rngTemp As Range
    Dim rngStart As Range, rngEnd As Range

    Application.ScreenUpdating = False

    ' Set the range to the entire document
    Set rngTemp = targetDoc.Content

    With rngTemp.Find
        .ClearFormatting
        .Text = Chr(13) ' Paragraph break
        .Forward = True
        .Wrap = wdFindStop
        .MatchWildcards = False

        Do While .Execute()
            If Not .Found Then Exit Do

                Set rngStart = rngTemp.Duplicate
                Set rngEnd = rngTemp.Duplicate
                rngStart.Collapse wdCollapseStart
                rngEnd.Collapse wdCollapseEnd

                ' If both ranges are highlighted, replace paragraph break with a space
                If rngStart.HighlightColorIndex <> wdNoHighlight And rngEnd.HighlightColorIndex <> wdNoHighlight Then
                    rngStart.End = rngEnd.Start
                    rngStart.Text = " "
                End If

                ' Reset the range
                rngTemp.SetRange rngEnd.End, rngTemp.Document.Range.End
            Loop
        End With

        Application.ScreenUpdating = True
    End Sub

Sub CreateZappedDoc()
    Dim originalDoc As Document
    Dim newDoc As Document
    Dim savePath As String
    Dim originalFolderPath As String
    Dim originalFilePath As String

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    ' Save the original document
    ActiveDocument.Save

    ' Assign the original document to a variable
    Set originalDoc = ActiveDocument

    ' Get the folder path and file path
    originalFolderPath = Left(originalDoc.FullName, InStrRev(originalDoc.FullName, Application.PathSeparator))
    originalFilePath = originalDoc.FullName

    ' Define save path for the modified document
    savePath = originalFolderPath & "[R] " & originalDoc.Name

    ' Save a copy of the document
    originalDoc.SaveAs2 Filename:=savePath, FileFormat:=wdFormatXMLDocument
    Set newDoc = Documents.Open(savePath)

    ' Call Zap and CondenseZap on the new document
    Call Zap(newDoc)
    Call CondenseZap(newDoc)

    ' Save and close the modified document
    newDoc.Save
    newDoc.Close

    ' Reopen the original document
    Documents.Open originalFilePath

    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    MsgBox "Read version created and saved as " & savePath
End Sub


--[006] For Reference-----------------------------------------------------------

  Provides ForReference, which operates on a selection of text. It takes all the
  highlights in the selected text and turns them Gray. This is useful for
  referencing previously read cards in blocks, and for recutting your opponent's
  evidence.


Sub ForReference()
    Dim rng As Range
    Dim char As Range

    ' Exit if there is no selection or if the selection is empty
    If Selection Is Nothing Or Selection.Range.Text = "" Then
        MsgBox "Please select text to apply the highlight change.", vbExclamation
        Exit Sub
    End If

    ' Speed up the macro by disabling screen updates and other processes
    Application.ScreenUpdating = False

    ' Set the range to the current selection
    Set rng = Selection.Range

    ' Loop through each word (or character range) within the selection
    For Each char In rng.Characters
        If char.HighlightColorIndex <> wdNoHighlight Then
            char.HighlightColorIndex = wdGray25 ' Change to gray highlight
        End If
    Next char

    ' Restore screen updates
    Application.ScreenUpdating = True
End Sub


--[007] Highlight to Fill-------------------------------------------------------

  Provides ConvertHighlightsToFills, which takes all the highlights in a
  selection of text and converts them to background fills. This is mainly
  useful for recuts of opponents' evidence, to prevent unihighlight from
  standardizing both your recut and their original highlight. You would first
  use ForReference on their evidence, then convert it to a fill (to preserve
  the gray color), and then rehighlight it.


Sub ConvertHighlightsToFills()
    Dim rng As Range
    Dim char As Range
    Dim highlightColor As Long

    ' Check if there is a selection
    If Selection.Type = wdSelectionIP Then
        MsgBox "No text selected. Please select the text you want to modify.", vbExclamation
        Exit Sub
    End If

    ' Set the range to the current selection
    Set rng = Selection.Range

    ' Loop through each character in the selection
    For Each char In rng.Characters
        ' Check if the character is highlighted
        If char.HighlightColorIndex <> wdNoHighlight Then
            ' Get the RGB color based on the highlight index
            highlightColor = MapHighlightToRGB(char.HighlightColorIndex)

            ' Set the background color to the highlight color
            char.Shading.BackgroundPatternColor = highlightColor

            ' Remove the highlight
            char.HighlightColorIndex = wdNoHighlight
        End If
    Next char

    ' Clean up
    Set rng = Nothing
    Set char = Nothing
End Sub

Function MapHighlightToRGB(highlightIndex As WdColorIndex) As Long
    Select Case highlightIndex
        Case wdYellow: MapHighlightToRGB = RGB(255, 255, 0)
        Case wdBrightGreen: MapHighlightToRGB = RGB(0, 255, 0)
        Case wdTurquoise: MapHighlightToRGB = RGB(0, 255, 255)
        Case wdPink: MapHighlightToRGB = RGB(255, 0, 255)
        Case wdBlue: MapHighlightToRGB = RGB(0, 0, 255)
        Case wdRed: MapHighlightToRGB = RGB(255, 0, 0)
        Case wdDarkBlue: MapHighlightToRGB = RGB(0, 0, 139)
        Case wdTeal: MapHighlightToRGB = RGB(0, 128, 128)
        Case wdGreen: MapHighlightToRGB = RGB(0, 128, 0)
        Case wdViolet: MapHighlightToRGB = RGB(238, 130, 238)
        Case wdDarkRed: MapHighlightToRGB = RGB(139, 0, 0)
        Case wdDarkYellow: MapHighlightToRGB = RGB(128, 128, 0)
        Case wdGray25: MapHighlightToRGB = RGB(210, 210, 210)
        Case wdGray50: MapHighlightToRGB = RGB(128, 128, 128)
        Case Else: MapHighlightToRGB = RGB(255, 255, 255) ' Default to white for unknown colors
    End Select
End Function



[0] Microsoft Support: Customize keyboard shortcuts
[1] Some teams have their style for Analytic arguments named as "Analytics". In
    my opinion, this is incorrect. All of the other styles that come default in
    Verbatim are in the singular tense, e.g. "Tag", "Cite", "Hat", etc. and not
    in the plural tense, e.g. "Tags", "Cites", etc. Therefore, to maintain
    consistency with the default Verbatim styles, any added styles should also
    be in the singular tense.
[2] The reason you don't want to use any other stylistic options for your
    default Analytic or Undertag styles is because those other options are
    often used in *addition* to Analytic or Undertag styles to modify text.
    E.g. many people underline certain words in analytics to add emphasis.
    Making your default analytic style underlined will lead to weird
    appearances for Analytics, which is undesired.



________________________________________________________________________________

(c) Shreeram Modi 2025