[Solved] Smart quotes

Writing a book, Automating Document Production - Discuss your special needs here
Post Reply
Runesmith
Posts: 6
Joined: Mon Apr 04, 2011 10:30 am

[Solved] Smart quotes

Post by Runesmith »

I occasionaly have to prepare for publication documents that have been created in systems that don't put smart quotes. I can't find any way to persuade the Search and Replace to replace the original "dumb quotes" with OO smart ones.

Is there a trick I haven't found, or do I have to go through and replace every single quotation mark manually?

That also goes for smart hyphens.

Hoping someone can save me a long boring job,
Runesmith
Last edited by Runesmith on Thu Apr 07, 2011 1:29 pm, edited 2 times in total.
Open Office 3.2 on Windows XP
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Smart quotes

Post by Villeroy »

menu:Edit>Find&Replace...
[More Options]
[X] Regular expressions
Search: "\< [straight quote followed by word start]
Replace: “
[Replace All]
Search: \>" [word ending followed by straight quote]
Replace: ”
[Replace All]
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Runesmith
Posts: 6
Joined: Mon Apr 04, 2011 10:30 am

Re: Smart quotes

Post by Runesmith »

I get "Search key not found."
Open Office 3.2 on Windows XP
User avatar
RoryOF
Moderator
Posts: 34586
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Smart quotes

Post by RoryOF »

Try doing it again, making sure Regular expressions is checked (on the F&R drop down section). You may need to Copy and Paste the desired type of quotes into the Find and Replace boxes, rather than relying on keyboard to type these.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
Runesmith
Posts: 6
Joined: Mon Apr 04, 2011 10:30 am

Re: Smart quotes

Post by Runesmith »

That worked beautifully for the quotes before the sentence, but for the quotes afterwards, it replaced the first 8 then started saying "search key not found." I've tried copying and pasting the target as well as the replacement, but it won't recognise it.
Open Office 3.2 on Windows XP
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Smart quotes

Post by Villeroy »

OK, there are punctuation marks rather than word endings at the end of some quotes. I did not think of that. The second search expression should be:
(\>|[.;!?])"
which means: word ending OR any of the characters in the brackets followed by a straight quote.
 Edit: Since we successfully replaced the leading straight quotes you may decide to replace all remaining straight quotes. 
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Runesmith
Posts: 6
Joined: Mon Apr 04, 2011 10:30 am

Re: Smart quotes

Post by Runesmith »

Oops! That replaced the quotes alright, but at the cost of deleting the punctuation marks at the ends of the sentences.

I'll use that if I have to, replacing the punctuation is less of a chore than changing the quotes, but maybe you can tweak it a little more?
Open Office 3.2 on Windows XP
Runesmith
Posts: 6
Joined: Mon Apr 04, 2011 10:30 am

Re: Smart quotes

Post by Runesmith »

To be more precise, having checked more carefully: where the sentence ended in a comma, it didn't replace. Where it ended in a dash, it replaced the quotes and nothing else. With all other punctuation, it replaced the quotes and deleted the punctuation mark.
Open Office 3.2 on Windows XP
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Smart quotes

Post by Villeroy »

OOops. I did not test the actual replacement in all situations. 3rd try:
Search: (\>|[.;!?])"
Replace: $1”
the $1 stands for "whatever has been matched by the first pair of (round braces)".
To match commas or other chars, put them in the [square braces]
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Runesmith
Posts: 6
Joined: Mon Apr 04, 2011 10:30 am

Re: Smart quotes *Solved*

Post by Runesmith »

Done it! I must save that tip for next time, I'll never remember it.

Thank you for your efforts.
Open Office 3.2 on Windows XP
ttbloodlusttt
Posts: 1
Joined: Fri Jun 28, 2013 1:18 am

Re: [Solved] Smart quotes

Post by ttbloodlusttt »

