Skip to content

Instantly share code, notes, and snippets.

@dajare
Last active September 3, 2016 15:23
Show Gist options
  • Save dajare/3924560 to your computer and use it in GitHub Desktop.
Save dajare/3924560 to your computer and use it in GitHub Desktop.
LibreOffice Macro - straight quotes to curly
sub StraightQuotes2CurlyQuotes
' Thanks to Tintazul for refinements
' https://gist.github.com/Tintazul/deb5e137cabf86ddf4c2
' Now updated to work with LibreOffice Writer Version: 5.0.x
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
dim undo as object
rem ----------------------------------------------------------------------
rem create single undo action
undo = ThisComponent.UndoManager
undo.enterUndoContext("Educate quotes")
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dim args1(18) as new com.sun.star.beans.PropertyValue
args1(0).Name = "SearchItem.StyleFamily"
args1(0).Value = 2
args1(1).Name = "SearchItem.CellType"
args1(1).Value = 0
args1(2).Name = "SearchItem.RowDirection"
args1(2).Value = true
args1(3).Name = "SearchItem.AllTables"
args1(3).Value = false
args1(4).Name = "SearchItem.Backward"
args1(4).Value = false
args1(5).Name = "SearchItem.Pattern"
args1(5).Value = false
args1(6).Name = "SearchItem.Content"
args1(6).Value = false
args1(7).Name = "SearchItem.AsianOptions"
args1(7).Value = false
args1(8).Name = "SearchItem.AlgorithmType"
args1(8).Value = 1
args1(9).Name = "SearchItem.SearchFlags"
args1(9).Value = 65536
args1(10).Name = "SearchItem.SearchString"
args1(10).Value = CHR$(34)+"\<"
args1(11).Name = "SearchItem.ReplaceString"
args1(11).Value = "“"
args1(12).Name = "SearchItem.Locale"
args1(12).Value = 255
args1(13).Name = "SearchItem.ChangedChars"
args1(13).Value = 2
args1(14).Name = "SearchItem.DeletedChars"
args1(14).Value = 2
args1(15).Name = "SearchItem.InsertedChars"
args1(15).Value = 2
args1(16).Name = "SearchItem.TransliterateFlags"
args1(16).Value = 1280
args1(17).Name = "SearchItem.Command"
args1(17).Value = 3
args1(18).Name = "Quiet"
args1(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1())
rem ----------------------------------------------------------------------
dim args2(18) as new com.sun.star.beans.PropertyValue
args2(0).Name = "SearchItem.StyleFamily"
args2(0).Value = 2
args2(1).Name = "SearchItem.CellType"
args2(1).Value = 0
args2(2).Name = "SearchItem.RowDirection"
args2(2).Value = true
args2(3).Name = "SearchItem.AllTables"
args2(3).Value = false
args2(4).Name = "SearchItem.Backward"
args2(4).Value = false
args2(5).Name = "SearchItem.Pattern"
args2(5).Value = false
args2(6).Name = "SearchItem.Content"
args2(6).Value = false
args2(7).Name = "SearchItem.AsianOptions"
args2(7).Value = false
args2(8).Name = "SearchItem.AlgorithmType"
args2(8).Value = 1
args2(9).Name = "SearchItem.SearchFlags"
args2(9).Value = 65536
args2(10).Name = "SearchItem.SearchString"
args2(10).Value = CHR$(34)+"([\[\(])"
args2(11).Name = "SearchItem.ReplaceString"
args2(11).Value = "“$1"
args2(12).Name = "SearchItem.Locale"
args2(12).Value = 255
args2(13).Name = "SearchItem.ChangedChars"
args2(13).Value = 2
args2(14).Name = "SearchItem.DeletedChars"
args2(14).Value = 2
args2(15).Name = "SearchItem.InsertedChars"
args2(15).Value = 2
args2(16).Name = "SearchItem.TransliterateFlags"
args2(16).Value = 1280
args2(17).Name = "SearchItem.Command"
args2(17).Value = 3
args2(18).Name = "Quiet"
args2(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args2())
rem ----------------------------------------------------------------------
dim args3(18) as new com.sun.star.beans.PropertyValue
args3(0).Name = "SearchItem.StyleFamily"
args3(0).Value = 2
args3(1).Name = "SearchItem.CellType"
args3(1).Value = 0
args3(2).Name = "SearchItem.RowDirection"
args3(2).Value = true
args3(3).Name = "SearchItem.AllTables"
args3(3).Value = false
args3(4).Name = "SearchItem.Backward"
args3(4).Value = false
args3(5).Name = "SearchItem.Pattern"
args3(5).Value = false
args3(6).Name = "SearchItem.Content"
args3(6).Value = false
args3(7).Name = "SearchItem.AsianOptions"
args3(7).Value = false
args3(8).Name = "SearchItem.AlgorithmType"
args3(8).Value = 1
args3(9).Name = "SearchItem.SearchFlags"
args3(9).Value = 65536
args3(10).Name = "SearchItem.SearchString"
args3(10).Value = "\>"+CHR$(34)
args3(11).Name = "SearchItem.ReplaceString"
args3(11).Value = "”"
args3(12).Name = "SearchItem.Locale"
args3(12).Value = 255
args3(13).Name = "SearchItem.ChangedChars"
args3(13).Value = 2
args3(14).Name = "SearchItem.DeletedChars"
args3(14).Value = 2
args3(15).Name = "SearchItem.InsertedChars"
args3(15).Value = 2
args3(16).Name = "SearchItem.TransliterateFlags"
args3(16).Value = 1280
args3(17).Name = "SearchItem.Command"
args3(17).Value = 3
args3(18).Name = "Quiet"
args3(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args3())
rem ----------------------------------------------------------------------
dim args4(18) as new com.sun.star.beans.PropertyValue
args4(0).Name = "SearchItem.StyleFamily"
args4(0).Value = 2
args4(1).Name = "SearchItem.CellType"
args4(1).Value = 0
args4(2).Name = "SearchItem.RowDirection"
args4(2).Value = true
args4(3).Name = "SearchItem.AllTables"
args4(3).Value = false
args4(4).Name = "SearchItem.Backward"
args4(4).Value = false
args4(5).Name = "SearchItem.Pattern"
args4(5).Value = false
args4(6).Name = "SearchItem.Content"
args4(6).Value = false
args4(7).Name = "SearchItem.AsianOptions"
args4(7).Value = false
args4(8).Name = "SearchItem.AlgorithmType"
args4(8).Value = 1
args4(9).Name = "SearchItem.SearchFlags"
args4(9).Value = 65536
args4(10).Name = "SearchItem.SearchString"
args4(10).Value = "([,.;!?\]\)])"+CHR$(34)
args4(11).Name = "SearchItem.ReplaceString"
args4(11).Value = "$1”"
args4(12).Name = "SearchItem.Locale"
args4(12).Value = 255
args4(13).Name = "SearchItem.ChangedChars"
args4(13).Value = 2
args4(14).Name = "SearchItem.DeletedChars"
args4(14).Value = 2
args4(15).Name = "SearchItem.InsertedChars"
args4(15).Value = 2
args4(16).Name = "SearchItem.TransliterateFlags"
args4(16).Value = 1280
args4(17).Name = "SearchItem.Command"
args4(17).Value = 3
args4(18).Name = "Quiet"
args4(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args4())
rem ----------------------------------------------------------------------
dim args5(18) as new com.sun.star.beans.PropertyValue
args5(0).Name = "SearchItem.StyleFamily"
args5(0).Value = 2
args5(1).Name = "SearchItem.CellType"
args5(1).Value = 0
args5(2).Name = "SearchItem.RowDirection"
args5(2).Value = true
args5(3).Name = "SearchItem.AllTables"
args5(3).Value = false
args5(4).Name = "SearchItem.Backward"
args5(4).Value = false
args5(5).Name = "SearchItem.Pattern"
args5(5).Value = false
args5(6).Name = "SearchItem.Content"
args5(6).Value = false
args5(7).Name = "SearchItem.AsianOptions"
args5(7).Value = false
args5(8).Name = "SearchItem.AlgorithmType"
args5(8).Value = 1
args5(9).Name = "SearchItem.SearchFlags"
args5(9).Value = 65536
args5(10).Name = "SearchItem.SearchString"
args5(10).Value = CHR$(39)+"\<"
args5(11).Name = "SearchItem.ReplaceString"
args5(11).Value = "‘"
args5(12).Name = "SearchItem.Locale"
args5(12).Value = 255
args5(13).Name = "SearchItem.ChangedChars"
args5(13).Value = 2
args5(14).Name = "SearchItem.DeletedChars"
args5(14).Value = 2
args5(15).Name = "SearchItem.InsertedChars"
args5(15).Value = 2
args5(16).Name = "SearchItem.TransliterateFlags"
args5(16).Value = 1280
args5(17).Name = "SearchItem.Command"
args5(17).Value = 3
args5(18).Name = "Quiet"
args5(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args5())
rem ----------------------------------------------------------------------
dim args6(18) as new com.sun.star.beans.PropertyValue
args6(0).Name = "SearchItem.StyleFamily"
args6(0).Value = 2
args6(1).Name = "SearchItem.CellType"
args6(1).Value = 0
args6(2).Name = "SearchItem.RowDirection"
args6(2).Value = true
args6(3).Name = "SearchItem.AllTables"
args6(3).Value = false
args6(4).Name = "SearchItem.Backward"
args6(4).Value = false
args6(5).Name = "SearchItem.Pattern"
args6(5).Value = false
args6(6).Name = "SearchItem.Content"
args6(6).Value = false
args6(7).Name = "SearchItem.AsianOptions"
args6(7).Value = false
args6(8).Name = "SearchItem.AlgorithmType"
args6(8).Value = 1
args6(9).Name = "SearchItem.SearchFlags"
args6(9).Value = 65536
args6(10).Name = "SearchItem.SearchString"
args6(10).Value = CHR$(39)+"([\[\(])"
args6(11).Name = "SearchItem.ReplaceString"
args6(11).Value = "‘$1"
args6(12).Name = "SearchItem.Locale"
args6(12).Value = 255
args6(13).Name = "SearchItem.ChangedChars"
args6(13).Value = 2
args6(14).Name = "SearchItem.DeletedChars"
args6(14).Value = 2
args6(15).Name = "SearchItem.InsertedChars"
args6(15).Value = 2
args6(16).Name = "SearchItem.TransliterateFlags"
args6(16).Value = 1280
args6(17).Name = "SearchItem.Command"
args6(17).Value = 3
args6(18).Name = "Quiet"
args6(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args6())
rem ----------------------------------------------------------------------
dim args7(18) as new com.sun.star.beans.PropertyValue
args7(0).Name = "SearchItem.StyleFamily"
args7(0).Value = 2
args7(1).Name = "SearchItem.CellType"
args7(1).Value = 0
args7(2).Name = "SearchItem.RowDirection"
args7(2).Value = true
args7(3).Name = "SearchItem.AllTables"
args7(3).Value = false
args7(4).Name = "SearchItem.Backward"
args7(4).Value = false
args7(5).Name = "SearchItem.Pattern"
args7(5).Value = false
args7(6).Name = "SearchItem.Content"
args7(6).Value = false
args7(7).Name = "SearchItem.AsianOptions"
args7(7).Value = false
args7(8).Name = "SearchItem.AlgorithmType"
args7(8).Value = 1
args7(9).Name = "SearchItem.SearchFlags"
args7(9).Value = 65536
args7(10).Name = "SearchItem.SearchString"
args7(10).Value = "'"
args7(11).Name = "SearchItem.ReplaceString"
args7(11).Value = "’"
args7(12).Name = "SearchItem.Locale"
args7(12).Value = 255
args7(13).Name = "SearchItem.ChangedChars"
args7(13).Value = 2
args7(14).Name = "SearchItem.DeletedChars"
args7(14).Value = 2
args7(15).Name = "SearchItem.InsertedChars"
args7(15).Value = 2
args7(16).Name = "SearchItem.TransliterateFlags"
args7(16).Value = 1280
args7(17).Name = "SearchItem.Command"
args7(17).Value = 3
args7(18).Name = "Quiet"
args7(18).Value = true
dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args7())
rem ----------------------------------------------------------------------
rem close the undo action
undo.leaveUndoContext
end sub
@Tintazul
Copy link

