2

How to change straight quotes to smart curly quotes without omitting word wrap.

The example contains single straight quote and double straight quotes.

INPUT

1 I have bowed before only one sanyasi in my life, and that is 'Sri
2 Chandrasekharendra Saraswathi', known to the world as the "Parmacharya."
3 
4 Therefore, I was the ''modern 
5 Indian'',believer in science, and
6 with little concern for spiritual
7 diversions.

OUTPUT

1 I have bowed before only one sanyasi in my life, and that is ‘Sri
2 Chandrasekharendra Saraswathi’, known to the world as the “Parmacharya.”
3 
4 Therefore, I was the “modern 
5 Indian”,believer in science, and with
6 little concern for spiritual 
7 diversions.
  • it would be good if you have shown the expected result – RomanPerekhrest May 7 '17 at 7:40
  • @RomanPerekhrest I have added expected result. – Ramaprakasha May 7 '17 at 7:52
  • Word processors seem to follow simple rules: straight-quote followed by letter → left quote, so did you try regular expressions (eg sed)? – Piotr Findeisen May 7 '17 at 11:34
  • @likkachu some scripts wouldn't turn straight quotes to curly when newline occured in between. – Ramaprakasha May 7 '17 at 11:38
  • 1
    @PiotrFindeisen No I didnt try sed. But it can be done. I also found a simple solution. It employs pandoc pandoc --wrap=preserve -f markdown -t markdown -S filename option -S changes staright quotes to curly ones. – Ramaprakasha May 7 '17 at 11:42
1

To make the newlines a non-issue, we could do a replacement so that a whole paragraph or the whole file is processed as one string. With Perl, we could use -0777 to read the full file at one go, or -00 to use paragraph mode (i.e. sections separated by empty lines, that would of course require that the line numbers are not part of the input file):

$ perl -0777 -pe 's/\x27\x27/"/g; s/\x27(.*?)\x27/‘$1’/gs; s/"(.*?)"/“$1”/gs; ' input
I have bowed before only one sanyasi in my life, and that is ‘Sri
Chandrasekharendra Saraswathi’, known to the world as the “Parmacharya.”

Therefore, I was the “modern 
Indian”, believer in science, and
with little concern for spiritual
diversions.

I used the hex representation \x27 of the single-quote to make the quoting easier. .*? means any string, but the shortest possible match. The first rule changes doubled single-quotes '' to double-quotes.

Or, similarly with GNU sed, -z takes the input as NUL-separated strings, so a usual text file will be read in one go:

$ sed -zEe 's/\x27\x27/"/g; s/\x27([^\x27]*)\x27/‘\1’/g; s/"([^"]*)"/“\1”/g; ' input
I have bowed before only one sanyasi in my life, and that is ‘Sri
Chandrasekharendra Saraswathi’, known to the world as the “Parmacharya.”

Therefore, I was the “modern 
Indian”, believer in science, and
with little concern for spiritual
diversions.
  • This only works when all quotes are balanced. One should check if this is the case before using these scripts. – helcim Mar 10 '18 at 15:38
  • @helcim, yeah, well, there's really nothing we can do about unbalanced/missing quotes, there's no way for a program to decide what the correct quoting should be, so it's a "garbage in-garbage out" situation. The bigger issue which I've totally neglected here is that the single-quote/apostrophe can well appear in contractions, and that's even a reasonable use-case. But detecting them programmatically would also be somewhat difficult. – ilkkachu Mar 10 '18 at 16:08
  • Indeed. That's why perhaps it would be more practical not to replace quotations using captures but only use preceding and following character for tests whether to use left or right quote. – helcim Mar 10 '18 at 16:44
  • @helcim, Point. I don't have time to test and write that now, but it does sound like something you could write up as an answer yourself. :) – ilkkachu Mar 10 '18 at 18:39
  • I will have to do it, that's why I came to this place ;) – helcim Mar 11 '18 at 11:09
0

A naive implementation which relies entirely on Perl's word character class. Changes only ["] to [„] or [”].

#!/usr/bin/perl -w -0777
local $/ = undef;

open INFILE, $ARGV[0] or die "I can't read the file. $!";
$string =  <INFILE>;
close INFILE;

$string =~ s/(\w)\"/$1”/smg;
$string =~ s/\"(\w)/„$1/smg;

open OUTFILE, ">",   $ARGV[1] or die "I can't write to the file. $!";
print OUTFILE ($string);

close 

Save as script.pl and run perl script.pl INFILE OUTFILE. After that you only have to search for any left over incorrectly placed straight quotes like |aaaaaa"bbbbb| or |aaaa " bbbb| which hopefully are not very frequent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.