My God! Thank you so much for this solution! Half of my current document had these stupid straight quotes and all I managed on my own was to replace them with start sentence quotes.
You, my friend, just saved me almost two thousand single corrections! Now I can get back to the meat of the content I'm writing instead of worrying over the ugly single quotes!

My hero!

-Angie
OpenOffice 3.4.1
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: [Solved] Smart quotes

Post by John_Ha »

Format > Autocorrect > Apply changes straight quotes to smart quotes if you have ticked the boxes in Format > Autocorrect > Autocorrect options > Localised options.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
User avatar
acknak
Moderator
Posts: 22756
Joined: Mon Oct 08, 2007 1:25 am
Location: USA:NJ:E3

Re: [Solved] Smart quotes

Post by acknak »

John_Ha wrote:Format > Autocorrect > Apply changes straight quotes to smart quotes ...
It's also tied into the document styles and may make changes that you don't want and can't undo.

I recommend using the Find & Replace instead, although I use a different pattern: (\S)"
AOO4/LO5 • Linux • Fedora 23
Mo.Huber
Posts: 1
Joined: Tue Nov 24, 2015 1:27 pm

Re: [Solved] Smart quotes

Post by Mo.Huber »

There is one thing left: curly apostrophes (and possible quotation marks after footnotes (which shouldn't occur and therefore is a good way to find them, so I left it this way)
Therefore I repost the complete instruction with the addendum

Smart quotes and apostrophes

1) replacing straight quotation marks with curly quotation marks
menu:Edit>Find&Replace...
[More Options]
[X] Regular expressions
Search: "\< [straight quote followed by word start]
Replace: “
[Replace All]
Search: (\>|[.;!?])" [word ending followed by straight quote]
Replace: $1”
[Replace All]

2) replacing straight single quotation mark with curly single quotation marks
menu:Edit>Find&Replace...
[More Options]
[X] Regular expressions
Search: '\< [straight quote followed by word start]
Replace: ‘
[Replace All]
Search: (\>|[.;!?])' [word ending followed by straight quote]
Replace: $1’
[Replace All]

3) replacing remaining apostrophes with curly apostrophes (aka closing single quotation marks)
menu:Edit>Find&Replace...
[More Options]
[X] Regular expressions
Search: ' [remaining straight apostrophes]
Replace: ’
[Replace All]
Open Office 4.1.2. on Windows 10
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: [Solved] Smart quotes

Post by John_Ha »

Those commands can be wrapped in a macro so you need only to click the macro icon to have it done. I will do so later, when I have more time.

I currently use bluegecko's excellent quotes macro, but unfortunately the regular expressions engine has since been changed, and it doesn't always now work for closing quotes. I append it as an example.

Code: Select all

sub Quotes

'   By bluegecko, 13 January 2010. Public domain.

'jh Regular expressions changed in OOo 3.4 - search at start / end of word changed

'   This is a revised version of the smart quotes routine posted in June 2009 on this
'   same page (http://www.oooforum.org/forum/viewtopic.phtml?p=328916)
'   The macro switches apostrophes and quotation marks (single and double) from
'   their straight (or "dumb") variants to what are variously called "smart", "curly"
'   or "typographer's" quotes, and vice-versa.

'   Although OpenOffice has an apparently similar Autocorrect function, it's buggy
'   in all but the simplest of cases. Autocorrect, if you want to apply it to an entire
'   dcument, is unfortunately also restricted to text formatted in the default paragraph
'   style, so useless if your document is already styled up.

'   This macro provides a solution. It should work correctly in most instances, and should
'   also preserve any character formatting or styling. I've tested it in various contexts,
'   including contemporary quotation formatting (no space on one side of the quotation mark);
'   in older style formatting with spaces on either side of the quotation mark; and, also an
'   old style (Victorian and earlier), with double quotes without closures that were used to
'   mark long quotes split into several paragraphs, where the closing double quote only appears
'   at the end of the last paragraph. The macro should also correctly deal with apostrophes, and,
'   hopefully, any combination or multiple of single quotes and apostrophes.

