Curly Quotation Marks

I’m undecided about whether to use the Twine editor for adding new bits to my branching story, or whether to export three dozen passages to Scrivener, work on the story there, and then import everything back into Twine. That would be a lot of extra work!

Scrivener is a much better word processor, of course. One wouldn’t expect Twine to rival it in that department. But here’s the problem:

Curly quotes.

I had written this story a few years ago in Scrivener. I recently imported it into Twine as a linear series of passages and then started adding branching bits. What I have now discovered, and it’s deeply disturbing, is that Twine’s text editor types straight quotes and apostrophes, while Scrivener does automatic conversion into curly quotes and apostrophes. Firefox (and probably all other browsers, I haven’t checked) preserves this distinction when displaying the text.

As a result, I now have a Twine story that is internally inconsistent. Some passages use curly quotes, while others use straight quotes. For me, as a professional writer and editor, this is unacceptable. For my own published work, I demand consistency of myself.

I’m sure I can find a way to type curly quotes into the Twine editor using special keystrokes on my PC. It’s extra work, but it’s manageable. Conversely, if I do the writing in Scrivener, then any code (such as in linkreplace) that demands straight quotes is going to require extra handling. If I type it in Scrivener, I’m pretty sure the code will malfunction.

I’m just thinking out loud here – this isn’t exactly a technical question – but I’m curious whether others have encountered the curly quote issue in Twine, and how they may have dealt with it.

I didn’t delete my post fast enough. :roll_eyes: If you happened to read it, don’t do what I said. If you’re going from curly to straight quotes, my suggestion would work. Going from straight to curly will break twine (unless you do something fancy like use a regular expression to replace the quotes).

The Twine 2.x application’s “Passage Editor” is a Text Editor, not a Word Processor, and this is an important distinction because one is used to write the instructions of a Programming Language and the other isn’t.

Text Editors default to using standard Single (apostrophes) and Double quotes because Programming languages generally require them as the delimiter of data-types like String and Character, and in this usage Typographical (curly) quotes are considered invalid.

Now it could be argued that not all Passage content is Programming language based, and that would be true, and that if the Passage Editor was more content/context aware it could distinguish when a quote is being used as part of a piece of code and when it is just prose. However distinguishing the usage difference is way harder than you may expect.

A simple use case, where distinguishing is easy…

/* Harlowe based code... */
(set: $variable to "a String value")
Jane said “Hello John, how are you to day?”

/* SugarCube based code... */
<<set $variable to "a different String value">>
Jane said “Hello John, how are you to day?”

The first line of each example is a Macro call which is assigning what is obviously a String literal to a variable, so in this context it is obvious that standard quotes need to be used. It is equally obvious that the second line is prose, so the choice of whether or not to use Typographical quotes could be left up to the end-user’s personal preference.

A slightly more complex Macro call example…

(set: $variable to 'Jane said “Hello John, how are you to day?”')
<<set $variable to 'Jane said “Hello John, how are you to day?”'>>

Now single quotes are being used to delimit the String literal, and double quotes are being used to delimit what Jane is saying. In this case the prose content is imbedded within programming content, so the feature handling the distinction needs to know the end-user may want to use Typographical quotes within String literals. So far so good, as the quotes being used to delimit the String literal (single) are different to those being used to delimit what is being said.

A even more complex example…

(set: $variable to 'Jane said “I don’t like the colour Purple!”')
<<set $variable to 'Jane said “I don’t like the colour Purple!”'>>

Now the feature needs to know that the quote being used to delimit the String literal can also be used within the prose, and that the one within the prose may need to be Typographic (depending on end-user’s preference)

I could keep creating more and more complex examples but I believe I’ve made the point that automatically disguising between when standard quotes must be used and when Typographical quotes may be used instead is not going to be a simple task.

I’m aware of all that. I’m just musing about the best way to deal with it while working. Maybe the best way is not to import a story into Twine until the story itself is done. Just keep a list of what needs to link to what, then import into Twine, then do the links.

If you have the source code written out in an editor that mistakenly put curly quotes in places where Twine actually needs straight quotes, you can use find/replace to “fix” them… but unless you do them one at a time it will fix all of them, even the ones in printed dialogue which perhaps you wanted to keep.

Personally, I usually just avoid using typographical (curly) quotes.

If you want to replace all of the typographical quotes with non-typographical quotes, then you should be able to do that from the “Find and replace” button in your story’s bottom toolbar, though I’d strongly recommend backing up your story before doing that, just in case, since it could break in a few cases. For example, <<set $example = "He said, “Help me.”">> would become broken code due to the double-quotes within double-quotes. To fix that you’d need to change it to either of these:

<<set $example = "He said, \"Help me.\"">>
  - or -
<<set $example = 'He said, "Help me."'>>

If you want to replace non-typographical quotes with typographical quotes, then it’s much more difficult. If you don’t want to go through all of your passages to resolve that manually, then you’d need to create a function for Config.passages.onProcess to use in order to alternate converting any double-quotes to starting and ending typographical quotes and single quotes to typographical apostrophes, as long as they’re not within angle brackets. (Though, this is further complicated if you have cases of multiple paragraphs of dialog by the same speaker, since there will only be ending quotes on the last paragraph.)

I might write some code to do that for you, since it sounds like fun, but I’m still recovering from dental surgery and in a lot of pain, so I don’t know if I’m up for it right now.

The “Character Map” application (charmap.exe; usually found in the “Accessories” section in the Windows “Start” menu) is great for figuring that kind of stuff out. Here’s what you need:

ALT+0146 = ’
ALT+0147 = “
ALT+0148 = ”

To type those, make sure that Num Lock is on, and then hold down the ALT key while hitting those numbers on the keyboard’s numpad. Releasing the ALT key at the end will then show that character. To help remember those numbers, “0147” are normally the four leftmost keys on the numpad, and the other two are just -1 and +1 from that.

Anyways, hope that helps! :grinning:


ALT+0145 = ‘

I use Character Map a lot. I’ve challenged myself to learn French, so I need the characters with accents.

There’s a program called Auto Hot Key that I’ve used in the past (for programming in TADS 3) with which you can create your own keystroke shortcuts.

I agree that almost no readers will notice if there are no curly quotes or curly apostrophes. If I were writing a whole story directly in Twine, I wouldn’t worry about it, but because I’ve imported a lot of text from a word processor, those characters are already there, and it would be messy to have the text go back and forth between one type and the other.