Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
@LMPerkins

This comment has been minimized.

Copy link

@LMPerkins LMPerkins commented Apr 30, 2015

Thank you for providing this (It looks like a LOT of work)!

I followed your instructions at http://ask.libreoffice.org/en/question/2612/how-do-i-convert-straight-quotes-to-typographic-quotes/ for setting up a macro in LibreOffice, but when I run the macro, hoping that foot marks will be replaced with apostrophes, instead foot marks are replaced with this: ’

What might I have done wrong -- or is this macro not meant to correct foot marks to apostrophes?

Thank you again for any help you might be able to provide.

@Tintazul

This comment has been minimized.

Copy link

@Tintazul 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

This comment has been minimized.

Copy link
Owner Author

@dajare 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

This comment has been minimized.

Copy link

@John-Cordone John-Cordone commented Jul 4, 2016

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

This comment has been minimized.

Copy link

@iguanaonmystack iguanaonmystack commented Sep 3, 2016

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