'   The logic makes some assumptions:
'   1. single quotation marks within words are apostrophes
'   2. if there's an odd number of quotation marks (excluding apostrophes) in a paragraph, the
'   first one is considered to have no closure (as was the norm in the 19th century: quotations
'   spanning several paragraphs had an opening quotation mark at the start of each paragraph,
'   but a closing mark only at the end of the last paragraph)
'   3. stand-alone acute and grave accents are assumed to be single quotation marks, and will
'   be converted as such.

'   The routine uses a subroutine to perform the search and replacements. It uses far more
'   steps than would have been necessary were OpenOffice's implementation of Regular Expressions
'   not so ****** awful (and were OpenOffice not in the habit of trashing character formatting
'   when performing Regular Expression search/replaces on parts of a string).

'   LIMITATIONS - GLOTTAL STOPS
'   The macro does not deal with single quotes used to indicate a glottal stops in some transliterations,
'   for instance Arabic (eg. ’Abdullah). In such transliterations, aleph glottal stops are often
'   written with a single right quotation mark, whilst the reverse form, the ‘ayn, is often written with
'   a left quotation mark.
'   I can't think of a method to reliably detect these without messing up the single quote detection, as
'   even if I used a word list, the opening quote might really be a quote, not a glottal stop.
'   If you do use glottal stops in your documents, I'd suggest you use the correct Unicode characters.
'   In properly encoded multilingual fonts such as Gentium, Linux Libertine and DejaVu (all of them
'   free), the aleph (left-pointing) is at code point 02BE, whilst ‘ayn (right-pointing) is at 02BF.
'   In OpenOffice's "Insert | Special character" dialog, they're under Spacing Modifier Letters.
'
'  Alternative method - do two passes with the following
'  The first pass handles all the close quotes; the second gets the remaining (open) quotes.
'  Search for: ([^ ])"       '   " = straight quotes
'  Replace with: $1”         '   ” = curly close quotes 
'  Options/Regular expression: ON
'  Click "Replace All"
'
'  Search for: "             '   " = straight quotes
'  Replace with: “           '   “ = curly open quotes
'  Click "Replace All"
'
'jh Remove the question and set the response = 6 so as to change straight to curly

'jh   a$ = "Use typographer’s quotes?" + Chr(10) + Chr(10) + _
'jh      "— Yes changes all quotation marks and apostrophes to curly ones;" + Chr(10) + _
'jh      "— No changes them all to straight ones;" + Chr(10) + _
'jh      "— Cancel leaves them as they are."
'jh   response = MsgBox(a$,512 + 32 + 3,"Typography - quotes")

'jh   If (response = 2) Then goto noChange                  ' 2 = cancel, so would do nothing

'jh set response to be 6 to change straight quotes to curly quotes

   response = 6        ' set by jh
   
   REM save cursor position
   oViewCursor = ThisComponent.getCurrentController().getViewCursor()
   oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)

   REM disable screen update
   ThisComponent.lockControllers
   ThisComponent.CurrentController.Frame.ContainerWindow.Enable = False

   REM correct quotes made with acute or grave accents

   FindReplaceQuotes ("´","'","all")                     ' change acute to single quote
   FindReplaceQuotes ("`","'","all")                     ' change grave to single quote

   If (response = 6) Then                              ' APPLY SMART QUOTATION MARKS
   
   REM DOUBLE QUOTES
      DQ = Chr(34)                                 ' Chr(34) is the straight double quote
      FindReplaceQuotes (""+DQ+"[^"+DQ+"]+"+DQ+"","","all")   ' find "....."
      FindReplaceQuotes (""+DQ+"[^"+DQ+"]+","","selection")   ' find "..... within selections
      
