<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -79,7 +79,7 @@ class Type:
 
             v.addBool(&quot;enabled&quot;, True, &quot;Enabled&quot;)
             v.addList(&quot;items&quot;, [], &quot;Items&quot;,
-                      mypickle.StrNoEscapeVar(&quot;&quot;, &quot;&quot;, &quot;&quot;))
+                      mypickle.StrLatin1Var(&quot;&quot;, &quot;&quot;, &quot;&quot;))
 
             v.makeDicts()
             </diff>
      <filename>autocompletion.py</filename>
    </modified>
    <modified>
      <diff>@@ -99,10 +99,10 @@ class GlobalData:
         v.addInt(&quot;height&quot;, 830, &quot;Height&quot;, 300, 9999)
         v.addInt(&quot;viewMode&quot;, VIEWMODE_LAYOUT, &quot;ViewMode&quot;, VIEWMODE_DRAFT,
                  VIEWMODE_OVERVIEW_LARGE)
-        v.addStr(&quot;license&quot;, &quot;&quot;, &quot;License&quot;)
+        v.addStrBinary(&quot;license&quot;, &quot;&quot;, &quot;License&quot;)
 
         v.addList(&quot;files&quot;, [], &quot;Files&quot;,
-                  mypickle.StrNoEscapeVar(&quot;&quot;, &quot;&quot;, &quot;&quot;))
+                  mypickle.StrUnicodeVar(&quot;&quot;, &quot;&quot;, &quot;&quot;))
         
         v.makeDicts()
         v.setDefaults(self)
@@ -165,8 +165,7 @@ class GlobalData:
 
     # save global spell checker dictionary to disk
     def saveScDict(self):
-        util.writeToFile(self.scDictFilename,
-                         util.toUTF8(self.scDict.save()), mainFrame)
+        util.writeToFile(self.scDictFilename, self.scDict.save(), mainFrame)
 
 class MyPanel(wxPanel):
 
@@ -2381,7 +2380,7 @@ class MyApp(wxApp):
         gd.setViewMode(gd.viewMode)
 
         if util.fileExists(gd.scDictFilename):
-            s = util.fromUTF8(util.loadFile(gd.scDictFilename, None))
+            s = util.loadFile(gd.scDictFilename, None)
 
             if s:
                 gd.scDict.load(s)</diff>
      <filename>blyte.py</filename>
    </modified>
    <modified>
      <diff>@@ -399,13 +399,13 @@ class Config:
         v.addInt(&quot;cursorColumn&quot;, 0, &quot;Cursor/Column&quot;, 0, 1000000)
 
         # various strings we add to the script
-        v.addStrNoEscape(&quot;strMore&quot;, &quot;(MORE)&quot;, &quot;String/MoreDialogue&quot;)
-        v.addStrNoEscape(&quot;strContinuedPageEnd&quot;, &quot;(CONTINUED)&quot;,
-                         &quot;String/ContinuedPageEnd&quot;)
-        v.addStrNoEscape(&quot;strContinuedPageStart&quot;, &quot;CONTINUED:&quot;,
-                         &quot;String/ContinuedPageStart&quot;)
-        v.addStrNoEscape(&quot;strDialogueContinued&quot;, &quot; (cont'd)&quot;,
-                         &quot;String/DialogueContinued&quot;)
+        v.addStrLatin1(&quot;strMore&quot;, &quot;(MORE)&quot;, &quot;String/MoreDialogue&quot;)
+        v.addStrLatin1(&quot;strContinuedPageEnd&quot;, &quot;(CONTINUED)&quot;,
+                       &quot;String/ContinuedPageEnd&quot;)
+        v.addStrLatin1(&quot;strContinuedPageStart&quot;, &quot;CONTINUED:&quot;,
+                       &quot;String/ContinuedPageStart&quot;)
+        v.addStrLatin1(&quot;strDialogueContinued&quot;, &quot; (cont'd)&quot;,
+                       &quot;String/DialogueContinued&quot;)
 
         v.makeDicts()
         
@@ -447,7 +447,7 @@ class Config:
             for it in el.cvars.numeric.itervalues():
                 util.clampObj(el, it.name, it.minVal, it.maxVal)
 
-        for it in self.cvars.stringNoEscape.itervalues():
+        for it in self.cvars.stringLatin1.itervalues():
             setattr(self, it.name, util.toInputStr(getattr(self, it.name)))
             
         # make sure usable space on the page isn't too small
@@ -850,26 +850,27 @@ class ConfigGlobal:
                                  % wxPlatform
             s2 = &quot;&quot;
 
-        v.addStr(&quot;pdfViewerPath&quot;, s1, &quot;PDF/ViewerPath&quot;)
-        v.addStr(&quot;pdfViewerArgs&quot;, s2, &quot;PDF/ViewerArguments&quot;)
+        v.addStrUnicode(&quot;pdfViewerPath&quot;, s1, &quot;PDF/ViewerPath&quot;)
+        v.addStrBinary(&quot;pdfViewerArgs&quot;, s2, &quot;PDF/ViewerArguments&quot;)
 
         # fonts
         if misc.isUnix:
-            v.addStr(&quot;fontNormal&quot;, &quot;0;-adobe-courier-medium-r-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontNormal&quot;)
-            v.addStr(&quot;fontBold&quot;, &quot;0;-adobe-courier-bold-r-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontBold&quot;)
-            v.addStr(&quot;fontItalic&quot;, &quot;0;-adobe-courier-medium-o-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontItalic&quot;)
-            v.addStr(&quot;fontBoldItalic&quot;, &quot;0;-adobe-courier-bold-o-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontBoldItalic&quot;)
+            v.addStrBinary(&quot;fontNormal&quot;, &quot;0;-adobe-courier-medium-r-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontNormal&quot;)
+            v.addStrBinary(&quot;fontBold&quot;, &quot;0;-adobe-courier-bold-r-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontBold&quot;)
+            v.addStrBinary(&quot;fontItalic&quot;, &quot;0;-adobe-courier-medium-o-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontItalic&quot;)
+            v.addStrBinary(&quot;fontBoldItalic&quot;, &quot;0;-adobe-courier-bold-o-normal-*-*-140-*-*-m-*-iso8859-1&quot;, &quot;FontBoldItalic&quot;)
             
         elif misc.isWindows:
-            v.addStr(&quot;fontNormal&quot;, &quot;0;-13;0;0;0;400;0;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontNormal&quot;)
-            v.addStr(&quot;fontBold&quot;, &quot;0;-13;0;0;0;700;0;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontBold&quot;)
-            v.addStr(&quot;fontItalic&quot;, &quot;0;-13;0;0;0;400;255;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontItalic&quot;)
-            v.addStr(&quot;fontBoldItalic&quot;, &quot;0;-13;0;0;0;700;255;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontBoldItalic&quot;)
+            v.addStrBinary(&quot;fontNormal&quot;, &quot;0;-13;0;0;0;400;0;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontNormal&quot;)
+            v.addStrBinary(&quot;fontBold&quot;, &quot;0;-13;0;0;0;700;0;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontBold&quot;)
+            v.addStrBinary(&quot;fontItalic&quot;, &quot;0;-13;0;0;0;400;255;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontItalic&quot;)
+            v.addStrBinary(&quot;fontBoldItalic&quot;, &quot;0;-13;0;0;0;700;255;0;0;0;3;2;1;49;Courier New&quot;, &quot;FontBoldItalic&quot;)
         else:
             raise ConfigError(&quot;unknown platform&quot;)
         
         # default script directory
-        v.addStr(&quot;scriptDir&quot;, misc.progPath, &quot;DefaultScriptDirectory&quot;)
+        v.addStrUnicode(&quot;scriptDir&quot;, misc.progPath,
+                        &quot;DefaultScriptDirectory&quot;)
         
         # colors
         v.addColor(&quot;text&quot;, 0, 0, 0, &quot;TextFG&quot;, &quot;Text foreground&quot;)</diff>
      <filename>config.py</filename>
    </modified>
    <modified>
      <diff>@@ -95,7 +95,7 @@ class HeaderString:
     #
     # sample of the format: '1,0,r,,${PAGE}.'
     def load(self, s):
-        a = s.split(&quot;,&quot;, 4)
+        a = util.fromUTF8(s).split(&quot;,&quot;, 4)
 
         if len(a) != 5:
             return
@@ -130,4 +130,4 @@ class HeaderString:
 
         s += &quot;,,%s&quot; % self.text
 
-        return s
+        return util.toUTF8(s)</diff>
      <filename>headers.py</filename>
    </modified>
    <modified>
      <diff>@@ -15,7 +15,7 @@ class Locations:
 
             v.addList(&quot;locations&quot;, [], &quot;Locations&quot;,
                       mypickle.ListVar(&quot;&quot;, [], &quot;&quot;,
-                                       mypickle.StrNoEscapeVar(&quot;&quot;, &quot;&quot;, &quot;&quot;)))
+                                       mypickle.StrLatin1Var(&quot;&quot;, &quot;&quot;, &quot;&quot;)))
 
             v.makeDicts()
             </diff>
      <filename>locations.py</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@ class Vars:
         self.all = self.getDict()
         self.color = self.getDict(ColorVar)
         self.numeric = self.getDict(NumericVar)
-        self.stringNoEscape = self.getDict(StrNoEscapeVar)
+        self.stringLatin1 = self.getDict(StrLatin1Var)
 
     # return dictionary containing given type of variable objects, or all
     # if typeObj is None.
@@ -100,11 +100,14 @@ class Vars:
     def addInt(self, *params):
         self.addVar(IntVar(*params))
 
-    def addStr(self, *params):
-        self.addVar(StrVar(*params))
+    def addStrLatin1(self, *params):
+        self.addVar(StrLatin1Var(*params))
 
-    def addStrNoEscape(self, *params):
-        self.addVar(StrNoEscapeVar(*params))
+    def addStrUnicode(self, *params):
+        self.addVar(StrUnicodeVar(*params))
+
+    def addStrBinary(self, *params):
+        self.addVar(StrBinaryVar(*params))
 
     def addElemName(self, *params):
         self.addVar(ElementNameVar(*params))
@@ -176,30 +179,41 @@ class IntVar(NumericVar):
 
     def fromStr(self, vals, val, prefix):
         return util.str2int(val, self.defVal, self.minVal, self.maxVal)
+
+# ISO-8859-1 (Latin 1) string.
+class StrLatin1Var(ConfVar):
+    def __init__(self, name, defVal, name2):
+        ConfVar.__init__(self, name, defVal, name2)
         
-class StrVar(ConfVar):
+    def toStr(self, val, prefix):
+        return &quot;%s:%s\n&quot; % (prefix, util.toUTF8(val))
+
+    def fromStr(self, vals, val, prefix):
+        return util.fromUTF8(val)
+
+# Unicode string.
+class StrUnicodeVar(ConfVar):
     def __init__(self, name, defVal, name2):
         ConfVar.__init__(self, name, defVal, name2)
         
     def toStr(self, val, prefix):
-        return &quot;%s:%s\n&quot; % (prefix, util.encodeStr(val))
+        return &quot;%s:%s\n&quot; % (prefix, val.encode(&quot;UTF-8&quot;))
 
     def fromStr(self, vals, val, prefix):
-        return util.decodeStr(val)
+        return val.decode(&quot;UTF-8&quot;, &quot;ignore&quot;)
 