Tintazul commented May 8, 2015

Hi @LMPerkins – I had to adapt the code for myself, as it was eating up punctuation; e.g. it would find "really?" and replace with “really” (note missing question mark).
Also, I wanted this to count as a single undo action; since the macro consisted of four find/replace actions, it was taking four undo actions to undo this macro. Took me over an hour to find out how to do it (newb LibreOffice programmer!), but I nailed it.
So, here’s my code – I don’t know if it solves your problem, but you might as well give it a try: https://gist.github.com/Tintazul/deb5e137cabf86ddf4c2
Cheers!

@dajare
Copy link
Author

dajare commented Feb 29, 2016

@Tintazul - thanks for the refinements! It looks to me like mixing word-boundary searches with other kinds was messing with the back-references. I'm not sure if this is related to long-reported bug as that relates to impress, but it seems to affect this "macro" for Writer, too.

I've elaborated my macro, incorporating your "single undo" wrapper. (Nice!) This will now respect/retain punctuation -- at least in my tests -- whether preceding or following the quotation marks (single or double).

@John-Cordone
Copy link

I was using this macro, and I find that the word Dr.'s is turning into Dr.‘s, with the wrong kind of single quote (with an opening single quote instead of a closing single quote).

@iguanaonmystack
Copy link

Thanks for the code! I had to update it a little bit to get it to work on my copy of LibreOffice, version 5.2.0.4. Not sure exactly why the extra SearchItem.AlgorithmType2 with value 2 needed to be added to this particular Find and Replace, but without it in my particular document I ended up with literal a little "$1”" in my text. Recording a new macro added this in. Annoyingly I can't reproduce the problem in an empty document...

https://gist.github.com/flexo/ae3758b744cf5aef852e851018a184dc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment