1 # This file is part of lyx2lyx
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2008 The LyX Team <lyx-devel@lists.lyx.org>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 """ Convert files to the file format generated by lyx 1.6"""
25 from parser_tools
import find_token
, find_end_of
, find_tokens
, get_value
, get_value_string
27 ####################################################################
28 # Private helper functions
30 def find_end_of_inset(lines
, i
):
31 " Find end of inset, where lines[i] is included."
32 return find_end_of(lines
, i
, "\\begin_inset", "\\end_inset")
36 # document.body[i] = wrap_insert_ert(...)
37 # wrap_into_ert may returns a multiline string, which should NOT appear
38 # in document.body. Insetad, do something like this:
39 # subst = wrap_inset_ert(...)
40 # subst = subst.split('\n')
41 # document.body[i:i+1] = subst
43 # where the last statement resets the counter to accord with the added
45 def wrap_into_ert(string
, src
, dst
):
46 '''Within string, replace occurrences of src with dst, wrapped into ERT
47 E.g.: wrap_into_ert('sch\"on', "\\", "\\backslash") is:
48 sch<ERT>\\backslash</ERT>"on'''
49 return string
.replace(src
, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
50 + dst
+ '\n\\end_layout\n\\end_inset\n')
52 def put_cmd_in_ert(string
):
53 for rep
in unicode_reps
:
54 string
= string
.replace(rep
[1], rep
[0].replace('\\\\', '\\'))
55 string
= string
.replace('\\', "\\backslash\n")
56 string
= "\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n" \
57 + string
+ "\n\\end_layout\n\\end_inset"
60 def add_to_preamble(document
, text
):
61 """ Add text to the preamble if it is not already there.
62 Only the first line is checked!"""
64 if find_token(document
.preamble
, text
[0], 0) != -1:
67 document
.preamble
.extend(text
)
69 def insert_to_preamble(index
, document
, text
):
70 """ Insert text to the preamble at a given line"""
72 document
.preamble
.insert(index
, text
)
74 # Convert a LyX length into a LaTeX length
76 units
= {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
77 "page%":"\\backslash\npagewidth", "line%":"\\backslash\nlinewidth",
78 "theight%":"\\backslash\ntextheight", "pheight%":"\\backslash\npageheight"}
80 # Convert LyX units to LaTeX units
81 for unit
in units
.keys():
82 if len.find(unit
) != -1:
83 len = '%f' % (len2value(len) / 100)
84 len = len.strip('0') + units
[unit
]
89 # Return the value of len without the unit in numerical form.
91 result
= re
.search('([+-]?[0-9.]+)', len)
93 return float(result
.group(1))
97 # Unfortunately, this doesn't really work, since Standard isn't always default.
98 # But it's as good as we can do right now.
99 def find_default_layout(document
, start
, end
):
100 l
= find_token(document
.body
, "\\begin_layout Standard", start
, end
)
102 l
= find_token(document
.body
, "\\begin_layout PlainLayout", start
, end
)
104 l
= find_token(document
.body
, "\\begin_layout Plain Layout", start
, end
)
107 def get_option(document
, m
, option
, default
):
108 l
= document
.body
[m
].find(option
)
111 val
= document
.body
[m
][l
:].split('"')[1]
114 def remove_option(document
, m
, option
):
115 l
= document
.body
[m
].find(option
)
117 val
= document
.body
[m
][l
:].split('"')[1]
118 document
.body
[m
] = document
.body
[m
][:l
-1] + document
.body
[m
][l
+len(option
+ '="' + val
+ '"'):]
121 def set_option(document
, m
, option
, value
):
122 l
= document
.body
[m
].find(option
)
124 oldval
= document
.body
[m
][l
:].split('"')[1]
125 l
= l
+ len(option
+ '="')
126 document
.body
[m
] = document
.body
[m
][:l
] + value
+ document
.body
[m
][l
+len(oldval
):]
128 document
.body
[m
] = document
.body
[m
][:-1] + ' ' + option
+ '="' + value
+ '">'
132 def read_unicodesymbols():
133 " Read the unicodesymbols list of unicode characters and corresponding commands."
134 pathname
= os
.path
.abspath(os
.path
.dirname(sys
.argv
[0]))
135 fp
= open(os
.path
.join(pathname
.strip('lyx2lyx'), 'unicodesymbols'))
137 # Two backslashes, followed by some non-word character, and then a character
138 # in brackets. The idea is to check for constructs like: \"{u}, which is how
139 # they are written in the unicodesymbols file; but they can also be written
140 # as: \"u or even \" u.
141 r
= re
.compile(r
'\\\\(\W)\{(\w)\}')
142 for line
in fp
.readlines():
143 if line
[0] != '#' and line
.strip() != "":
144 line
=line
.replace(' "',' ') # remove all quotation marks with spaces before
145 line
=line
.replace('" ',' ') # remove all quotation marks with spaces after
146 line
=line
.replace(r
'\"','"') # replace \" by " (for characters with diaeresis)
148 [ucs4
,command
,dead
] = line
.split(None,2)
149 if command
[0:1] != "\\":
151 spec_chars
.append([command
, unichr(eval(ucs4
))])
157 # If the character is a double-quote, then we need to escape it, too,
158 # since it is done that way in the LyX file.
159 if m
.group(1) == "\"":
162 command
+= m
.group(1) + m
.group(2)
163 commandbl
+= m
.group(1) + ' ' + m
.group(2)
164 spec_chars
.append([command
, unichr(eval(ucs4
))])
165 spec_chars
.append([commandbl
, unichr(eval(ucs4
))])
170 def extract_argument(line
):
171 'Extracts a LaTeX argument from the start of line. Returns (arg, rest).'
176 bracere
= re
.compile("(\s*)(.*)")
177 n
= bracere
.match(line
)
178 whitespace
= n
.group(1)
181 if brace
!= "[" and brace
!= "{":
205 # We never found the matching brace
206 # So, to be on the safe side, let's just return everything
207 # which will then get wrapped as ERT
209 return (line
[:pos
+ 1], line
[pos
+ 1:])
213 '''Converts LaTeX commands into ERT. line may well be a multi-line
214 string when it is returned.'''
219 ## FIXME Escaped \ ??
220 # This regex looks for a LaTeX command---i.e., something of the form
221 # "\alPhaStuFF", or "\X", where X is any character---where the command
222 # may also be preceded by an additional backslash, which is how it would
223 # appear (e.g.) in an InsetIndex.
224 labelre
= re
.compile(r
'(.*?)\\?(\\(?:[a-zA-Z]+|.))(.*)')
226 m
= labelre
.match(line
)
233 (arg
, rest
) = extract_argument(end
)
238 # If we wanted to put labels into an InsetLabel, for example, then we
239 # would just need to test here for cmd == "label" and then take some
240 # appropriate action, i.e., to use arg to get the content and then
241 # wrap it appropriately.
242 cmd
= put_cmd_in_ert(cmd
)
243 retval
+= "\n" + cmd
+ "\n"
245 m
= labelre
.match(line
)
246 # put all remaining braces in ERT
247 line
= wrap_into_ert(line
, '}', '}')
248 line
= wrap_into_ert(line
, '{', '{')
253 unicode_reps
= read_unicodesymbols()
256 #Might should do latex2ert first, then deal with stuff that DOESN'T
257 #end up inside ERT. That routine could be modified so that it returned
258 #a list of lines, and we could then skip ERT bits and only deal with
261 '''Takes a string, possibly multi-line, and returns the result of
262 converting LaTeX constructs into LyX constructs. Returns a list of
263 lines, suitable for insertion into document.body.'''
269 # Convert LaTeX to Unicode
270 # Commands of this sort need to be checked to make sure they are
271 # followed by a non-alpha character, lest we replace too much.
272 hardone
= re
.compile(r
'^\\\\[a-zA-Z]+$')
274 for rep
in unicode_reps
:
275 if hardone
.match(rep
[0]):
278 pos
= data
.find(rep
[0], pos
)
281 nextpos
= pos
+ len(rep
[0])
282 if nextpos
< len(data
) and data
[nextpos
].isalpha():
283 # not the end of that command
286 data
= data
[:pos
] + rep
[1] + data
[nextpos
:]
289 data
= data
.replace(rep
[0], rep
[1])
293 data
= wrap_into_ert(data
, r
'\"', '"')
295 data
= data
.replace('\\\\', '\\')
298 mathre
= re
.compile('^(.*?)(\$.*?\$)(.*)')
299 lines
= data
.split('\n')
301 #document.warning("LINE: " + line)
302 #document.warning(str(i) + ":" + document.body[i])
303 #document.warning("LAST: " + document.body[-1])
308 f
= m
.group(2).replace('\\\\', '\\')
313 subst
= s
.split('\n')
315 retval
.append("\\begin_inset Formula " + f
)
316 retval
.append("\\end_inset")
318 # Handle whatever is left, which is just text
320 subst
= g
.split('\n')
325 def lyxline2latex(document
, line
, inert
):
326 'Convert some LyX stuff into corresponding LaTeX stuff line-wise, as best we can.'
327 if line
.startswith("\\begin_inset Formula"):
329 elif line
.startswith("\\begin_inset Quotes"):
330 # For now, we do a very basic reversion. Someone who understands
331 # quotes is welcome to fix it up.
332 qtype
= line
[20:].strip()
346 elif line
.isspace() or \
347 line
.startswith("\\begin_layout") or \
348 line
.startswith("\\end_layout") or \
349 line
.startswith("\\begin_inset") or \
350 line
.startswith("\\end_inset") or \
351 line
.startswith("\\lang") or \
352 line
.strip() == "status collapsed" or \
353 line
.strip() == "status open":
357 # this needs to be added to the preamble because of cases like
358 # \textmu, \textbackslash, etc.
359 add_to_preamble(document
, ['% added by lyx2lyx for converted entries',
360 '\\@ifundefined{textmu}',
361 ' {\\usepackage{textcomp}}{}'])
362 # a lossless reversion is not possible
363 # try at least to handle some common insets and settings
365 line
= line
.replace(r
'\backslash', '\\')
367 line
= line
.replace('&', '\\&{}')
368 line
= line
.replace('#', '\\#{}')
369 line
= line
.replace('^', '\\^{}')
370 line
= line
.replace('%', '\\%{}')
371 line
= line
.replace('_', '\\_{}')
372 line
= line
.replace('$', '\\${}')
374 # Do the LyX text --> LaTeX conversion
375 for rep
in unicode_reps
:
376 line
= line
.replace(rep
[1], rep
[0].replace('\\\\', '\\') + "{}")
377 line
= line
.replace(r
'\backslash', r
'\textbackslash{}')
378 line
= line
.replace(r
'\series bold', r
'\bfseries{}').replace(r
'\series default', r
'\mdseries{}')
379 line
= line
.replace(r
'\shape italic', r
'\itshape{}').replace(r
'\shape smallcaps', r
'\scshape{}')
380 line
= line
.replace(r
'\shape slanted', r
'\slshape{}').replace(r
'\shape default', r
'\upshape{}')
381 line
= line
.replace(r
'\emph on', r
'\em{}').replace(r
'\emph default', r
'\em{}')
382 line
= line
.replace(r
'\noun on', r
'\scshape{}').replace(r
'\noun default', r
'\upshape{}')
383 line
= line
.replace(r
'\bar under', r
'\underbar{').replace(r
'\bar default', r
'}')
384 line
= line
.replace(r
'\family sans', r
'\sffamily{}').replace(r
'\family default', r
'\normalfont{}')
385 line
= line
.replace(r
'\family typewriter', r
'\ttfamily{}').replace(r
'\family roman', r
'\rmfamily{}')
386 line
= line
.replace(r
'\InsetSpace ', r
'').replace(r
'\SpecialChar ', r
'')
390 def lyx2latex(document
, lines
):
391 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.'
392 # clean up multiline stuff
396 for curline
in range(len(lines
)):
397 line
= lines
[curline
]
398 if line
.startswith("\\begin_inset ERT"):
399 # We don't want to replace things inside ERT, so figure out
400 # where the end of the inset is.
401 ert_end
= find_end_of_inset(lines
, curline
+ 1)
403 inert
= ert_end
>= curline
404 content
+= lyxline2latex(document
, lines
[curline
], inert
)
409 ####################################################################
411 def convert_ltcaption(document
):
414 i
= find_token(document
.body
, "\\begin_inset Tabular", i
)
417 j
= find_end_of_inset(document
.body
, i
+ 1)
419 document
.warning("Malformed LyX document: Could not find end of tabular.")
422 nrows
= int(document
.body
[i
+1].split('"')[3])
423 ncols
= int(document
.body
[i
+1].split('"')[5])
426 for k
in range(nrows
):
427 m
= find_token(document
.body
, "<row", m
)
430 for k
in range(ncols
):
431 m
= find_token(document
.body
, "<cell", m
)
433 mend
= find_token(document
.body
, "</cell>", m
+ 1)
434 # first look for caption insets
435 mcap
= find_token(document
.body
, "\\begin_inset Caption", m
+ 1, mend
)
436 # then look for ERT captions
438 mcap
= find_token(document
.body
, "caption", m
+ 1, mend
)
440 mcap
= find_token(document
.body
, "\\backslash", mcap
- 1, mcap
)
443 if caption
== 'true':
445 set_option(document
, r
, 'caption', 'true')
446 set_option(document
, m
, 'multicolumn', '1')
447 set_option(document
, m
, 'bottomline', 'false')
448 set_option(document
, m
, 'topline', 'false')
449 set_option(document
, m
, 'rightline', 'false')
450 set_option(document
, m
, 'leftline', 'false')
451 #j = find_end_of_inset(document.body, j + 1)
453 set_option(document
, m
, 'multicolumn', '2')
460 #FIXME Use of wrap_into_ert can confuse lyx2lyx
461 def revert_ltcaption(document
):
464 i
= find_token(document
.body
, "\\begin_inset Tabular", i
)
467 j
= find_end_of_inset(document
.body
, i
+ 1)
469 document
.warning("Malformed LyX document: Could not find end of tabular.")
473 nrows
= int(document
.body
[i
+1].split('"')[3])
474 ncols
= int(document
.body
[i
+1].split('"')[5])
476 for k
in range(nrows
):
477 m
= find_token(document
.body
, "<row", m
)
478 caption
= get_option(document
, m
, 'caption', 'false')
479 if caption
== 'true':
480 remove_option(document
, m
, 'caption')
481 for k
in range(ncols
):
482 m
= find_token(document
.body
, "<cell", m
)
483 remove_option(document
, m
, 'multicolumn')
485 m
= find_token(document
.body
, "\\begin_inset Caption", m
)
488 m
= find_end_of_inset(document
.body
, m
+ 1)
489 document
.body
[m
] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
495 def convert_tablines(document
):
498 i
= find_token(document
.body
, "\\begin_inset Tabular", i
)
500 # LyX 1.3 inserted an extra space between \begin_inset
501 # and Tabular so let us try if this is the case and fix it.
502 i
= find_token(document
.body
, "\\begin_inset Tabular", i
)
506 document
.body
[i
] = "\\begin_inset Tabular"
507 j
= find_end_of_inset(document
.body
, i
+ 1)
509 document
.warning("Malformed LyX document: Could not find end of tabular.")
513 nrows
= int(document
.body
[i
+1].split('"')[3])
514 ncols
= int(document
.body
[i
+1].split('"')[5])
517 for k
in range(ncols
):
518 m
= find_token(document
.body
, "<column", m
)
519 left
= get_option(document
, m
, 'leftline', 'false')
520 right
= get_option(document
, m
, 'rightline', 'false')
521 col_info
.append([left
, right
])
522 remove_option(document
, m
, 'leftline')
523 remove_option(document
, m
, 'rightline')
527 for k
in range(nrows
):
528 m
= find_token(document
.body
, "<row", m
)
529 top
= get_option(document
, m
, 'topline', 'false')
530 bottom
= get_option(document
, m
, 'bottomline', 'false')
531 row_info
.append([top
, bottom
])
532 remove_option(document
, m
, 'topline')
533 remove_option(document
, m
, 'bottomline')
538 for k
in range(nrows
*ncols
):
539 m
= find_token(document
.body
, "<cell", m
)
540 mc_info
.append(get_option(document
, m
, 'multicolumn', '0'))
543 for l
in range(nrows
):
544 for k
in range(ncols
):
545 m
= find_token(document
.body
, '<cell', m
)
546 if mc_info
[l
*ncols
+ k
] == '0':
547 r
= set_option(document
, m
, 'topline', row_info
[l
][0])
548 r
= set_option(document
, m
, 'bottomline', row_info
[l
][1])
549 r
= set_option(document
, m
, 'leftline', col_info
[k
][0])
550 r
= set_option(document
, m
, 'rightline', col_info
[k
][1])
551 elif mc_info
[l
*ncols
+ k
] == '1':
553 while s
< ncols
and mc_info
[l
*ncols
+ s
] == '2':
555 if s
< ncols
and mc_info
[l
*ncols
+ s
] != '1':
556 r
= set_option(document
, m
, 'rightline', col_info
[k
][1])
557 if k
> 0 and mc_info
[l
*ncols
+ k
- 1] == '0':
558 r
= set_option(document
, m
, 'leftline', col_info
[k
][0])
563 def revert_tablines(document
):
566 i
= find_token(document
.body
, "\\begin_inset Tabular", i
)
569 j
= find_end_of_inset(document
.body
, i
+ 1)
571 document
.warning("Malformed LyX document: Could not find end of tabular.")
575 nrows
= int(document
.body
[i
+1].split('"')[3])
576 ncols
= int(document
.body
[i
+1].split('"')[5])
579 for k
in range(nrows
*ncols
):
580 m
= find_token(document
.body
, "<cell", m
)
581 top
= get_option(document
, m
, 'topline', 'false')
582 bottom
= get_option(document
, m
, 'bottomline', 'false')
583 left
= get_option(document
, m
, 'leftline', 'false')
584 right
= get_option(document
, m
, 'rightline', 'false')
585 lines
.append([top
, bottom
, left
, right
])
588 # we will want to ignore longtable captions
591 for k
in range(nrows
):
592 m
= find_token(document
.body
, "<row", m
)
593 caption
= get_option(document
, m
, 'caption', 'false')
594 caption_info
.append([caption
])
599 for k
in range(ncols
):
600 m
= find_token(document
.body
, "<column", m
)
602 for l
in range(nrows
):
603 left
= lines
[l
*ncols
+ k
][2]
604 if left
== 'false' and caption_info
[l
] == 'false':
606 set_option(document
, m
, 'leftline', left
)
608 for l
in range(nrows
):
609 right
= lines
[l
*ncols
+ k
][3]
610 if right
== 'false' and caption_info
[l
] == 'false':
612 set_option(document
, m
, 'rightline', right
)
616 for k
in range(nrows
):
617 m
= find_token(document
.body
, "<row", m
)
619 for l
in range(ncols
):
620 top
= lines
[k
*ncols
+ l
][0]
623 if caption_info
[k
] == 'false':
625 set_option(document
, m
, 'topline', top
)
627 for l
in range(ncols
):
628 bottom
= lines
[k
*ncols
+ l
][1]
629 if bottom
== 'false':
631 if caption_info
[k
] == 'false':
633 set_option(document
, m
, 'bottomline', bottom
)
639 def fix_wrong_tables(document
):
642 i
= find_token(document
.body
, "\\begin_inset Tabular", i
)
645 j
= find_end_of_inset(document
.body
, i
+ 1)
647 document
.warning("Malformed LyX document: Could not find end of tabular.")
651 nrows
= int(document
.body
[i
+1].split('"')[3])
652 ncols
= int(document
.body
[i
+1].split('"')[5])
654 for l
in range(nrows
):
656 for k
in range(ncols
):
657 m
= find_token(document
.body
, '<cell', m
)
659 if document
.body
[m
].find('multicolumn') != -1:
660 multicol_cont
= int(document
.body
[m
].split('"')[1])
662 if multicol_cont
== 2 and (k
== 0 or prev_multicolumn
== 0):
663 document
.body
[m
] = document
.body
[m
][:5] + document
.body
[m
][21:]
666 prev_multicolumn
= multicol_cont
673 def close_begin_deeper(document
):
677 i
= find_tokens(document
.body
, ["\\begin_deeper", "\\end_deeper"], i
)
682 if document
.body
[i
][:13] == "\\begin_deeper":
689 document
.body
[-2:-2] = ['\\end_deeper' for i
in range(depth
)]
692 def long_charstyle_names(document
):
695 i
= find_token(document
.body
, "\\begin_inset CharStyle", i
)
698 document
.body
[i
] = document
.body
[i
].replace("CharStyle ", "CharStyle CharStyle:")
701 def revert_long_charstyle_names(document
):
704 i
= find_token(document
.body
, "\\begin_inset CharStyle", i
)
707 document
.body
[i
] = document
.body
[i
].replace("CharStyle CharStyle:", "CharStyle ")
711 def axe_show_label(document
):
714 i
= find_token(document
.body
, "\\begin_inset CharStyle", i
)
717 if document
.body
[i
+ 1].find("show_label") != -1:
718 if document
.body
[i
+ 1].find("true") != -1:
719 document
.body
[i
+ 1] = "status open"
720 del document
.body
[ i
+ 2]
722 if document
.body
[i
+ 1].find("false") != -1:
723 document
.body
[i
+ 1] = "status collapsed"
724 del document
.body
[ i
+ 2]
726 document
.warning("Malformed LyX document: show_label neither false nor true.")
728 document
.warning("Malformed LyX document: show_label missing in CharStyle.")
733 def revert_show_label(document
):
736 i
= find_token(document
.body
, "\\begin_inset CharStyle", i
)
739 if document
.body
[i
+ 1].find("status open") != -1:
740 document
.body
.insert(i
+ 1, "show_label true")
742 if document
.body
[i
+ 1].find("status collapsed") != -1:
743 document
.body
.insert(i
+ 1, "show_label false")
745 document
.warning("Malformed LyX document: no legal status line in CharStyle.")
748 def revert_begin_modules(document
):
751 i
= find_token(document
.header
, "\\begin_modules", i
)
754 j
= find_end_of(document
.header
, i
, "\\begin_modules", "\\end_modules")
756 # this should not happen
758 document
.header
[i
: j
+ 1] = []
760 def convert_flex(document
):
761 "Convert CharStyle to Flex"
764 i
= find_token(document
.body
, "\\begin_inset CharStyle", i
)
767 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
769 def revert_flex(document
):
770 "Convert Flex to CharStyle"
773 i
= find_token(document
.body
, "\\begin_inset Flex", i
)
776 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
779 def revert_pdf_options(document
):
780 "Revert PDF options for hyperref."
781 # store the PDF options and delete the entries from the Lyx file
789 bookmarksnumbered
= ""
791 bookmarksopenlevel
= ""
799 i
= find_token(document
.header
, "\\use_hyperref", i
)
801 hyperref
= get_value(document
.header
, "\\use_hyperref", i
) == 'true'
802 del document
.header
[i
]
803 i
= find_token(document
.header
, "\\pdf_store_options", i
)
805 del document
.header
[i
]
806 i
= find_token(document
.header
, "\\pdf_title", 0)
808 title
= get_value_string(document
.header
, '\\pdf_title', 0, 0, True)
809 title
= ' pdftitle={' + title
+ '}'
810 del document
.header
[i
]
811 i
= find_token(document
.header
, "\\pdf_author", 0)
813 author
= get_value_string(document
.header
, '\\pdf_author', 0, 0, True)
815 author
= ' pdfauthor={' + author
+ '}'
817 author
= ',\n pdfauthor={' + author
+ '}'
818 del document
.header
[i
]
819 i
= find_token(document
.header
, "\\pdf_subject", 0)
821 subject
= get_value_string(document
.header
, '\\pdf_subject', 0, 0, True)
822 if title
== "" and author
== "":
823 subject
= ' pdfsubject={' + subject
+ '}'
825 subject
= ',\n pdfsubject={' + subject
+ '}'
826 del document
.header
[i
]
827 i
= find_token(document
.header
, "\\pdf_keywords", 0)
829 keywords
= get_value_string(document
.header
, '\\pdf_keywords', 0, 0, True)
830 if title
== "" and author
== "" and subject
== "":
831 keywords
= ' pdfkeywords={' + keywords
+ '}'
833 keywords
= ',\n pdfkeywords={' + keywords
+ '}'
834 del document
.header
[i
]
835 i
= find_token(document
.header
, "\\pdf_bookmarks", 0)
837 bookmarks
= get_value_string(document
.header
, '\\pdf_bookmarks', 0)
838 bookmarks
= ',\n bookmarks=' + bookmarks
839 del document
.header
[i
]
840 i
= find_token(document
.header
, "\\pdf_bookmarksnumbered", i
)
842 bookmarksnumbered
= get_value_string(document
.header
, '\\pdf_bookmarksnumbered', 0)
843 bookmarksnumbered
= ',\n bookmarksnumbered=' + bookmarksnumbered
844 del document
.header
[i
]
845 i
= find_token(document
.header
, "\\pdf_bookmarksopen", i
)
847 bookmarksopen
= get_value_string(document
.header
, '\\pdf_bookmarksopen', 0)
848 bookmarksopen
= ',\n bookmarksopen=' + bookmarksopen
849 del document
.header
[i
]
850 i
= find_token(document
.header
, "\\pdf_bookmarksopenlevel", i
)
852 bookmarksopenlevel
= get_value_string(document
.header
, '\\pdf_bookmarksopenlevel', 0, 0, True)
853 bookmarksopenlevel
= ',\n bookmarksopenlevel=' + bookmarksopenlevel
854 del document
.header
[i
]
855 i
= find_token(document
.header
, "\\pdf_breaklinks", i
)
857 breaklinks
= get_value_string(document
.header
, '\\pdf_breaklinks', 0)
858 breaklinks
= ',\n breaklinks=' + breaklinks
859 del document
.header
[i
]
860 i
= find_token(document
.header
, "\\pdf_pdfborder", i
)
862 pdfborder
= get_value_string(document
.header
, '\\pdf_pdfborder', 0)
863 if pdfborder
== 'true':
864 pdfborder
= ',\n pdfborder={0 0 0}'
866 pdfborder
= ',\n pdfborder={0 0 1}'
867 del document
.header
[i
]
868 i
= find_token(document
.header
, "\\pdf_colorlinks", i
)
870 colorlinks
= get_value_string(document
.header
, '\\pdf_colorlinks', 0)
871 colorlinks
= ',\n colorlinks=' + colorlinks
872 del document
.header
[i
]
873 i
= find_token(document
.header
, "\\pdf_backref", i
)
875 backref
= get_value_string(document
.header
, '\\pdf_backref', 0)
876 backref
= ',\n backref=' + backref
877 del document
.header
[i
]
878 i
= find_token(document
.header
, "\\pdf_pagebackref", i
)
880 pagebackref
= get_value_string(document
.header
, '\\pdf_pagebackref', 0)
881 pagebackref
= ',\n pagebackref=' + pagebackref
882 del document
.header
[i
]
883 i
= find_token(document
.header
, "\\pdf_pagemode", 0)
885 pagemode
= get_value_string(document
.header
, '\\pdf_pagemode', 0)
886 pagemode
= ',\n pdfpagemode=' + pagemode
887 del document
.header
[i
]
888 i
= find_token(document
.header
, "\\pdf_quoted_options", 0)
890 otheroptions
= get_value_string(document
.header
, '\\pdf_quoted_options', 0, 0, True)
891 if title
== "" and author
== "" and subject
== "" and keywords
== "":
892 otheroptions
= ' ' + otheroptions
894 otheroptions
= ',\n ' + otheroptions
895 del document
.header
[i
]
897 # write to the preamble when hyperref was used
899 # preamble write preparations
900 # bookmark numbers are only output when they are turned on
901 if bookmarksopen
== ',\n bookmarksopen=true':
902 bookmarksopen
= bookmarksopen
+ bookmarksopenlevel
903 if bookmarks
== ',\n bookmarks=true':
904 bookmarks
= bookmarks
+ bookmarksnumbered
+ bookmarksopen
906 bookmarks
= bookmarks
907 # hypersetup is only output when there are things to be set up
908 setupstart
= '\\hypersetup{%\n'
910 if otheroptions
== "" and title
== "" and author
== ""\
911 and subject
== "" and keywords
== "":
915 # babel must be loaded before hyperref and hyperref the first part
916 # of the preamble, like in LyX 1.6
917 insert_to_preamble(0, document
,
918 '% Commands inserted by lyx2lyx for PDF properties\n'
919 + '\\usepackage{babel}\n'
920 + '\\usepackage[unicode=true'
939 def remove_inzip_options(document
):
940 "Remove inzipName and embed options from the Graphics inset"
943 i
= find_token(document
.body
, "\\begin_inset Graphics", i
)
946 j
= find_end_of_inset(document
.body
, i
+ 1)
949 document
.warning("Malformed LyX document: Could not find end of graphics inset.")
950 # If there's a inzip param, just remove that
951 k
= find_token(document
.body
, "\tinzipName", i
+ 1, j
)
954 # embed option must follow the inzipName option
955 del document
.body
[k
+1]
959 def convert_inset_command(document
):
962 \begin_inset LatexCommand cmd
964 \begin_inset CommandInset InsetType
969 i
= find_token(document
.body
, "\\begin_inset LatexCommand", i
)
972 line
= document
.body
[i
]
973 r
= re
.compile(r
'\\begin_inset LatexCommand (.*)$')
977 #this is adapted from factory.cpp
978 if cmdName
[0:4].lower() == "cite":
979 insetName
= "citation"
980 elif cmdName
== "url" or cmdName
== "htmlurl":
982 elif cmdName
[-3:] == "ref":
984 elif cmdName
== "tableofcontents":
986 elif cmdName
== "printnomenclature":
987 insetName
= "nomencl_print"
988 elif cmdName
== "printindex":
989 insetName
= "index_print"
992 insertion
= ["\\begin_inset CommandInset " + insetName
, "LatexCommand " + cmdName
]
993 document
.body
[i
: i
+1] = insertion
996 def revert_inset_command(document
):
999 \begin_inset CommandInset InsetType
1002 \begin_inset LatexCommand cmd
1003 Some insets may end up being converted to insets earlier versions of LyX
1004 will not be able to recognize. Not sure what to do about that.
1008 i
= find_token(document
.body
, "\\begin_inset CommandInset", i
)
1011 nextline
= document
.body
[i
+1]
1012 r
= re
.compile(r
'LatexCommand\s+(.*)$')
1013 m
= r
.match(nextline
)
1015 document
.warning("Malformed LyX document: Missing LatexCommand in " + document
.body
[i
] + ".")
1018 cmdName
= m
.group(1)
1019 insertion
= ["\\begin_inset LatexCommand " + cmdName
]
1020 document
.body
[i
: i
+2] = insertion
1023 def convert_wrapfig_options(document
):
1024 "Convert optional options for wrap floats (wrapfig)."
1025 # adds the tokens "lines", "placement", and "overhang"
1028 i
= find_token(document
.body
, "\\begin_inset Wrap figure", i
)
1031 document
.body
.insert(i
+ 1, "lines 0")
1032 j
= find_token(document
.body
, "placement", i
)
1033 # placement can be already set or not; if not, set it
1035 document
.body
.insert(i
+ 3, "overhang 0col%")
1037 document
.body
.insert(i
+ 2, "placement o")
1038 document
.body
.insert(i
+ 3, "overhang 0col%")
1042 def revert_wrapfig_options(document
):
1043 "Revert optional options for wrap floats (wrapfig)."
1046 i
= find_token(document
.body
, "\\begin_inset Wrap figure", i
)
1049 j
= find_end_of_inset(document
.body
, i
)
1051 document
.warning("Can't find end of Wrap inset at line " + str(i
))
1054 k
= find_default_layout(document
, i
, j
)
1056 document
.warning("Can't find default layout for Wrap figure!")
1059 # Options should be between i and k now
1060 l
= find_token(document
.body
, "lines", i
, k
)
1062 document
.warning("Can't find lines option for Wrap figure!")
1065 m
= find_token(document
.body
, "overhang", i
+ 1, k
)
1067 document
.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
1070 # Do these in reverse order
1071 del document
.body
[m
]
1072 del document
.body
[l
]
1076 def convert_latexcommand_index(document
):
1077 "Convert from LatexCommand form to collapsable form."
1079 r1
= re
.compile('name "(.*)"')
1081 i
= find_token(document
.body
, "\\begin_inset CommandInset index", i
)
1084 if document
.body
[i
+ 1] != "LatexCommand index": # Might also be index_print
1087 j
= find_end_of_inset(document
.body
, i
+ 1)
1089 document
.warning("Unable to find end of index inset at line " + str(i
) + "!")
1092 m
= r1
.match(document
.body
[i
+ 2])
1094 document
.warning("Unable to match: " + document
.body
[i
+2])
1095 # this can happen with empty index insets!
1098 fullcontent
= m
.group(1)
1099 linelist
= latex2lyx(fullcontent
)
1100 #document.warning(fullcontent)
1102 linelist
= ["\\begin_inset Index", "status collapsed", "\\begin_layout Standard", ""] + \
1103 linelist
+ ["\\end_layout"]
1104 document
.body
[i
: j
] = linelist
1105 i
+= len(linelist
) - (j
- i
)
1108 def revert_latexcommand_index(document
):
1109 "Revert from collapsable form to LatexCommand form."
1112 i
= find_token(document
.body
, "\\begin_inset Index", i
)
1115 j
= find_end_of_inset(document
.body
, i
+ 1)
1119 content
= lyx2latex(document
, document
.body
[i
:j
])
1121 content
= content
.replace('"', r
'\"')
1122 document
.body
[i
:j
] = ["\\begin_inset CommandInset index", "LatexCommand index",
1123 "name " + '"' + content
+ '"', ""]
1127 def revert_wraptable(document
):
1128 "Revert wrap table to wrap figure."
1131 i
= find_token(document
.body
, "\\begin_inset Wrap table", i
)
1134 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
1138 def revert_vietnamese(document
):
1139 "Set language Vietnamese to English"
1140 # Set document language from Vietnamese to English
1142 if document
.language
== "vietnamese":
1143 document
.language
= "english"
1144 i
= find_token(document
.header
, "\\language", 0)
1146 document
.header
[i
] = "\\language english"
1149 j
= find_token(document
.body
, "\\lang vietnamese", j
)
1152 document
.body
[j
] = document
.body
[j
].replace("\\lang vietnamese", "\\lang english")
1156 def convert_japanese_cjk(document
):
1157 "Set language japanese to japanese-cjk"
1158 # Set document language from japanese-plain to japanese
1160 if document
.language
== "japanese":
1161 document
.language
= "japanese-cjk"
1162 i
= find_token(document
.header
, "\\language", 0)
1164 document
.header
[i
] = "\\language japanese-cjk"
1167 j
= find_token(document
.body
, "\\lang japanese", j
)
1170 document
.body
[j
] = document
.body
[j
].replace("\\lang japanese", "\\lang japanese-cjk")
1174 def revert_japanese(document
):
1175 "Set language japanese-plain to japanese"
1176 # Set document language from japanese-plain to japanese
1178 if document
.language
== "japanese-plain":
1179 document
.language
= "japanese"
1180 i
= find_token(document
.header
, "\\language", 0)
1182 document
.header
[i
] = "\\language japanese"
1185 j
= find_token(document
.body
, "\\lang japanese-plain", j
)
1188 document
.body
[j
] = document
.body
[j
].replace("\\lang japanese-plain", "\\lang japanese")
1192 def revert_japanese_cjk(document
):
1193 "Set language japanese-cjk to japanese"
1194 # Set document language from japanese-plain to japanese
1196 if document
.language
== "japanese-cjk":
1197 document
.language
= "japanese"
1198 i
= find_token(document
.header
, "\\language", 0)
1200 document
.header
[i
] = "\\language japanese"
1203 j
= find_token(document
.body
, "\\lang japanese-cjk", j
)
1206 document
.body
[j
] = document
.body
[j
].replace("\\lang japanese-cjk", "\\lang japanese")
1210 def revert_japanese_encoding(document
):
1211 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1212 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1214 i
= find_token(document
.header
, "\\inputencoding EUC-JP-plain", 0)
1216 document
.header
[i
] = "\\inputencoding EUC-JP"
1218 j
= find_token(document
.header
, "\\inputencoding JIS-plain", 0)
1220 document
.header
[j
] = "\\inputencoding JIS"
1222 k
= find_token(document
.header
, "\\inputencoding SJIS-plain", 0)
1223 if k
!= -1: # convert to UTF8 since there is currently no SJIS encoding
1224 document
.header
[k
] = "\\inputencoding UTF8"
1227 def revert_inset_info(document
):
1228 'Replace info inset with its content'
1231 i
= find_token(document
.body
, '\\begin_inset Info', i
)
1234 j
= find_end_of_inset(document
.body
, i
+ 1)
1237 document
.warning("Malformed LyX document: Could not find end of Info inset.")
1240 for k
in range(i
, j
+1):
1241 if document
.body
[k
].startswith("arg"):
1242 arg
= document
.body
[k
][3:].strip()
1243 # remove embracing quotation marks
1246 if arg
[len(arg
) - 1] == '"':
1247 arg
= arg
[:len(arg
) - 1]
1248 # \" to straight quote
1249 arg
= arg
.replace(r
'\"', '"')
1251 arg
= arg
.replace(r
'\\', "\\backslash\n")
1252 if document
.body
[k
].startswith("type"):
1253 type = document
.body
[k
][4:].strip().strip('"')
1254 # I think there is a newline after \\end_inset, which should be removed.
1255 if document
.body
[j
+ 1].strip() == "":
1256 document
.body
[i
: (j
+ 2)] = [type + ':' + arg
]
1258 document
.body
[i
: (j
+ 1)] = [type + ':' + arg
]
1261 def convert_pdf_options(document
):
1262 # Set the pdfusetitle tag, delete the pdf_store_options,
1263 # set quotes for bookmarksopenlevel"
1264 has_hr
= get_value(document
.header
, "\\use_hyperref", 0, default
= "0")
1266 k
= find_token(document
.header
, "\\use_hyperref", 0)
1267 document
.header
.insert(k
+ 1, "\\pdf_pdfusetitle true")
1268 k
= find_token(document
.header
, "\\pdf_store_options", 0)
1270 del document
.header
[k
]
1271 i
= find_token(document
.header
, "\\pdf_bookmarksopenlevel", k
)
1273 document
.header
[i
] = document
.header
[i
].replace('"', '')
1276 def revert_pdf_options_2(document
):
1277 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1278 k
= find_token(document
.header
, "\\use_hyperref", 0)
1279 i
= find_token(document
.header
, "\\pdf_pdfusetitle", k
)
1281 del document
.header
[i
]
1282 i
= find_token(document
.header
, "\\pdf_bookmarksopenlevel", k
)
1284 values
= document
.header
[i
].split()
1285 values
[1] = ' "' + values
[1] + '"'
1286 document
.header
[i
] = ''.join(values
)
1289 def convert_htmlurl(document
):
1290 'Convert "htmlurl" to "href" insets for docbook'
1291 if document
.backend
!= "docbook":
1295 i
= find_token(document
.body
, "\\begin_inset CommandInset url", i
)
1298 document
.body
[i
] = "\\begin_inset CommandInset href"
1299 document
.body
[i
+ 1] = "LatexCommand href"
1303 def convert_url(document
):
1304 'Convert url insets to url charstyles'
1305 if document
.backend
== "docbook":
1309 i
= find_token(document
.body
, "\\begin_inset CommandInset url", i
)
1312 n
= find_token(document
.body
, "name", i
)
1314 # place the URL name in typewriter before the new URL insert
1315 # grab the name 'bla' from the e.g. the line 'name "bla"',
1316 # therefore start with the 6th character
1317 name
= document
.body
[n
][6:-1]
1318 newname
= [name
+ " "]
1319 document
.body
[i
:i
] = newname
1321 j
= find_token(document
.body
, "target", i
)
1323 document
.warning("Malformed LyX document: Can't find target for url inset")
1326 target
= document
.body
[j
][8:-1]
1327 k
= find_token(document
.body
, "\\end_inset", j
)
1329 document
.warning("Malformed LyX document: Can't find end of url inset")
1332 newstuff
= ["\\begin_inset Flex URL",
1333 "status collapsed", "",
1334 "\\begin_layout Standard",
1339 document
.body
[i
:k
] = newstuff
1340 i
= i
+ len(newstuff
)
1342 def convert_ams_classes(document
):
1343 tc
= document
.textclass
1344 if (tc
!= "amsart" and tc
!= "amsart-plain" and
1345 tc
!= "amsart-seq" and tc
!= "amsbook"):
1347 if tc
== "amsart-plain":
1348 document
.textclass
= "amsart"
1349 document
.set_textclass()
1350 document
.add_module("Theorems (Starred)")
1352 if tc
== "amsart-seq":
1353 document
.textclass
= "amsart"
1354 document
.set_textclass()
1355 document
.add_module("Theorems (AMS)")
1357 #Now we want to see if any of the environments in the extended theorems
1358 #module were used in this document. If so, we'll add that module, too.
1359 layouts
= ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1360 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1363 r
= re
.compile(r
'^\\begin_layout (.*?)\*?\s*$')
1366 i
= find_token(document
.body
, "\\begin_layout", i
)
1369 m
= r
.match(document
.body
[i
])
1371 # This is an empty layout
1372 # document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1376 if layouts
.count(m
) != 0:
1377 document
.add_module("Theorems (AMS-Extended)")
1381 def revert_href(document
):
1382 'Reverts hyperlink insets (href) to url insets (url)'
1385 i
= find_token(document
.body
, "\\begin_inset CommandInset href", i
)
1388 document
.body
[i
: i
+ 2] = \
1389 ["\\begin_inset CommandInset url", "LatexCommand url"]
1392 def revert_url(document
):
1393 'Reverts Flex URL insets to old-style URL insets'
1396 i
= find_token(document
.body
, "\\begin_inset Flex URL", i
)
1399 j
= find_end_of_inset(document
.body
, i
)
1401 document
.warning("Can't find end of inset in revert_url!")
1403 k
= find_default_layout(document
, i
, j
)
1405 document
.warning("Can't find default layout in revert_url!")
1408 l
= find_end_of(document
.body
, k
, "\\begin_layout", "\\end_layout")
1409 if l
== -1 or l
>= j
:
1410 document
.warning("Can't find end of default layout in revert_url!")
1413 # OK, so the inset's data is between lines k and l.
1414 data
= " ".join(document
.body
[k
+1:l
])
1416 newinset
= ["\\begin_inset LatexCommand url", "target \"" + data
+ "\"",\
1418 document
.body
[i
:j
+1] = newinset
1419 i
= i
+ len(newinset
)
1422 def convert_include(document
):
1423 'Converts include insets to new format.'
1425 r
= re
.compile(r
'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1427 i
= find_token(document
.body
, "\\begin_inset Include", i
)
1430 line
= document
.body
[i
]
1431 previewline
= document
.body
[i
+ 1]
1434 document
.warning("Unable to match line " + str(i
) + " of body!")
1440 insertion
= ["\\begin_inset CommandInset include",
1441 "LatexCommand " + cmd
, previewline
,
1442 "filename \"" + fn
+ "\""]
1445 insertion
.append("lstparams " + '"' + opt
+ '"')
1447 document
.body
[i
: i
+ 2] = insertion
1451 def revert_include(document
):
1452 'Reverts include insets to old format.'
1454 r0
= re
.compile('preview.*')
1455 r1
= re
.compile('LatexCommand (.+)')
1456 r2
= re
.compile('filename "(.+)"')
1457 r3
= re
.compile('lstparams "(.*)"')
1459 i
= find_token(document
.body
, "\\begin_inset CommandInset include", i
)
1463 m
= r1
.match(document
.body
[nextline
])
1465 document
.warning("Malformed LyX document: No LatexCommand line for `" +
1466 document
.body
[i
] + "' on line " + str(i
) + ".")
1471 if r0
.match(document
.body
[nextline
]):
1472 previewline
= document
.body
[nextline
]
1476 m
= r2
.match(document
.body
[nextline
])
1478 document
.warning("Malformed LyX document: No filename line for `" + \
1479 document
.body
[i
] + "' on line " + str(i
) + ".")
1485 if (cmd
== "lstinputlisting"):
1486 m
= r3
.match(document
.body
[nextline
])
1488 options
= m
.group(1)
1491 newline
= "\\begin_inset Include \\" + cmd
+ "{" + fn
+ "}"
1493 newline
+= ("[" + options
+ "]")
1494 insertion
= [newline
]
1495 if previewline
!= "":
1496 insertion
.append(previewline
)
1497 document
.body
[i
: nextline
] = insertion
1501 def revert_albanian(document
):
1502 "Set language Albanian to English"
1504 if document
.language
== "albanian":
1505 document
.language
= "english"
1506 i
= find_token(document
.header
, "\\language", 0)
1508 document
.header
[i
] = "\\language english"
1511 j
= find_token(document
.body
, "\\lang albanian", j
)
1514 document
.body
[j
] = document
.body
[j
].replace("\\lang albanian", "\\lang english")
1518 def revert_lowersorbian(document
):
1519 "Set language lower Sorbian to English"
1521 if document
.language
== "lowersorbian":
1522 document
.language
= "english"
1523 i
= find_token(document
.header
, "\\language", 0)
1525 document
.header
[i
] = "\\language english"
1528 j
= find_token(document
.body
, "\\lang lowersorbian", j
)
1531 document
.body
[j
] = document
.body
[j
].replace("\\lang lowersorbian", "\\lang english")
1535 def revert_uppersorbian(document
):
1536 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1538 if document
.language
== "uppersorbian":
1539 document
.language
= "usorbian"
1540 i
= find_token(document
.header
, "\\language", 0)
1542 document
.header
[i
] = "\\language usorbian"
1545 j
= find_token(document
.body
, "\\lang uppersorbian", j
)
1548 document
.body
[j
] = document
.body
[j
].replace("\\lang uppersorbian", "\\lang usorbian")
1552 def convert_usorbian(document
):
1553 "Set language usorbian to uppersorbian"
1555 if document
.language
== "usorbian":
1556 document
.language
= "uppersorbian"
1557 i
= find_token(document
.header
, "\\language", 0)
1559 document
.header
[i
] = "\\language uppersorbian"
1562 j
= find_token(document
.body
, "\\lang usorbian", j
)
1565 document
.body
[j
] = document
.body
[j
].replace("\\lang usorbian", "\\lang uppersorbian")
1569 def convert_macro_global(document
):
1570 "Remove TeX code command \global when it is in front of a macro"
1571 # math macros are nowadays already defined \global, so that an additional
1572 # \global would make the document uncompilable, see
1573 # http://bugzilla.lyx.org/show_bug.cgi?id=5371
1574 # We're looking for something like this:
1578 # \begin_layout Plain Layout
1588 # \begin_inset FormulaMacro
1589 # \renewcommand{\foo}{123}
1593 i
= find_token(document
.body
, "\\begin_inset FormulaMacro", i
)
1596 # if i <= 13, then there isn't enough room for the ERT
1600 if document
.body
[i
-6] == "global":
1601 del document
.body
[i
-13 : i
]
1607 def revert_macro_optional_params(document
):
1608 "Convert macro definitions with optional parameters into ERTs"
1609 # Stub to convert macro definitions with one or more optional parameters
1610 # into uninterpreted ERT insets
1613 def revert_hyperlinktype(document
):
1614 'Reverts hyperlink type'
1618 i
= find_token(document
.body
, "target", i
)
1621 j
= find_token(document
.body
, "type", i
)
1625 del document
.body
[j
]
1629 def revert_pagebreak(document
):
1630 'Reverts pagebreak to ERT'
1633 i
= find_token(document
.body
, "\\pagebreak", i
)
1636 document
.body
[i
] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1637 '\\begin_layout Standard\n\n\n\\backslash\n' \
1638 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1642 def revert_linebreak(document
):
1643 'Reverts linebreak to ERT'
1646 i
= find_token(document
.body
, "\\linebreak", i
)
1649 document
.body
[i
] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1650 '\\begin_layout Standard\n\n\n\\backslash\n' \
1651 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1655 def revert_latin(document
):
1656 "Set language Latin to English"
1658 if document
.language
== "latin":
1659 document
.language
= "english"
1660 i
= find_token(document
.header
, "\\language", 0)
1662 document
.header
[i
] = "\\language english"
1665 j
= find_token(document
.body
, "\\lang latin", j
)
1668 document
.body
[j
] = document
.body
[j
].replace("\\lang latin", "\\lang english")
1672 def revert_samin(document
):
1673 "Set language North Sami to English"
1675 if document
.language
== "samin":
1676 document
.language
= "english"
1677 i
= find_token(document
.header
, "\\language", 0)
1679 document
.header
[i
] = "\\language english"
1682 j
= find_token(document
.body
, "\\lang samin", j
)
1685 document
.body
[j
] = document
.body
[j
].replace("\\lang samin", "\\lang english")
1689 def convert_serbocroatian(document
):
1690 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1692 if document
.language
== "serbocroatian":
1693 document
.language
= "croatian"
1694 i
= find_token(document
.header
, "\\language", 0)
1696 document
.header
[i
] = "\\language croatian"
1699 j
= find_token(document
.body
, "\\lang serbocroatian", j
)
1702 document
.body
[j
] = document
.body
[j
].replace("\\lang serbocroatian", "\\lang croatian")
1706 def convert_framed_notes(document
):
1707 "Convert framed notes to boxes. "
1710 i
= find_tokens(document
.body
, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i
)
1713 subst
= [document
.body
[i
].replace("\\begin_inset Note", "\\begin_inset Box"),
1722 'height_special "totalheight"']
1723 document
.body
[i
:i
+1] = subst
1727 def convert_module_names(document
):
1728 modulemap
= { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1729 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1730 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1731 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1732 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1733 modlist
= document
.get_module_list()
1734 if len(modlist
) == 0:
1738 if modulemap
.has_key(mod
):
1739 newmodlist
.append(modulemap
[mod
])
1741 document
.warning("Can't find module %s in the module map!" % mod
)
1742 newmodlist
.append(mod
)
1743 document
.set_module_list(newmodlist
)
1746 def revert_module_names(document
):
1747 modulemap
= { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1748 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1749 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1750 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1751 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1752 modlist
= document
.get_module_list()
1753 if len(modlist
) == 0:
1757 if modulemap
.has_key(mod
):
1758 newmodlist
.append(modulemap
[mod
])
1760 document
.warning("Can't find module %s in the module map!" % mod
)
1761 newmodlist
.append(mod
)
1762 document
.set_module_list(newmodlist
)
1765 def revert_colsep(document
):
1766 i
= find_token(document
.header
, "\\columnsep", 0)
1769 colsepline
= document
.header
[i
]
1770 r
= re
.compile(r
'\\columnsep (.*)')
1771 m
= r
.match(colsepline
)
1773 document
.warning("Malformed column separation line!")
1776 del document
.header
[i
]
1777 #it seems to be safe to add the package even if it is already used
1778 pretext
= ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep
+ "}"]
1780 add_to_preamble(document
, pretext
)
1783 def revert_framed_notes(document
):
1784 "Revert framed boxes to notes. "
1787 i
= find_tokens(document
.body
, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i
)
1791 j
= find_end_of_inset(document
.body
, i
+ 1)
1794 document
.warning("Malformed LyX document: Could not find end of Box inset.")
1795 k
= find_token(document
.body
, "status", i
+ 1, j
)
1797 document
.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1799 status
= document
.body
[k
]
1800 l
= find_default_layout(document
, i
+ 1, j
)
1802 document
.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1804 m
= find_token(document
.body
, "\\end_layout", i
+ 1, j
)
1806 document
.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1808 ibox
= find_token(document
.body
, "has_inner_box 1", i
+ 1, k
)
1809 pbox
= find_token(document
.body
, "use_parbox 1", i
+ 1, k
)
1810 if ibox
== -1 and pbox
== -1:
1811 document
.body
[i
] = document
.body
[i
].replace("\\begin_inset Box", "\\begin_inset Note")
1812 del document
.body
[i
+1:k
]
1814 document
.body
[i
] = document
.body
[i
].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1815 subst1
= [document
.body
[l
],
1816 "\\begin_inset Note Shaded",
1818 '\\begin_layout Standard']
1819 document
.body
[l
:l
+ 1] = subst1
1820 subst2
= [document
.body
[m
], "\\end_layout", "\\end_inset"]
1821 document
.body
[m
:m
+ 1] = subst2
1825 def revert_slash(document
):
1826 'Revert \\SpecialChar \\slash{} to ERT'
1828 while i
< len(document
.body
):
1829 m
= re
.match(r
'(.*)\\SpecialChar \\slash{}(.*)', document
.body
[i
])
1834 '\\begin_inset ERT',
1835 'status collapsed', '',
1836 '\\begin_layout Standard',
1837 '', '', '\\backslash',
1842 document
.body
[i
: i
+1] = subst
1848 def revert_nobreakdash(document
):
1849 'Revert \\SpecialChar \\nobreakdash- to ERT'
1851 while i
< len(document
.body
):
1852 m
= re
.match(r
'(.*)\\SpecialChar \\nobreakdash-(.*)', document
.body
[i
])
1857 '\\begin_inset ERT',
1858 'status collapsed', '',
1859 '\\begin_layout Standard', '', '',
1865 document
.body
[i
: i
+1] = subst
1867 j
= find_token(document
.header
, "\\use_amsmath", 0)
1869 document
.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1871 document
.header
[j
] = "\\use_amsmath 2"
1876 #Returns number of lines added/removed
1877 def revert_nocite_key(body
, start
, end
):
1878 'key "..." -> \nocite{...}'
1879 r
= re
.compile(r
'^key "(.*)"')
1883 m
= r
.match(body
[i
])
1885 body
[i
:i
+1] = ["\\backslash", "nocite{" + m
.group(1) + "}"]
1886 j
+= 1 # because we added a line
1887 i
+= 2 # skip that line
1890 j
-= 1 # because we deleted a line
1891 # no need to change i, since it now points to the next line
1895 def revert_nocite(document
):
1896 "Revert LatexCommand nocite to ERT"
1899 i
= find_token(document
.body
, "\\begin_inset CommandInset citation", i
)
1902 if (document
.body
[i
+1] != "LatexCommand nocite"):
1903 # note that we already incremented i
1906 insetEnd
= find_end_of_inset(document
.body
, i
)
1908 #this should not happen
1909 document
.warning("End of CommandInset citation not found in revert_nocite!")
1912 paramLocation
= i
+ 2 #start of the inset's parameters
1914 document
.body
[i
:i
+2] = \
1915 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1916 # that added two lines
1919 #print insetEnd, document.body[i: insetEnd + 1]
1920 insetEnd
+= revert_nocite_key(document
.body
, paramLocation
, insetEnd
)
1921 #print insetEnd, document.body[i: insetEnd + 1]
1922 document
.body
.insert(insetEnd
, "\\end_layout")
1923 document
.body
.insert(insetEnd
+ 1, "")
1927 def revert_btprintall(document
):
1928 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1929 i
= find_token(document
.header
, '\\use_bibtopic', 0)
1931 document
.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1933 if get_value(document
.header
, '\\use_bibtopic', 0) == "false":
1935 while i
< len(document
.body
):
1936 i
= find_token(document
.body
, "\\begin_inset CommandInset bibtex", i
)
1939 j
= find_end_of_inset(document
.body
, i
+ 1)
1941 #this should not happen
1942 document
.warning("End of CommandInset bibtex not found in revert_btprintall!")
1943 j
= len(document
.body
)
1944 # this range isn't really right, but it should be OK, since we shouldn't
1945 # see more than one matching line in each inset
1947 for k
in range(i
, j
):
1948 if (document
.body
[k
] == 'btprint "btPrintAll"'):
1949 del document
.body
[k
]
1950 subst
= ["\\begin_inset ERT",
1951 "status collapsed", "",
1952 "\\begin_layout Standard", "",
1957 document
.body
[i
:i
] = subst
1958 addlines
= addedlines
+ len(subst
) - 1
1962 def revert_bahasam(document
):
1963 "Set language Bahasa Malaysia to Bahasa Indonesia"
1965 if document
.language
== "bahasam":
1966 document
.language
= "bahasa"
1967 i
= find_token(document
.header
, "\\language", 0)
1969 document
.header
[i
] = "\\language bahasa"
1972 j
= find_token(document
.body
, "\\lang bahasam", j
)
1975 document
.body
[j
] = document
.body
[j
].replace("\\lang bahasam", "\\lang bahasa")
1979 def revert_interlingua(document
):
1980 "Set language Interlingua to English"
1982 if document
.language
== "interlingua":
1983 document
.language
= "english"
1984 i
= find_token(document
.header
, "\\language", 0)
1986 document
.header
[i
] = "\\language english"
1989 j
= find_token(document
.body
, "\\lang interlingua", j
)
1992 document
.body
[j
] = document
.body
[j
].replace("\\lang interlingua", "\\lang english")
1996 def revert_serbianlatin(document
):
1997 "Set language Serbian-Latin to Croatian"
1999 if document
.language
== "serbian-latin":
2000 document
.language
= "croatian"
2001 i
= find_token(document
.header
, "\\language", 0)
2003 document
.header
[i
] = "\\language croatian"
2006 j
= find_token(document
.body
, "\\lang serbian-latin", j
)
2009 document
.body
[j
] = document
.body
[j
].replace("\\lang serbian-latin", "\\lang croatian")
2013 def revert_rotfloat(document
):
2014 " Revert sideways custom floats. "
2017 # whitespace intended (exclude \\begin_inset FloatList)
2018 i
= find_token(document
.body
, "\\begin_inset Float ", i
)
2021 line
= document
.body
[i
]
2022 r
= re
.compile(r
'\\begin_inset Float (.*)$')
2025 document
.warning("Unable to match line " + str(i
) + " of body!")
2028 floattype
= m
.group(1)
2029 if floattype
== "figure" or floattype
== "table":
2032 j
= find_end_of_inset(document
.body
, i
)
2034 document
.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
2038 if get_value(document
.body
, 'sideways', i
, j
) == "false":
2041 l
= find_default_layout(document
, i
+ 1, j
)
2043 document
.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2045 subst
= ['\\begin_layout Standard',
2046 '\\begin_inset ERT',
2047 'status collapsed', '',
2048 '\\begin_layout Standard', '', '',
2050 'end{sideways' + floattype
+ '}',
2051 '\\end_layout', '', '\\end_inset']
2052 document
.body
[j
: j
+1] = subst
2053 addedLines
= len(subst
) - 1
2054 del document
.body
[i
+1 : l
]
2055 addedLines
-= (l
-1) - (i
+1)
2056 subst
= ['\\begin_inset ERT', 'status collapsed', '',
2057 '\\begin_layout Standard', '', '', '\\backslash',
2058 'begin{sideways' + floattype
+ '}',
2059 '\\end_layout', '', '\\end_inset', '',
2061 document
.body
[i
: i
+1] = subst
2062 addedLines
+= len(subst
) - 1
2063 if floattype
== "algorithm":
2064 add_to_preamble(document
,
2065 ['% Commands inserted by lyx2lyx for sideways algorithm float',
2066 '\\usepackage{rotfloat}',
2067 '\\floatstyle{ruled}',
2068 '\\newfloat{algorithm}{tbp}{loa}',
2069 '\\floatname{algorithm}{Algorithm}'])
2071 document
.warning("Cannot create preamble definition for custom float" + floattype
+ ".")
2075 def revert_widesideways(document
):
2076 " Revert wide sideways floats. "
2079 # whitespace intended (exclude \\begin_inset FloatList)
2080 i
= find_token(document
.body
, '\\begin_inset Float ', i
)
2083 line
= document
.body
[i
]
2084 r
= re
.compile(r
'\\begin_inset Float (.*)$')
2087 document
.warning("Unable to match line " + str(i
) + " of body!")
2090 floattype
= m
.group(1)
2091 if floattype
!= "figure" and floattype
!= "table":
2094 j
= find_end_of_inset(document
.body
, i
)
2096 document
.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
2099 if get_value(document
.body
, 'sideways', i
, j
) == "false" or \
2100 get_value(document
.body
, 'wide', i
, j
) == "false":
2103 l
= find_default_layout(document
, i
+ 1, j
)
2105 document
.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2107 subst
= ['\\begin_layout Standard', '\\begin_inset ERT',
2108 'status collapsed', '',
2109 '\\begin_layout Standard', '', '', '\\backslash',
2110 'end{sideways' + floattype
+ '*}',
2111 '\\end_layout', '', '\\end_inset']
2112 document
.body
[j
: j
+1] = subst
2113 addedLines
= len(subst
) - 1
2114 del document
.body
[i
+1:l
-1]
2115 addedLines
-= (l
-1) - (i
+1)
2116 subst
= ['\\begin_inset ERT', 'status collapsed', '',
2117 '\\begin_layout Standard', '', '', '\\backslash',
2118 'begin{sideways' + floattype
+ '*}', '\\end_layout', '',
2119 '\\end_inset', '', '\\end_layout', '']
2120 document
.body
[i
: i
+1] = subst
2121 addedLines
+= len(subst
) - 1
2122 add_to_preamble(document
, ['\\usepackage{rotfloat}\n'])
2126 def revert_inset_embedding(document
, type):
2127 ' Remove embed tag from certain type of insets'
2130 i
= find_token(document
.body
, "\\begin_inset %s" % type, i
)
2133 j
= find_end_of_inset(document
.body
, i
)
2135 document
.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
2138 k
= find_token(document
.body
, "\tembed", i
, j
)
2140 k
= find_token(document
.body
, "embed", i
, j
)
2142 del document
.body
[k
]
2146 def revert_external_embedding(document
):
2147 ' Remove embed tag from external inset '
2148 revert_inset_embedding(document
, 'External')
2151 def convert_subfig(document
):
2152 " Convert subfigures to subfloats. "
2156 i
= find_token(document
.body
, '\\begin_inset Graphics', i
)
2159 endInset
= find_end_of_inset(document
.body
, i
)
2161 document
.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
2164 k
= find_token(document
.body
, '\tsubcaption', i
, endInset
)
2168 l
= find_token(document
.body
, '\tsubcaptionText', i
, endInset
)
2172 caption
= document
.body
[l
][16:].strip('"')
2173 del document
.body
[l
]
2175 del document
.body
[k
]
2177 subst
= ['\\begin_inset Float figure', 'wide false', 'sideways false',
2178 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
2179 '', '\\begin_layout Plain Layout'] + latex2lyx(caption
) + \
2180 [ '\\end_layout', '', '\\end_inset', '',
2181 '\\end_layout', '', '\\begin_layout Plain Layout']
2182 document
.body
[i
: i
] = subst
2183 addedLines
+= len(subst
)
2184 endInset
+= addedLines
2185 subst
= ['', '\\end_inset', '', '\\end_layout']
2186 document
.body
[endInset
: endInset
] = subst
2187 addedLines
+= len(subst
)
2191 def revert_subfig(document
):
2192 " Revert subfloats. "
2195 # whitespace intended (exclude \\begin_inset FloatList)
2196 i
= find_tokens(document
.body
, ['\\begin_inset Float ', '\\begin_inset Wrap'], i
)
2202 j
= find_end_of_inset(document
.body
, i
)
2204 document
.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i
+ len(document
.header
)) + ".\n\t" + document
.body
[i
])
2205 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
2207 continue # this will get us back to the outer loop, since j == -1
2208 # look for embedded float (= subfloat)
2209 # whitespace intended (exclude \\begin_inset FloatList)
2210 k
= find_token(document
.body
, '\\begin_inset Float ', i
+ 1, j
)
2213 # is the subfloat aligned?
2214 al
= find_token(document
.body
, '\\align ', k
- 1, j
)
2218 if get_value(document
.body
, '\\align', al
) == "center":
2219 alignment_beg
= "\\backslash\nbegin{centering}"
2220 alignment_end
= "\\backslash\npar\\backslash\nend{centering}"
2221 elif get_value(document
.body
, '\\align', al
) == "left":
2222 alignment_beg
= "\\backslash\nbegin{raggedright}"
2223 alignment_end
= "\\backslash\npar\\backslash\nend{raggedright}"
2224 elif get_value(document
.body
, '\\align', al
) == "right":
2225 alignment_beg
= "\\backslash\nbegin{raggedleft}"
2226 alignment_end
= "\\backslash\npar\\backslash\nend{raggedleft}"
2227 l
= find_end_of_inset(document
.body
, k
)
2229 document
.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
2232 continue # escape to the outer loop
2233 m
= find_default_layout(document
, k
+ 1, l
)
2235 cap
= find_token(document
.body
, '\\begin_inset Caption', k
+ 1, l
)
2240 capend
= find_end_of_inset(document
.body
, cap
)
2242 document
.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
2246 lbl
= find_token(document
.body
, '\\begin_inset CommandInset label', cap
, capend
)
2248 lblend
= find_end_of_inset(document
.body
, lbl
+ 1)
2250 document
.warning("Malformed lyx document: Missing '\\end_inset' (label).")
2252 for line
in document
.body
[lbl
:lblend
+ 1]:
2253 if line
.startswith('name '):
2254 label
= line
.split()[1].strip('"')
2261 opt
= find_token(document
.body
, '\\begin_inset OptArg', cap
, capend
)
2263 optend
= find_end_of_inset(document
.body
, opt
)
2265 document
.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2267 optc
= find_default_layout(document
, opt
, optend
)
2269 document
.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2271 optcend
= find_end_of(document
.body
, optc
, "\\begin_layout", "\\end_layout")
2272 for line
in document
.body
[optc
:optcend
]:
2273 if not line
.startswith('\\'):
2274 shortcap
+= line
.strip()
2278 for line
in document
.body
[cap
:capend
]:
2279 if line
in document
.body
[lbl
:lblend
]:
2281 elif line
in document
.body
[opt
:optend
]:
2285 caption
+= lyxline2latex(document
, line
, inert
)
2287 caption
+= "\n\\backslash\nlabel{" + label
+ "}"
2288 subst
= '\\begin_layout PlainLayout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2289 '\\begin_layout PlainLayout\n\n}' + alignment_end
+ \
2290 '\n\\end_layout\n\n\\end_inset\n\n' \
2291 '\\end_layout\n\n\\begin_layout PlainLayout\n'
2292 subst
= subst
.split('\n')
2293 document
.body
[l
: l
+1] = subst
2294 addedLines
= len(subst
) - 1
2295 # this is before l and so is unchanged by the multiline insertion
2297 del document
.body
[cap
:capend
+1]
2298 addedLines
-= (capend
+ 1 - cap
)
2299 del document
.body
[k
+1:m
-1]
2300 addedLines
-= (m
- 1 - (k
+ 1))
2301 insertion
= '\\begin_inset ERT\nstatus collapsed\n\n' \
2302 '\\begin_layout PlainLayout\n\n' + alignment_beg
+ '\n\\backslash\n' \
2304 if len(shortcap
) > 0:
2305 insertion
= insertion
+ "[" + shortcap
+ "]"
2306 if len(caption
) > 0:
2307 insertion
= insertion
+ "[" + caption
+ "]"
2308 insertion
= insertion
+ '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2309 insertion
= insertion
.split('\n')
2310 document
.body
[k
: k
+ 1] = insertion
2311 addedLines
+= len(insertion
) - 1
2312 al
= find_token(document
.body
, '\\align ', k
- 1, j
+ addedLines
)
2314 del document
.body
[al
]
2316 add_to_preamble(document
, ['\\usepackage{subfig}\n'])
2320 def revert_wrapplacement(document
):
2321 " Revert placement options wrap floats (wrapfig). "
2324 i
= find_token(document
.body
, "\\begin_inset Wrap figure", i
)
2327 e
= find_end_of_inset(document
.body
, i
)
2328 j
= find_token(document
.body
, "placement", i
+ 1, e
)
2330 document
.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2333 r
= re
.compile("placement (o|i|l|r|O|I|L|R)")
2334 m
= r
.match(document
.body
[j
])
2336 document
.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2338 document
.body
[j
] = "placement " + m
.group(1).lower()
2342 def remove_extra_embedded_files(document
):
2343 " Remove \extra_embedded_files from buffer params "
2344 i
= find_token(document
.header
, '\\extra_embedded_files', 0)
2347 document
.header
.pop(i
)
2350 def convert_spaceinset(document
):
2351 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2353 while i
< len(document
.body
):
2354 m
= re
.match(r
'(.*)\\InsetSpace (.*)', document
.body
[i
])
2358 subst
= [before
, "\\begin_inset Space " + after
, "\\end_inset"]
2359 document
.body
[i
: i
+1] = subst
2365 def revert_spaceinset(document
):
2366 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2369 i
= find_token(document
.body
, "\\begin_inset Space", i
)
2372 j
= find_end_of_inset(document
.body
, i
)
2374 document
.warning("Malformed LyX document: Could not find end of space inset.")
2376 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Space', '\\InsetSpace')
2377 del document
.body
[j
]
2380 def convert_hfill(document
):
2381 " Convert hfill to space inset "
2384 i
= find_token(document
.body
, "\\hfill", i
)
2387 subst
= document
.body
[i
].replace('\\hfill', \
2388 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2389 subst
= subst
.split('\n')
2390 document
.body
[i
: i
+1] = subst
2394 def revert_hfills(document
):
2395 ' Revert \\hfill commands '
2396 hfill
= re
.compile(r
'\\hfill')
2397 dotfill
= re
.compile(r
'\\dotfill')
2398 hrulefill
= re
.compile(r
'\\hrulefill')
2401 i
= find_token(document
.body
, "\\InsetSpace", i
)
2404 if hfill
.search(document
.body
[i
]):
2405 document
.body
[i
] = \
2406 document
.body
[i
].replace('\\InsetSpace \\hfill{}', '\\hfill')
2409 if dotfill
.search(document
.body
[i
]):
2410 subst
= document
.body
[i
].replace('\\InsetSpace \\dotfill{}', \
2411 '\\begin_inset ERT\nstatus collapsed\n\n' \
2412 '\\begin_layout Standard\n\n\n\\backslash\n' \
2413 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2414 subst
= subst
.split('\n')
2415 document
.body
[i
: i
+1] = subst
2418 if hrulefill
.search(document
.body
[i
]):
2419 subst
= document
.body
[i
].replace('\\InsetSpace \\hrulefill{}', \
2420 '\\begin_inset ERT\nstatus collapsed\n\n' \
2421 '\\begin_layout Standard\n\n\n\\backslash\n' \
2422 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2423 subst
= subst
.split('\n')
2424 document
.body
[i
: i
+1] = subst
2429 def revert_hspace(document
):
2430 ' Revert \\InsetSpace \\hspace{} to ERT '
2432 hspace
= re
.compile(r
'\\hspace{}')
2433 hstar
= re
.compile(r
'\\hspace\*{}')
2435 i
= find_token(document
.body
, "\\InsetSpace \\hspace", i
)
2438 length
= get_value(document
.body
, '\\length', i
+1)
2440 document
.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2442 del document
.body
[i
+1]
2444 if hstar
.search(document
.body
[i
]):
2445 subst
= document
.body
[i
].replace('\\InsetSpace \\hspace*{}', \
2446 '\\begin_inset ERT\nstatus collapsed\n\n' \
2447 '\\begin_layout Standard\n\n\n\\backslash\n' \
2448 'hspace*{' + length
+ '}\n\\end_layout\n\n\\end_inset\n\n')
2449 subst
= subst
.split('\n')
2450 document
.body
[i
: i
+1] = subst
2451 addedLines
+= len(subst
) - 1
2454 if hspace
.search(document
.body
[i
]):
2455 subst
= document
.body
[i
].replace('\\InsetSpace \\hspace{}', \
2456 '\\begin_inset ERT\nstatus collapsed\n\n' \
2457 '\\begin_layout Standard\n\n\n\\backslash\n' \
2458 'hspace{' + length
+ '}\n\\end_layout\n\n\\end_inset\n\n')
2459 subst
= subst
.split('\n')
2460 document
.body
[i
: i
+1] = subst
2461 addedLines
+= len(subst
) - 1
2467 def revert_protected_hfill(document
):
2468 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2471 i
= find_token(document
.body
, '\\begin_inset Space \\hspace*{\\fill}', i
)
2474 j
= find_end_of_inset(document
.body
, i
)
2476 document
.warning("Malformed LyX document: Could not find end of space inset.")
2478 del document
.body
[j
]
2479 subst
= document
.body
[i
].replace('\\begin_inset Space \\hspace*{\\fill}', \
2480 '\\begin_inset ERT\nstatus collapsed\n\n' \
2481 '\\begin_layout Standard\n\n\n\\backslash\n' \
2482 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2483 subst
= subst
.split('\n')
2484 document
.body
[i
: i
+1] = subst
2488 def revert_leftarrowfill(document
):
2489 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2492 i
= find_token(document
.body
, '\\begin_inset Space \\leftarrowfill{}', i
)
2495 j
= find_end_of_inset(document
.body
, i
)
2497 document
.warning("Malformed LyX document: Could not find end of space inset.")
2499 del document
.body
[j
]
2500 subst
= document
.body
[i
].replace('\\begin_inset Space \\leftarrowfill{}', \
2501 '\\begin_inset ERT\nstatus collapsed\n\n' \
2502 '\\begin_layout Standard\n\n\n\\backslash\n' \
2503 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2504 subst
= subst
.split('\n')
2505 document
.body
[i
: i
+1] = subst
2509 def revert_rightarrowfill(document
):
2510 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2513 i
= find_token(document
.body
, '\\begin_inset Space \\rightarrowfill{}', i
)
2516 j
= find_end_of_inset(document
.body
, i
)
2518 document
.warning("Malformed LyX document: Could not find end of space inset.")
2520 del document
.body
[j
]
2521 subst
= document
.body
[i
].replace('\\begin_inset Space \\rightarrowfill{}', \
2522 '\\begin_inset ERT\nstatus collapsed\n\n' \
2523 '\\begin_layout Standard\n\n\n\\backslash\n' \
2524 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2525 subst
= subst
.split('\n')
2526 document
.body
[i
: i
+1] = subst
2530 def revert_upbracefill(document
):
2531 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2534 i
= find_token(document
.body
, '\\begin_inset Space \\upbracefill{}', i
)
2537 j
= find_end_of_inset(document
.body
, i
)
2539 document
.warning("Malformed LyX document: Could not find end of space inset.")
2541 del document
.body
[j
]
2542 subst
= document
.body
[i
].replace('\\begin_inset Space \\upbracefill{}', \
2543 '\\begin_inset ERT\nstatus collapsed\n\n' \
2544 '\\begin_layout Standard\n\n\n\\backslash\n' \
2545 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2546 subst
= subst
.split('\n')
2547 document
.body
[i
: i
+1] = subst
2551 def revert_downbracefill(document
):
2552 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2555 i
= find_token(document
.body
, '\\begin_inset Space \\downbracefill{}', i
)
2558 j
= find_end_of_inset(document
.body
, i
)
2560 document
.warning("Malformed LyX document: Could not find end of space inset.")
2562 del document
.body
[j
]
2563 subst
= document
.body
[i
].replace('\\begin_inset Space \\downbracefill{}', \
2564 '\\begin_inset ERT\nstatus collapsed\n\n' \
2565 '\\begin_layout Standard\n\n\n\\backslash\n' \
2566 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2567 subst
= subst
.split('\n')
2568 document
.body
[i
: i
+1] = subst
2572 def revert_local_layout(document
):
2573 ' Revert local layout headers.'
2576 i
= find_token(document
.header
, "\\begin_local_layout", i
)
2579 j
= find_end_of(document
.header
, i
, "\\begin_local_layout", "\\end_local_layout")
2581 # this should not happen
2583 document
.header
[i
: j
+ 1] = []
2586 def convert_pagebreaks(document
):
2587 ' Convert inline Newpage insets to new format '
2590 i
= find_token(document
.body
, '\\newpage', i
)
2593 document
.body
[i
:i
+1] = ['\\begin_inset Newpage newpage',
2597 i
= find_token(document
.body
, '\\pagebreak', i
)
2600 document
.body
[i
:i
+1] = ['\\begin_inset Newpage pagebreak',
2604 i
= find_token(document
.body
, '\\clearpage', i
)
2607 document
.body
[i
:i
+1] = ['\\begin_inset Newpage clearpage',
2611 i
= find_token(document
.body
, '\\cleardoublepage', i
)
2614 document
.body
[i
:i
+1] = ['\\begin_inset Newpage cleardoublepage',
2618 def revert_pagebreaks(document
):
2619 ' Revert \\begin_inset Newpage to previous inline format '
2622 i
= find_token(document
.body
, '\\begin_inset Newpage', i
)
2625 j
= find_end_of_inset(document
.body
, i
)
2627 document
.warning("Malformed LyX document: Could not find end of Newpage inset.")
2629 del document
.body
[j
]
2630 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Newpage newpage', '\\newpage')
2631 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2632 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2633 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2636 def convert_linebreaks(document
):
2637 ' Convert inline Newline insets to new format '
2640 i
= find_token(document
.body
, '\\newline', i
)
2643 document
.body
[i
:i
+1] = ['\\begin_inset Newline newline',
2647 i
= find_token(document
.body
, '\\linebreak', i
)
2650 document
.body
[i
:i
+1] = ['\\begin_inset Newline linebreak',
2654 def revert_linebreaks(document
):
2655 ' Revert \\begin_inset Newline to previous inline format '
2658 i
= find_token(document
.body
, '\\begin_inset Newline', i
)
2661 j
= find_end_of_inset(document
.body
, i
)
2663 document
.warning("Malformed LyX document: Could not find end of Newline inset.")
2665 del document
.body
[j
]
2666 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Newline newline', '\\newline')
2667 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Newline linebreak', '\\linebreak')
2670 def convert_japanese_plain(document
):
2671 ' Set language japanese-plain to japanese '
2673 if document
.language
== "japanese-plain":
2674 document
.language
= "japanese"
2675 i
= find_token(document
.header
, "\\language", 0)
2677 document
.header
[i
] = "\\language japanese"
2680 j
= find_token(document
.body
, "\\lang japanese-plain", j
)
2683 document
.body
[j
] = document
.body
[j
].replace("\\lang japanese-plain", "\\lang japanese")
2687 def revert_pdfpages(document
):
2688 ' Revert pdfpages external inset to ERT '
2691 i
= find_token(document
.body
, "\\begin_inset External", i
)
2694 j
= find_end_of_inset(document
.body
, i
)
2696 document
.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2699 if get_value(document
.body
, 'template', i
, j
) == "PDFPages":
2700 filename
= get_value(document
.body
, 'filename', i
, j
)
2702 r
= re
.compile(r
'\textra PDFLaTeX \"(.*)\"$')
2703 for k
in range(i
, j
):
2704 m
= r
.match(document
.body
[k
])
2707 angle
= get_value(document
.body
, 'rotateAngle', i
, j
)
2708 width
= get_value(document
.body
, 'width', i
, j
)
2709 height
= get_value(document
.body
, 'height', i
, j
)
2710 scale
= get_value(document
.body
, 'scale', i
, j
)
2711 keepAspectRatio
= find_token(document
.body
, "\tkeepAspectRatio", i
, j
)
2715 options
+= ",angle=" + angle
2717 options
+= "angle=" + angle
2720 options
+= ",width=" + convert_len(width
)
2722 options
+= "width=" + convert_len(width
)
2725 options
+= ",height=" + convert_len(height
)
2727 options
+= "height=" + convert_len(height
)
2730 options
+= ",scale=" + scale
2732 options
+= "scale=" + scale
2733 if keepAspectRatio
!= '':
2735 options
+= ",keepaspectratio"
2737 options
+= "keepaspectratio"
2739 options
= '[' + options
+ ']'
2740 del document
.body
[i
+1:j
+1]
2741 document
.body
[i
:i
+1] = ['\\begin_inset ERT',
2744 '\\begin_layout Standard',
2747 'includepdf' + options
+ '{' + filename
+ '}',
2751 add_to_preamble(document
, ['\\usepackage{pdfpages}\n'])
2757 def revert_mexican(document
):
2758 ' Set language Spanish(Mexico) to Spanish '
2760 if document
.language
== "spanish-mexico":
2761 document
.language
= "spanish"
2762 i
= find_token(document
.header
, "\\language", 0)
2764 document
.header
[i
] = "\\language spanish"
2767 j
= find_token(document
.body
, "\\lang spanish-mexico", j
)
2770 document
.body
[j
] = document
.body
[j
].replace("\\lang spanish-mexico", "\\lang spanish")
2774 def remove_embedding(document
):
2775 ' Remove embed tag from all insets '
2776 revert_inset_embedding(document
, 'Graphics')
2777 revert_inset_embedding(document
, 'External')
2778 revert_inset_embedding(document
, 'CommandInset include')
2779 revert_inset_embedding(document
, 'CommandInset bibtex')
2782 def revert_master(document
):
2783 ' Remove master param '
2784 i
= find_token(document
.header
, "\\master", 0)
2786 del document
.header
[i
]
2789 def revert_graphics_group(document
):
2790 ' Revert group information from graphics insets '
2793 i
= find_token(document
.body
, "\\begin_inset Graphics", i
)
2796 j
= find_end_of_inset(document
.body
, i
)
2798 document
.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2801 k
= find_token(document
.body
, " groupId", i
, j
)
2805 del document
.body
[k
]
2809 def update_apa_styles(document
):
2810 ' Replace obsolete styles '
2812 if document
.textclass
!= "apa":
2815 obsoletedby
= { "Acknowledgments": "Acknowledgements",
2816 "Section*": "Section",
2817 "Subsection*": "Subsection",
2818 "Subsubsection*": "Subsubsection",
2819 "Paragraph*": "Paragraph",
2820 "Subparagraph*": "Subparagraph"}
2823 i
= find_token(document
.body
, "\\begin_layout", i
)
2827 layout
= document
.body
[i
][14:]
2828 if layout
in obsoletedby
:
2829 document
.body
[i
] = "\\begin_layout " + obsoletedby
[layout
]
2834 def convert_paper_sizes(document
):
2835 ' exchange size options legalpaper and executivepaper to correct order '
2836 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2839 i
= find_token(document
.header
, "\\papersize executivepaper", 0)
2841 document
.header
[i
] = "\\papersize legalpaper"
2843 j
= find_token(document
.header
, "\\papersize legalpaper", 0)
2845 document
.header
[j
] = "\\papersize executivepaper"
2848 def revert_paper_sizes(document
):
2849 ' exchange size options legalpaper and executivepaper to correct order '
2852 i
= find_token(document
.header
, "\\papersize executivepaper", 0)
2854 document
.header
[i
] = "\\papersize legalpaper"
2856 j
= find_token(document
.header
, "\\papersize legalpaper", 0)
2858 document
.header
[j
] = "\\papersize executivepaper"
2861 def convert_InsetSpace(document
):
2862 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2865 i
= find_token(document
.body
, "\\begin_inset Space", i
)
2868 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Space', '\\begin_inset space')
2871 def revert_InsetSpace(document
):
2872 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2875 i
= find_token(document
.body
, "\\begin_inset space", i
)
2878 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset space', '\\begin_inset Space')
2881 def convert_display_enum(document
):
2882 " Convert 'display foo' to 'display false/true'"
2885 i
= find_token(document
.body
, "\tdisplay", i
)
2888 val
= get_value(document
.body
, 'display', i
)
2890 document
.body
[i
] = document
.body
[i
].replace('none', 'false')
2891 if val
== "default":
2892 document
.body
[i
] = document
.body
[i
].replace('default', 'true')
2893 if val
== "monochrome":
2894 document
.body
[i
] = document
.body
[i
].replace('monochrome', 'true')
2895 if val
== "grayscale":
2896 document
.body
[i
] = document
.body
[i
].replace('grayscale', 'true')
2898 document
.body
[i
] = document
.body
[i
].replace('color', 'true')
2899 if val
== "preview":
2900 document
.body
[i
] = document
.body
[i
].replace('preview', 'true')
2904 def revert_display_enum(document
):
2905 " Revert 'display false/true' to 'display none/color'"
2908 i
= find_token(document
.body
, "\tdisplay", i
)
2911 val
= get_value(document
.body
, 'display', i
)
2913 document
.body
[i
] = document
.body
[i
].replace('false', 'none')
2915 document
.body
[i
] = document
.body
[i
].replace('true', 'default')
2919 def remove_fontsCJK(document
):
2920 ' Remove font_cjk param '
2921 i
= find_token(document
.header
, "\\font_cjk", 0)
2923 del document
.header
[i
]
2926 def convert_plain_layout(document
):
2927 " Convert 'PlainLayout' to 'Plain Layout'"
2930 i
= find_token(document
.body
, '\\begin_layout PlainLayout', i
)
2933 document
.body
[i
] = document
.body
[i
].replace('\\begin_layout PlainLayout', \
2934 '\\begin_layout Plain Layout')
2938 def revert_plain_layout(document
):
2939 " Revert 'Plain Layout' to 'PlainLayout'"
2942 i
= find_token(document
.body
, '\\begin_layout Plain Layout', i
)
2945 document
.body
[i
] = document
.body
[i
].replace('\\begin_layout Plain Layout', \
2946 '\\begin_layout PlainLayout')
2950 def revert_plainlayout(document
):
2951 " Revert 'PlainLayout' to 'Standard'"
2954 i
= find_token(document
.body
, '\\begin_layout PlainLayout', i
)
2957 # This will be incorrect for some document classes, since Standard is not always
2958 # the default. But (a) it is probably the best we can do and (b) it will actually
2959 # work, in fact, since an unknown layout will be converted to default.
2960 document
.body
[i
] = document
.body
[i
].replace('\\begin_layout PlainLayout', \
2961 '\\begin_layout Standard')
2965 def revert_polytonicgreek(document
):
2966 "Set language polytonic Greek to Greek"
2968 if document
.language
== "polutonikogreek":
2969 document
.language
= "greek"
2970 i
= find_token(document
.header
, "\\language", 0)
2972 document
.header
[i
] = "\\language greek"
2975 j
= find_token(document
.body
, "\\lang polutonikogreek", j
)
2978 document
.body
[j
] = document
.body
[j
].replace("\\lang polutonikogreek", "\\lang greek")
2982 def revert_removed_modules(document
):
2985 i
= find_token(document
.header
, "\\begin_remove_modules", i
)
2988 j
= find_end_of(document
.header
, i
, "\\begin_remove_modules", "\\end_remove_modules")
2990 # this should not happen
2992 document
.header
[i
: j
+ 1] = []
2995 def add_plain_layout(document
):
2998 i
= find_token(document
.body
, "\\begin_layout", i
)
3001 if len(document
.body
[i
].split()) == 1:
3002 document
.body
[i
] = "\\begin_layout Plain Layout"
3006 def revert_tabulators(document
):
3007 "Revert tabulators to 4 spaces"
3010 i
= find_token(document
.body
, "\t", i
)
3013 document
.body
[i
] = document
.body
[i
].replace("\t", " ")
3017 def revert_tabsize(document
):
3018 "Revert the tabsize parameter of listings"
3022 # either it is the only parameter
3023 i
= find_token(document
.body
, 'lstparams "tabsize=4"', i
)
3025 del document
.body
[i
]
3027 j
= find_token(document
.body
, "lstparams", j
)
3030 pos
= document
.body
[j
].find(",tabsize=")
3031 document
.body
[j
] = document
.body
[j
][:pos
] + '"'
3036 def revert_mongolian(document
):
3037 "Set language Mongolian to English"
3039 if document
.language
== "mongolian":
3040 document
.language
= "english"
3041 i
= find_token(document
.header
, "\\language", 0)
3043 document
.header
[i
] = "\\language english"
3046 j
= find_token(document
.body
, "\\lang mongolian", j
)
3049 document
.body
[j
] = document
.body
[j
].replace("\\lang mongolian", "\\lang english")
3053 def revert_default_options(document
):
3054 ' Remove param use_default_options '
3055 i
= find_token(document
.header
, "\\use_default_options", 0)
3057 del document
.header
[i
]
3060 def convert_default_options(document
):
3061 ' Add param use_default_options and set it to false '
3062 i
= find_token(document
.header
, "\\textclass", 0)
3064 document
.warning("Malformed LyX document: Missing `\\textclass'.")
3066 document
.header
.insert(i
, '\\use_default_options false')
3069 def revert_backref_options(document
):
3070 ' Revert option pdf_backref=page to pagebackref '
3071 i
= find_token(document
.header
, "\\pdf_backref page", 0)
3073 document
.header
[i
] = "\\pdf_pagebackref true"
3076 def convert_backref_options(document
):
3077 ' We have changed the option pagebackref to backref=true '
3078 i
= find_token(document
.header
, "\\pdf_pagebackref true", 0)
3080 document
.header
[i
] = "\\pdf_backref page"
3081 j
= find_token(document
.header
, "\\pdf_pagebackref false", 0)
3083 del document
.header
[j
]
3084 # backref=true was not a valid option, we meant backref=section
3085 k
= find_token(document
.header
, "\\pdf_backref true", 0)
3086 if k
!= -1 and i
!= -1:
3087 del document
.header
[k
]
3088 elif k
!= -1 and j
!= -1:
3089 document
.header
[k
] = "\\pdf_backref section"
3092 def convert_charstyle_element(document
):
3093 "Convert CharStyle to Element for docbook backend"
3094 if document
.backend
!= "docbook":
3098 i
= find_token(document
.body
, "\\begin_inset Flex CharStyle:", i
)
3101 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Flex CharStyle:',
3102 '\\begin_inset Flex Element:')
3104 def revert_charstyle_element(document
):
3105 "Convert Element to CharStyle for docbook backend"
3106 if document
.backend
!= "docbook":
3110 i
= find_token(document
.body
, "\\begin_inset Flex Element:", i
)
3113 document
.body
[i
] = document
.body
[i
].replace('\\begin_inset Flex Element:',
3114 '\\begin_inset Flex CharStyle:')
3120 supported_versions
= ["1.6.0","1.6"]
3121 convert
= [[277, [fix_wrong_tables
]],
3122 [278, [close_begin_deeper
]],
3123 [279, [long_charstyle_names
]],
3124 [280, [axe_show_label
]],
3127 [283, [convert_flex
]],
3131 [287, [convert_wrapfig_options
]],
3132 [288, [convert_inset_command
]],
3133 [289, [convert_latexcommand_index
]],
3136 [292, [convert_japanese_cjk
]],
3138 [294, [convert_pdf_options
]],
3139 [295, [convert_htmlurl
, convert_url
]],
3140 [296, [convert_include
]],
3141 [297, [convert_usorbian
]],
3142 [298, [convert_macro_global
]],
3147 [303, [convert_serbocroatian
]],
3148 [304, [convert_framed_notes
]],
3155 [311, [convert_ams_classes
]],
3157 [313, [convert_module_names
]],
3160 [316, [convert_subfig
]],
3163 [319, [convert_spaceinset
, convert_hfill
]],
3165 [321, [convert_tablines
]],
3166 [322, [convert_plain_layout
]],
3167 [323, [convert_pagebreaks
]],
3168 [324, [convert_linebreaks
]],
3169 [325, [convert_japanese_plain
]],
3172 [328, [remove_embedding
, remove_extra_embedded_files
, remove_inzip_options
]],
3175 [331, [convert_ltcaption
]],
3177 [333, [update_apa_styles
]],
3178 [334, [convert_paper_sizes
]],
3179 [335, [convert_InsetSpace
]],
3181 [337, [convert_display_enum
]],
3184 [340, [add_plain_layout
]],
3187 [343, [convert_default_options
]],
3188 [344, [convert_backref_options
]],
3189 [345, [convert_charstyle_element
]]
3192 revert
= [[344, [revert_charstyle_element
]],
3193 [343, [revert_backref_options
]],
3194 [342, [revert_default_options
]],
3195 [341, [revert_mongolian
]],
3196 [340, [revert_tabulators
, revert_tabsize
]],
3198 [338, [revert_removed_modules
]],
3199 [337, [revert_polytonicgreek
]],
3200 [336, [revert_display_enum
]],
3201 [335, [remove_fontsCJK
]],
3202 [334, [revert_InsetSpace
]],
3203 [333, [revert_paper_sizes
]],
3205 [331, [revert_graphics_group
]],
3206 [330, [revert_ltcaption
]],
3207 [329, [revert_leftarrowfill
, revert_rightarrowfill
, revert_upbracefill
, revert_downbracefill
]],
3208 [328, [revert_master
]],
3210 [326, [revert_mexican
]],
3211 [325, [revert_pdfpages
]],
3213 [323, [revert_linebreaks
]],
3214 [322, [revert_pagebreaks
]],
3215 [321, [revert_local_layout
, revert_plain_layout
]],
3216 [320, [revert_tablines
]],
3217 [319, [revert_protected_hfill
]],
3218 [318, [revert_spaceinset
, revert_hfills
, revert_hspace
]],
3219 [317, [remove_extra_embedded_files
]],
3220 [316, [revert_wrapplacement
]],
3221 [315, [revert_subfig
]],
3222 [314, [revert_colsep
, revert_plainlayout
]],
3224 [312, [revert_module_names
]],
3225 [311, [revert_rotfloat
, revert_widesideways
]],
3226 [310, [revert_external_embedding
]],
3227 [309, [revert_btprintall
]],
3228 [308, [revert_nocite
]],
3229 [307, [revert_serbianlatin
]],
3230 [306, [revert_slash
, revert_nobreakdash
]],
3231 [305, [revert_interlingua
]],
3232 [304, [revert_bahasam
]],
3233 [303, [revert_framed_notes
]],
3235 [301, [revert_latin
, revert_samin
]],
3236 [300, [revert_linebreak
]],
3237 [299, [revert_pagebreak
]],
3238 [298, [revert_hyperlinktype
]],
3239 [297, [revert_macro_optional_params
]],
3240 [296, [revert_albanian
, revert_lowersorbian
, revert_uppersorbian
]],
3241 [295, [revert_include
]],
3242 [294, [revert_href
, revert_url
]],
3243 [293, [revert_pdf_options_2
]],
3244 [292, [revert_inset_info
]],
3245 [291, [revert_japanese
, revert_japanese_encoding
, revert_japanese_cjk
]],
3246 [290, [revert_vietnamese
]],
3247 [289, [revert_wraptable
]],
3248 [288, [revert_latexcommand_index
]],
3249 [287, [revert_inset_command
]],
3250 [286, [revert_wrapfig_options
]],
3251 [285, [revert_pdf_options
]],
3252 [284, [remove_inzip_options
]],
3254 [282, [revert_flex
]],
3256 [280, [revert_begin_modules
]],
3257 [279, [revert_show_label
]],
3258 [278, [revert_long_charstyle_names
]],
3264 if __name__
== "__main__":