]> git.lyx.org Git - features.git/blob - lib/lyx2lyx/lyx_2_3.py
Improve the file format upgrade and downgrade for microtype
[features.git] / lib / lyx2lyx / lyx_2_3.py
1 # -*- coding: utf-8 -*-
2 # This file is part of lyx2lyx
3 # -*- coding: utf-8 -*-
4 # Copyright (C) 2016 The LyX team
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 """ Convert files to the file format generated by lyx 2.3"""
21
22 import re, string
23 import unicodedata
24 import sys, os
25
26 # Uncomment only what you need to import, please.
27
28 #from parser_tools import find_token, find_end_of, find_tokens, \
29 #  find_token_exact, find_end_of_inset, find_end_of_layout, \
30 #  find_token_backwards, is_in_inset, get_value, get_quoted_value, \
31 #  del_token, check_token, get_option_value, get_bool_value
32
33 from parser_tools import find_token, find_end_of_inset, get_value, \
34      get_bool_value
35
36 #from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert, lyx2latex, \
37 #  lyx2verbatim, length_in_bp, convert_info_insets
38 #  insert_to_preamble, latex_length, revert_flex_inset, \
39 #  revert_font_attrs, hex2ratio, str2bool
40
41 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert
42
43 ####################################################################
44 # Private helper functions
45
46
47
48 ###############################################################################
49 ###
50 ### Conversion and reversion routines
51 ###
52 ###############################################################################
53
54 def convert_microtype(document):
55     " Add microtype settings. "
56     i = find_token(document.header, "\\font_tt_scale" , 0)
57     if i == -1:
58         document.warning("Malformed LyX document: Can't find \\font_tt_scale.")
59         i = len(document.header) - 1
60
61     j = find_token(document.preamble, "\\usepackage{microtype}", 0)
62     if j == -1:
63         document.header.insert(i + 1, "\\use_microtype false")
64     else:
65         document.header.insert(i + 1, "\\use_microtype true")
66         del document.preamble[j]
67
68
69 def revert_microtype(document):
70     " Remove microtype settings. "
71     i = find_token(document.header, "\\use_microtype", 0)
72     if i == -1:
73         return
74     use_microtype = get_bool_value(document.header, "\\use_microtype" , i)
75     del document.header[i]
76     if use_microtype:
77         add_to_preamble(document, ["\\usepackage{microtype}"])
78
79
80 def convert_dateinset(document):
81     ' Convert date external inset to ERT '
82     i = 0
83     while True:
84         i = find_token(document.body, "\\begin_inset External", i)
85         if i == -1:
86             return
87         j = find_end_of_inset(document.body, i)
88         if j == -1:
89             document.warning("Malformed lyx document: Missing '\\end_inset' in convert_dateinset.")
90             i += 1
91             continue
92         if get_value(document.body, 'template', i, j) == "Date":
93             document.body[i : j + 1] = put_cmd_in_ert("\\today ")
94         i += 1
95         continue
96
97
98 def convert_ibranches(document):
99     ' Add "inverted 0" to branch insets'
100     i = 0
101     while True:
102         i = find_token(document.body, "\\begin_inset Branch", i)
103         if i == -1:
104             return
105         document.body.insert(i + 1, "inverted 0")
106         i += 1
107
108
109 def revert_ibranches(document):
110     ' Convert inverted branches to explicit anti-branches'
111     # Get list of branches
112     ourbranches = {}
113     i = 0
114     while True:
115         i = find_token(document.header, "\\branch", i)
116         if i == -1:
117             break
118         branch = document.header[i][8:].strip()
119         if document.header[i+1].startswith("\\selected "):
120             #document.warning(document.header[i+1])
121             #document.warning(document.header[i+1][10])
122             selected = int(document.header[i+1][10])
123         else:
124             document.warning("Malformed LyX document: No selection indicator for branch " + branch)
125             selected = 1
126             
127         # the value tells us whether the branch is selected
128         ourbranches[document.header[i][8:].strip()] = selected
129         i += 1
130
131     # Figure out what inverted branches, if any, have been used
132     # and convert them to "Anti-OldBranch"
133     ibranches = {}
134     i = 0
135     while True:
136         i = find_token(document.body, "\\begin_inset Branch", i)
137         if i == -1:
138             break
139         if not document.body[i+1].startswith("inverted "):
140             document.warning("Malformed LyX document: Missing 'inverted' tag!")
141             i += 1
142             continue
143         inverted = document.body[i+1][9]
144         #document.warning(document.body[i+1])
145
146         if inverted == "1":
147             branch = document.body[i][20:].strip()
148             #document.warning(branch)
149             if not branch in ibranches:
150                 antibranch = "Anti-" + branch
151                 while antibranch in ibranches:
152                     antibranch = "x" + antibranch
153                 ibranches[branch] = antibranch
154             else:
155                 antibranch = ibranches[branch]
156             #document.warning(antibranch)
157             document.body[i] = "\\begin_inset Branch " + antibranch
158
159         # remove "inverted" key
160         del document.body[i+1]
161         i += 1
162
163     # now we need to add the new branches to the header
164     for old, new in ibranches.iteritems():
165         i = find_token(document.header, "\\branch " + old, 0)
166         if i == -1:
167             document.warning("Can't find branch %s even though we found it before!" % (old))
168             continue
169         j = find_token(document.header, "\\end_branch", i)
170         if j == -1:
171             document.warning("Malformed LyX document! Can't find end of branch " + old)
172             continue
173         # ourbranches[old] - 1 inverts the selection status of the old branch
174         lines = ["\\branch " + new,
175                  "\\selected " + str(ourbranches[old] - 1)]
176         # these are the old lines telling us color, etc.
177         lines += document.header[i+2 : j+1]
178         document.header[i:i] = lines
179         
180
181 ##
182 # Conversion hub
183 #
184
185 supported_versions = ["2.3.0", "2.3"]
186 convert = [
187            [509, [convert_microtype]],
188            [510, [convert_dateinset]],
189            [511, [convert_ibranches]]
190           ]
191
192 revert =  [
193            [510, [revert_ibranches]],
194            [509, []],
195            [508, [revert_microtype]]
196           ]
197
198
199 if __name__ == "__main__":
200     pass