-# like StrVar, but doesn't do any escaping. this is useful if you have
-# e.g. Latin1 text without newlines that you want to transcode to UTF-8
-# later on, which is impossible to do with StrVar since it's escaped the
-# Latin1 characters already.
-class StrNoEscapeVar(ConfVar):
+# binary string, can contain anything. characters outside of printable
+# ASCII (and \ itself) are encoded as \XX, where XX is the hex code of the
+# character.
+class StrBinaryVar(ConfVar):
     def __init__(self, name, defVal, name2):
         ConfVar.__init__(self, name, defVal, name2)
         
     def toStr(self, val, prefix):
-        return &quot;%s:%s\n&quot; % (prefix, val)
+        return &quot;%s:%s\n&quot; % (prefix, util.encodeStr(val))
 
     def fromStr(self, vals, val, prefix):
-        return val
+        return util.decodeStr(val)
 
 # screenplay.ACTION &lt;-&gt; &quot;Action&quot;
 class ElementNameVar(ConfVar):</diff>
      <filename>mypickle.py</filename>
    </modified>
    <modified>
      <diff>@@ -140,19 +140,19 @@ class Screenplay:
         output += &quot;#Version 3\n&quot;
 
         output += &quot;#Begin-Auto-Completion \n&quot;
-        output += util.toUTF8(self.autoCompletion.save())
+        output += self.autoCompletion.save()
         output += &quot;#End-Auto-Completion \n&quot;
 
         output += &quot;#Begin-Config \n&quot;
-        output += util.toUTF8(self.cfg.save())
+        output += self.cfg.save()
         output += &quot;#End-Config \n&quot;
 
         output += &quot;#Begin-Locations \n&quot;
-        output += util.toUTF8(self.locations.save())
+        output += self.locations.save()
         output += &quot;#End-Locations \n&quot;
 
         output += &quot;#Begin-Spell-Checker-Dict \n&quot;
-        output += util.toUTF8(self.scDict.save())
+        output += self.scDict.save()
         output += &quot;#End-Spell-Checker-Dict \n&quot;
         
         pgs = self.titles.pages
@@ -161,10 +161,10 @@ class Screenplay:
                 output += &quot;#Title-Page \n&quot;
 
             for i in xrange(len(pgs[pg])):
-                output += &quot;#Title-String %s\n&quot; % util.toUTF8(str(pgs[pg][i]))
+                output += &quot;#Title-String %s\n&quot; % str(pgs[pg][i])
 
         for h in self.headers.hdrs:
-            output += &quot;#Header-String %s\n&quot; % util.toUTF8(str(h))
+            output += &quot;#Header-String %s\n&quot; % str(h)
 
         output += &quot;#Header-Empty-Lines %d\n&quot; % self.headers.emptyLinesAfter
 
@@ -190,32 +190,6 @@ class Screenplay:
         # remove default empty line
         sp.lines = []
 
-        # did we encounter characters not in ISO-8859-1
-        invalidChars = False
-
-        # did we encounter characters in ISO-8859-1, but undesired
-        unwantedChars = False
-
-        # convert to ISO-8859-1, remove invalid characters
-        for i in xrange(len(lines)):
-            try:
-                s = unicode(lines[i], &quot;UTF-8&quot;)
-            except ValueError:
-                raise error.MiscError(&quot;Line %d contains invalid UTF-8 data.&quot;
-                                      % (i + 1))
-
-            try:
-                s = s.encode(&quot;ISO-8859-1&quot;)
-            except ValueError:
-                invalidChars = True
-                s = s.encode(&quot;ISO-8859-1&quot;, &quot;backslashreplace&quot;)
-
-            newS = util.toInputStr(s)
-            if s != newS:
-                unwantedChars = True
-
-            lines[i] = newS
-
         if len(lines) &lt; 2:
             raise error.MiscError(&quot;File has too few lines to be a valid\n&quot;
                                   &quot;screenplay file.&quot;)
@@ -314,7 +288,7 @@ class Screenplay:
 
                 lb = config.char2lb(s[0], False)
                 lt = config.char2lt(s[1], False)