'jh  I think that in the above two lines, the first line searches all.  
'jh  The second line searches only the selection 
 
      FindReplaceQuotes (""+DQ+"","“","selection")         ' change  to “
      FindReplaceQuotes ("“[^"+DQ+"“]+"+DQ+"","","all")      ' find “...."
      FindReplaceQuotes (""+DQ+"","”","selection")         ' change " to ”
      FindReplaceQuotes (""+DQ+"","“","all")               ' change remaining quotes to “

   REM SINGLE QUOTES
'jh  I think the following are correct.  Here in case they are needed - but not used below
      SQ   = Chr(39)    ' single quote - straight
      LQc  = Chr(8216)  ' single quote left - curly  
      RQc  = Chr(8217)  ' single quote right - curly
      LDQc = Chr(8220)  ' double quote left - curly
      RDQc = Chr(8221)  ' double quote right - curly
      
'jh   macro works differently if changes are enabled
        
      FindReplaceQuotes ("'","’","all")          ' change all single quotes to right

'jhq FindReplaceQuotes ("’\>","‘","all")   ' change rightquotes before words to leftquotes
'jhq the previous line should only replace "r-quotes before words". It replaces "r-quotes before and after words"
'jhq because??  \< no longer works for non-alpha chars (in macros?) after OOo 3.4.1. So ...

      FindReplaceQuotes ("’","‘","all")          ' change all rightquotes to leftquotes

'jhq Now change back only the "l-quotes after words"
'jhq ...look for (chars)(l-quote)(punctuation or sp). note \) rqd for )

      FindReplaceRegExp ("([a-z0-9])(‘)(\.|\?| |!|,|;|:|\))","$1’$3","all") 'l-quote at end of word changed to r-quote

'jhq ... and we have done it

'jhq Note that FindReplaceQuotes ("z\>","‘","all") works OK for z\> where z is a character.

      FindReplaceQuotes ("([:alnum:])‘([:alnum:])","","all")   ' find leftquotes within words
      FindReplaceQuotes ("‘","’","selection")                  ' change to rightquotes (apostrophes)
' deal with single quotes that have spaces around them
      FindReplaceQuotes (" ’","¨","all")                   ' temporarily change space+rightquote to dieresis (¨)
      FindReplaceQuotes ("¨[^¨]+¨","","all")               ' select all pairs
      FindReplaceQuotes ("¨[^¨]+","","selection")          ' trim selections to exclude closing space+rightquote
      FindReplaceQuotes ("¨"," ‘","selection")             ' replace with leftquote
      FindReplaceQuotes ("¨"," ’","all")                   ' change markers back to rightquotes
' deal with single quotes at start of line, paragraph, or following tabs or starting punctuation
      FindReplaceQuotes ("(\t|[“\[\(\{])’","","all")       ' select rightquotes following opening punctuation or tabs
      FindReplaceQuotes ("’","‘","selection")              ' change to leftquotes
      FindReplaceQuotes ("^’","‘","all")                   ' change rightquotes at new line to leftquotes
      FindReplaceQuotes ("“ ’","","all")                   ' change rightquotes after quotequote+space (2 steps)
      FindReplaceQuotes ("’","‘","selection")

'jh  simplest to leave this - it will never be executed as response was set to 6 above

   Else                                          ' APPLY STRAIGHT QUOTATION MARKS
      FindReplaceQuotes ("‘","'","all")
      FindReplaceQuotes ("’","'","all")
      FindReplaceQuotes ("“",Chr(34),"all")
      FindReplaceQuotes ("”",Chr(34),"all")
   EndIf

   REM restore cursor position
   oViewCursor = ThisComponent.getCurrentController().getViewCursor()
   oViewCursor.gotoRange(oTextCursor,false)
   
   REM reenable screen update
   ThisComponent.CurrentController.Frame.ContainerWindow.Enable = True
   ThisComponent.unlockControllers

   noChange:

'jh  Remove search backwards and regular expressions by running a dummy RESET search with them unticked
   FindReplaceReset ("abc","abc","all")                             ' change a abc to abc 

