]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_1_5.py
Don't use widest label for numerical citations.
[lyx.git] / lib / lyx2lyx / lyx_1_5.py
index 4b75701688e125ce572a8871ae4bcc4e5682eabc..d3de88f9981148e5d3b50d27f038f5bbc944e965 100644 (file)
@@ -15,7 +15,7 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 """ Convert files to the file format generated by lyx 1.5"""
 
@@ -287,7 +287,7 @@ necessary parsing in modern formats than in ancient ones.
                 inset_result = inset_re.match(document.body[i])
                 if inset_result:
                     insets.append(inset_result.group(1))
-                else: 
+                else:
                     insets.append("")
             elif find_token(document.body, "\\end_inset", i, i + 1) == i:
                 del insets[-1]
@@ -362,7 +362,7 @@ def revert_unicode_line(document, i, insets, spec_chars, replacement_character =
     math_outro='$\n\\end_inset'
 
     mod_line = u''
-    if i and document.body[i - 1][:1] != '\\':
+    if i and not is_inset_line(document, i-1):
         last_char = document.body[i - 1][-1:]
     else:
         last_char = ''
@@ -445,7 +445,7 @@ implemented.'''
             insets.append(line[13:].split()[0])
         if line.find('\\end_inset') > -1:
             del insets[-1]
-        
+
         # Try to write the line
         try:
             # If all goes well the line is written here
@@ -653,17 +653,17 @@ def convert_commandparams(document):
             if commandparams_info[name][0] == "":
                 document.warning("Ignoring invalid option `%s' of command `%s'." % (option1, name))
             else:
-                lines.append('%s "%s"' % (commandparams_info[name][0], option1.replace('"', '\\"')))
+                lines.append('%s "%s"' % (commandparams_info[name][0], option1.replace('\\', '\\\\').replace('"', '\\"')))
         if option2 != "":
             if commandparams_info[name][1] == "":
                 document.warning("Ignoring invalid second option `%s' of command `%s'." % (option2, name))
             else:
-                lines.append('%s "%s"' % (commandparams_info[name][1], option2.replace('"', '\\"')))
+                lines.append('%s "%s"' % (commandparams_info[name][1], option2.replace('\\', '\\\\').replace('"', '\\"')))
         if argument != "":
             if commandparams_info[name][2] == "":
                 document.warning("Ignoring invalid argument `%s' of command `%s'." % (argument, name))
             else:
-                lines.append('%s "%s"' % (commandparams_info[name][2], argument.replace('"', '\\"')))
+                lines.append('%s "%s"' % (commandparams_info[name][2], argument.replace('\\', '\\\\').replace('"', '\\"')))
         document.body[i:i+1] = lines
         i = i + 1
 
@@ -676,7 +676,7 @@ def revert_commandparams(document):
         if i == -1:
             break
         name = document.body[i].split()[2]
-        j = find_end_of_inset(document.body, i + 1)
+        j = find_end_of_inset(document.body, i)
         preview_line = ""
         option1 = ""
         option2 = ""
@@ -690,13 +690,13 @@ def revert_commandparams(document):
                     preview_line = document.body[k]
                 elif (commandparams_info[name][0] != "" and
                       pname == commandparams_info[name][0]):
-                    option1 = pvalue.strip('"').replace('\\"', '"')
+                    option1 = pvalue.strip('"').replace('\\"', '"').replace('\\\\', '\\')
                 elif (commandparams_info[name][1] != "" and
                       pname == commandparams_info[name][1]):
-                    option2 = pvalue.strip('"').replace('\\"', '"')
+                    option2 = pvalue.strip('"').replace('\\"', '"').replace('\\\\', '\\')
                 elif (commandparams_info[name][2] != "" and
                       pname == commandparams_info[name][2]):
-                    argument = pvalue.strip('"').replace('\\"', '"')
+                    argument = pvalue.strip('"').replace('\\"', '"').replace('\\\\', '\\')
             elif document.body[k].strip() != "":
                 document.warning("Ignoring unknown contents `%s' in command inset %s." % (document.body[k], name))
         if name == "bibitem":
@@ -721,7 +721,7 @@ def revert_commandparams(document):
             lines.append('')
             lines.append('\\end_inset')
         document.body[i:j+1] = lines
-        i = j + 1
+        i += len(lines) + 1
 
 
 def revert_nomenclature(document):
@@ -1150,6 +1150,33 @@ def convert_accent(document):
         i += 3
 
 
+def is_inset_line(document, i):
+    """ Line i of body has an inset """
+    if document.body[i][:1] == '\\':
+        return True
+    last_tokens = "".join(document.body[i].split()[-2:])
+    return last_tokens.find('\\') != -1
+
+
+# A wrapper around normalize that handles special cases (cf. bug 3313)
+def normalize(form, text):
+    # do not normalize OHM, ANGSTROM
+    keep_characters = [0x2126,0x212b]
+    result = ''
+    convert = ''
+    for i in text:
+        if ord(i) in keep_characters:
+            if len(convert) > 0:
+                result = result + unicodedata.normalize(form, convert)
+                convert = ''
+            result = result + i
+        else:
+            convert = convert + i
+    if len(convert) > 0:
+        result = result + unicodedata.normalize(form, convert)
+    return result
+
+
 def revert_accent(document):
     inverse_accent_map = {}
     for k in accent_map:
@@ -1168,7 +1195,7 @@ def revert_accent(document):
     for i in range(len(document.body) - 1):
         if document.body[i] == '' or document.body[i+1] == '' or document.body[i][-1] == ' ':
             continue
-        if (document.body[i+1][0] in inverse_accent_map and document.body[i][:1] != '\\'):
+        if (document.body[i+1][0] in inverse_accent_map and not is_inset_line(document, i)):
             # the last character of this line and the first of the next line
             # form probably a surrogate pair, inline insets are excluded (second part of the test)
             while (len(document.body[i+1]) > 0 and document.body[i+1][0] != ' '):
@@ -1182,9 +1209,9 @@ def revert_accent(document):
         # because we never use u'xxx' for string literals, but 'xxx'.
         # Therefore we may have to try two times to normalize the data.
         try:
-            document.body[i] = unicodedata.normalize("NFD", document.body[i])
+            document.body[i] = normalize("NFD", document.body[i])
         except TypeError:
-            document.body[i] = unicodedata.normalize("NFD", unicode(document.body[i], 'utf-8'))
+            document.body[i] = normalize("NFD", unicode(document.body[i], 'utf-8'))
 
     # Replace accented characters with InsetLaTeXAccent
     # Do not convert characters that can be represented in the chosen
@@ -1226,10 +1253,7 @@ def revert_accent(document):
                     if j < len(document.body[i]) - 1:
                         document.body.insert(i+1, document.body[i][j+1:])
                     # Delete the accented character
-                    if j > 0:
-                        document.body[i] = document.body[i][:j-1]
-                    else:
-                        document.body[i] = u''
+                    document.body[i] = document.body[i][:j]
                     # Finally add the InsetLaTeXAccent
                     document.body[i] += "\\i \\%s{}" % inverse_special_accent_map[accent]
                     break
@@ -1242,16 +1266,13 @@ def revert_accent(document):
                     accented_char = inverse_accented_map[accented_char]
                 accent = document.body[i][j]
                 try:
-                    dummy = unicodedata.normalize("NFC", accented_char + accent).encode(encoding_stack[-1])
+                    dummy = normalize("NFC", accented_char + accent).encode(encoding_stack[-1])
                 except UnicodeEncodeError:
                     # Insert the rest of the line as new line
                     if j < len(document.body[i]) - 1:
                         document.body.insert(i+1, document.body[i][j+1:])
                     # Delete the accented characters
-                    if j > 1:
-                        document.body[i] = document.body[i][:j-2]
-                    else:
-                        document.body[i] = u''
+                    document.body[i] = document.body[i][:j-1]
                     # Finally add the InsetLaTeXAccent
                     document.body[i] += "\\i \\%s{%s}" % (inverse_accent_map[accent], accented_char)
                     break
@@ -1259,14 +1280,14 @@ def revert_accent(document):
 
     # Normalize to "Normal form C" (NFC, pre-composed characters) again
     for i in range(len(document.body)):
-        document.body[i] = unicodedata.normalize("NFC", document.body[i])
+        document.body[i] = normalize("NFC", document.body[i])
 
 
 def normalize_font_whitespace_259(document):
     """ Before format 259 the font changes were ignored if a
     whitespace was the first or last character in the sequence, this function
     transfers the whitespace outside."""
-       
+
     char_properties = {"\\series": "default",
                        "\\emph": "default",
                        "\\color": "none",
@@ -1277,8 +1298,8 @@ def normalize_font_whitespace_259(document):
 
 def normalize_font_whitespace_274(document):
     """ Before format 259 (sic) the font changes were ignored if a
-    whitespace was the first or last character in the sequence. This was 
-    corrected for most font properties in format 259, but the language 
+    whitespace was the first or last character in the sequence. This was
+    corrected for most font properties in format 259, but the language
     was forgotten then. This function applies the same conversion done
     there (namely, transfers the whitespace outside) for font language
     changes, as well."""
@@ -1289,11 +1310,11 @@ def normalize_font_whitespace_274(document):
 def get_paragraph_language(document, i):
     """ Return the language of the paragraph in which line i of the document
     body is. If the first thing in the paragraph is a \\lang command, that
-    is the paragraph's langauge; otherwise, the paragraph's language is the 
+    is the paragraph's langauge; otherwise, the paragraph's language is the
     document's language."""
 
     lines = document.body
-       
+
     first_nonempty_line = \
         find_nonempty_line(lines, find_beginning_of_layout(lines, i) + 1)
 
@@ -1303,7 +1324,7 @@ def get_paragraph_language(document, i):
         return words[1]
     else:
         return document.language
-       
+
 def normalize_font_whitespace(document, char_properties):
     """ Before format 259 the font changes were ignored if a
     whitespace was the first or last character in the sequence, this function
@@ -1576,7 +1597,7 @@ def revert_graphics_rotation(document):
 
 
 def convert_tableborder(document):
-    # The problematic is: LyX double the table cell border as it ignores the "|" character in
+    # The problem is: LyX doubles the table cell border as it ignores the "|" character in
     # the cell arguments. A fix takes care of this and therefore the "|" has to be removed
     i = 0
     while i < len(document.body):
@@ -1585,7 +1606,7 @@ def convert_tableborder(document):
         # the two tokens have to be in one line
         if (h != -1 and k != -1):
             # delete the "|"
-            document.body[i] = document.body[i][:k] + document.body[i][k+1:len(document.body[i])-1]
+            document.body[i] = document.body[i][:k] + document.body[i][k+1:len(document.body[i])]
         i = i + 1
 
 
@@ -1602,13 +1623,13 @@ def revert_tableborder(document):
 
 
 def revert_armenian(document):
-    
-    # set inputencoding from armscii8 to auto 
+
+    # set inputencoding from armscii8 to auto
     if document.inputencoding == "armscii8":
         i = find_token(document.header, "\\inputencoding", 0)
         if i != -1:
             document.header[i] = "\\inputencoding auto"
-    # check if preamble exists, if not k is set to -1 
+    # check if preamble exists, if not k is set to -1
     i = 0
     k = -1
     while i < len(document.preamble):
@@ -1625,7 +1646,7 @@ def revert_armenian(document):
         # create the preamble when it doesn't exist
         else:
             document.preamble.append('\\usepackage{armtex}')
-    # Set document language from armenian to english 
+    # Set document language from armenian to english
     if document.language == "armenian":
         document.language = "english"
         i = find_token(document.header, "\\language", 0)
@@ -1665,10 +1686,10 @@ def revert_preamble_listings_params(document):
 
 
 def revert_listings_inset(document):
-    r''' Revert listings inset to \lstinline or \begin, \end lstlisting, translate 
+    r''' Revert listings inset to \lstinline or \begin, \end lstlisting, translate
 FROM
 
-\begin_inset 
+\begin_inset
 lstparams "language=Delphi"
 inline true
 status open
@@ -1766,7 +1787,7 @@ after label
             k = cap_end + 1
         inlinecode = ''
         # looking for the oneline code for lstinline
-        inlinecode = document.body[find_end_of_layout(document.body, 
+        inlinecode = document.body[find_end_of_layout(document.body,
             find_token(document.body,  '\\begin_layout %s' % document.default_layout, i + 1) +1 ) - 1]
         if len(caption) > 0:
             if len(params) == 0:
@@ -1785,7 +1806,7 @@ after label
             document.body[i:(j+1)] = [r'\begin_inset ERT',
                                       'status %s' % status,
                                       r'\begin_layout %s' % document.default_layout,
-                                      '', 
+                                      '',
                                       '',
                                       r'\backslash',
                                       'lstinline%s{%s}' % (params, inlinecode),
@@ -1813,7 +1834,7 @@ after label
                                       r'\end_layout',
                                       '',
                                       r'\end_inset']
-            
+
 
 def revert_include_listings(document):
     r''' Revert lstinputlisting Include option , translate
@@ -1852,7 +1873,7 @@ lstinputlisting{file}[opt]
         # find command line lstinputlisting{file}[options]
         cmd, file, option = '', '', ''
         if re.match(r'\\(lstinputlisting){([.\w]*)}(.*)', document.body[i].split()[2]):
-            cmd, file, option = re.match(r'\\(lstinputlisting){([.\w]*)}(.*)', document.body[i].split()[2]).groups()            
+            cmd, file, option = re.match(r'\\(lstinputlisting){([.\w]*)}(.*)', document.body[i].split()[2]).groups()
         option = option.replace('\\', '\\backslash\n')
         document.body[i : j + 1] = [r'\begin_inset ERT',
                                     'status open',