-                text = s[2:]
+                text = util.toInputStr(util.fromUTF8(s[2:]))
 
                 # convert unknown lb types into LB_SPACE
                 if lb == None:
@@ -375,18 +349,6 @@ class Screenplay:
                         &quot;  You'll lose that information if you save over&quot;
                         &quot; the existing file.&quot;)
 
-        if invalidChars:
-            msgs.append(&quot;Screenplay contained characters not in the&quot;
-                        &quot; ISO-8859-1 character set, which is all that this&quot;
-                        &quot; version of the program supports.\n\n&quot;
-                        &quot;  These characters have been converted to their&quot;
-                        &quot; Unicode escape sequences. Search for '\u' to find&quot;
-                        &quot; them.&quot;)
-
-        if unwantedChars:
-            msgs.append(&quot;Screenplay contained invalid characters. These&quot;
-                        &quot; characters have been converted to '|'.&quot;)
-
         return (sp, &quot;\n\n&quot;.join(msgs))
 
     load = staticmethod(load)</diff>
      <filename>screenplay.py</filename>
    </modified>
    <modified>
      <diff>@@ -81,7 +81,7 @@ class Dict:
             v = self.__class__.cvars = mypickle.Vars()
 
             v.addList(&quot;wordsList&quot;, [], &quot;Words&quot;,
-                      mypickle.StrNoEscapeVar(&quot;&quot;, &quot;&quot;, &quot;&quot;))
+                      mypickle.StrLatin1Var(&quot;&quot;, &quot;&quot;, &quot;&quot;))
 
             v.makeDicts()
             </diff>
      <filename>spellcheck.py</filename>
    </modified>
    <modified>
      <diff>@@ -134,7 +134,7 @@ class TitleString:
     #
     # sample of the format: '0.000000,70.000000,24,cb,Helvetica,,text here'
     def load(self, s):
-        a = s.split(&quot;,&quot;, 6)
+        a = util.fromUTF8(s).split(&quot;,&quot;, 6)
 
         if len(a) != 7:
             return
@@ -170,4 +170,4 @@ class TitleString:
 
         s += &quot;,,%s&quot; % self.text
 
-        return s
+        return util.toUTF8(s)</diff>
      <filename>titles.py</filename>
    </modified>
    <modified>
      <diff>@@ -948,5 +948,8 @@ def showPDF(filename, cfgGl, frame):
     # give the full path of the program as first arg, so give a
     # dummy arg.
     args = [&quot;pdf&quot;] + cfgGl.pdfViewerArgs.split() + [filename]
-    
+
+    # FIXME: investigate if spawnv supports unicode string as program name
+    # in Python 2.3 (maybe also test Python 2.4 and switch to it on
+    # Windows if needed?)
     os.spawnv(os.P_NOWAIT, cfgGl.pdfViewerPath, args)</diff>
      <filename>util.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>105aaea03107a43254d26025ee4c1ceac04555e4</id>
    </parent>
  </parents>
  <author>
    <name>Osku Salerma</name>
    <email>osku@iki.fi</email>
  </author>
  <url>http://github.com/oskusalerma/blyte/commit/4f76a9379bf2715ca513b4688ef8041ce65ae4f8</url>
  <id>4f76a9379bf2715ca513b4688ef8041ce65ae4f8</id>
  <committed-date>2006-03-04T22:58:10-08:00</committed-date>
  <authored-date>2006-03-04T22:58:10-08:00</authored-date>
  <message>Add Str(Latin1|Unicode|Binary)Var to mypickle and change everyone to use
them. Remove global toUTF8/fromUTF8 calls since everyone is now
responsible for their own encodings.</message>
  <tree>70831e301f5ac2f0d7f246317dff61934192a607</tree>
  <committer>
    <name>Osku Salerma</name>
    <email>osku@iki.fi</email>
  </committer>
</commit>