End Sub

Sub FindReplaceQuotes (sFind,sReplace,sScope)
   REM sFind: regular expression  
   REM sReplace: if empty, function selects all occurrences of sFind
   REM sScope: set to "all" for entire document, or "selection" to restrict the scope.
   REM function searches backwards (necessary to correctly catch quotes)

   dim document   as object
   dim dispatcher as object
   document   = ThisComponent.CurrentController.Frame
   dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

   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 = true                            ' backward is required for quotes
   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                                ' search using Regular Expressions
   args1(9).Name = "SearchItem.SearchFlags"
   If sScope = "all" Then
      args1(9).Value = 65536   ' parse entire doc
   Else
      args1(9).Value = 71680   ' parse selection only
   End If
   args1(10).Name = "SearchItem.SearchString"
   args1(10).Value = sFind
   args1(11).Name = "SearchItem.ReplaceString"
   args1(11).Value = sReplace
   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"
   If sReplace = "" Then
      args1(17).Value = 1      ' find all
   Else
      args1(17).Value = 3      ' replace all
   End If
   args1(18).Name = "Quiet"
   args1(18).Value = true
   dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1())

End Sub

Sub FindReplaceReset (sFind,sReplace,sScope)
'jh This sub FindReplaceReset is used merely to untick the Regular Expression and Backwards search boxes.
   REM sFind:     is not a regular expression
   REM sReplace:  if empty, function selects all occurrences of sFind
   REM sScope:    set to "all" for entire document, or "selection" to restrict the scope.
   REM function   searches forwards to untick the box

   dim document   as object
   dim dispatcher as object
   document   = ThisComponent.CurrentController.Frame
   dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

   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                      ' set to false to search forwards so as to untick the box
   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 = 0                          ' set to 0 to untick regular expressions
   args1(9).Name = "SearchItem.SearchFlags"
   If sScope = "all" Then
      args1(9).Value = 65536   ' parse entire doc
   Else
      args1(9).Value = 71680   ' parse selection only
   End If
   args1(10).Name = "SearchItem.SearchString"
   args1(10).Value = sFind
   args1(11).Name = "SearchItem.ReplaceString"
   args1(11).Value = sReplace
   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"
   If sReplace = "" Then
      args1(17).Value = 1      ' find all
   Else
      args1(17).Value = 3      ' replace all
   End If
   args1(18).Name = "Quiet"
   args1(18).Value = true
   dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1())

End Sub
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
timearl
Posts: 3
Joined: Thu Jan 19, 2012 1:15 pm

Re: [Solved] Smart quotes

Post by timearl »

Search: "\< [straight quote followed by word start]
Search: (\>|[.;!?])" [word ending followed by straight quote]
Is there a reference with all these codes (\< = word start, \> = word end) anywhere, please?

Tim
OpenOffice 3.3 on Windows 2000 (installed 18/1/2012).
User avatar
robleyd
Moderator
Posts: 5055
Joined: Mon Aug 19, 2013 3:47 am
Location: Murbko, Australia

Re: [Solved] Smart quotes

Post by robleyd »

Search the HELP - F1 - for regular expressions;list of for more information and additional links.
Cheers
David
OS - Slackware 15 64 bit
Apache OpenOffice 4.1.15
LibreOffice 24.2.1.2; SlackBuild for 24.2.1 by Eric Hameleers
matty9NZ
Posts: 1
Joined: Sat Feb 01, 2020 4:47 am

Re: [Solved] Smart quotes

Post by matty9NZ »

This was invaluable advice. Thank you so much! I was dreading manually changing every bit of dialogue in my manuscript, written in an app that doesn't support smart quotes.

However, I still got "Search key not found" with (\>|[.;!?])"
I tried variations, but eventually realised that since I had already changed all the opening quotes, the remaining ones would be closing quotes. Replacing all " with ” did the trick.
OpenOffice 4.1.0 on Win7
Post Reply