# This file is part of lyx2lyx
# -*- coding: utf-8 -*-
-# Copyright (C) 2002-2010 Dekel Tsur <dekel@lyx.org>,
+# Copyright (C) 2002-2011 Dekel Tsur <dekel@lyx.org>,
# José Matos <jamatos@lyx.org>, Richard Heck <rgheck@comcast.net>
#
# This program is free software; you can redistribute it and/or
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'''
find_token(lines, token, start[, end[, ignorews]]):
Returns the first line i, start <= i < end, on which
token is found at the beginning. Returns -1 if not
- found. If ignorews is (given and) True, then differences
- in whitespace do not count.
+ found.
+ If ignorews is (given and) True, then differences
+ in whitespace do not count, except that there must be no
+ extra whitespace following token itself.
find_token_exact(lines, token, start[, end]):
- Badly named. As find_token, but with ignorews True.
+ As find_token, but with ignorews True.
find_tokens(lines, tokens, start[, end[, ignorews]]):
Returns the first line i, start <= i < end, on which
oen of the tokens in tokens is found at the beginning.
- Returns -1 if not found. If ignorews is (given and) True,
- then differences in whitespace do not count.
+ Returns -1 if not found.
+ If ignorews is (given and) True, then differences
+ in whitespace do not count, except that there must be no
+ extra whitespace following token itself.
find_tokens_exact(lines, token, start[, end]):
- Badly named. As find_tokens, but with ignorews True.
+ As find_tokens, but with ignorews True.
find_token_backwards(lines, token, start):
find_tokens_backwards(lines, tokens, start):
value, if they are present. So use this one for cases
where the value is normally quoted.
+get_option_value(line, option):
+ This assumes we have a line with something like:
+ option="value"
+ and returns value. Returns "" if not found.
+
del_token(lines, token, start[, end]):
Like find_token, but deletes the line if it finds one.
Returns True if a line got deleted, otherwise False.
find_end_of_layout(lines, i):
Specialization of find_end_of for layouts.
+find_end_of_sequence(lines, i):
+ Find the end of the sequence of layouts of the same kind.
+ Considers nesting.
+
is_in_inset(lines, i, inset):
Checks if line i is in an inset of the given type.
If so, returns starting and ending lines. Otherwise,
on line 306.
get_containing_layout(lines, i):
- As get_containing_inset, but for layout.
+ As get_containing_inset, but for layout. Additionally returns the
+ position of real paragraph start (after par params) as 4th value.
find_nonempty_line(lines, start[, end):
is_nonempty_line(line):
Does line contain something besides whitespace?
+count_pars_in_inset(lines, i):
+ Counts the paragraphs inside an inset.
+
'''
+import re
+
# Utilities for one line
def check_token(line, token):
""" check_token(line, token) -> bool
element, in lines[start, end].
If ignorews is True (default is False), then differences in
- whitespace are ignored.
+ whitespace are ignored, except that there must be no extra
+ whitespace following token itself.
Return -1 on failure."""
return val.strip('"')
+def get_option_value(line, option):
+ rx = option + '\s*=\s*"([^"]+)"'
+ rx = re.compile(rx)
+ m = rx.search(line)
+ if not m:
+ return ""
+ return m.group(1)
+
+
+def set_option_value(line, option, value):
+ rx = '(' + option + '\s*=\s*")[^"]+"'
+ rx = re.compile(rx)
+ m = rx.search(line)
+ if not m:
+ return line
+ return re.sub(rx, '\g<1>' + value + '"', line)
+
+
def del_token(lines, token, start, end = 0):
""" del_token(lines, token, start, end) -> int
on which the inset begins, plus the starting and ending line.
Returns False on any kind of error or if it isn't in an inset.
'''
- stins = find_token_backwards(lines, i, "\\begin_inset")
- if stins == -1:
- return False
- endins = find_end_of_inset(lines, stins)
- if endins < i:
- return False
+ j = i
+ while True:
+ stins = find_token_backwards(lines, "\\begin_inset", j)
+ if stins == -1:
+ return False
+ endins = find_end_of_inset(lines, stins)
+ if endins > j:
+ break
+ j = stins - 1
+
inset = get_value(lines, "\\begin_inset", stins)
if inset == "":
# shouldn't happen
'''
Finds out what kind of layout line i is within. Returns a
list containing (i) what follows \begin_layout on the the line
- on which the layout begins, plus the starting and ending line.
+ on which the layout begins, plus the starting and ending line
+ and the start of the apargraph (after all params).
Returns False on any kind of error.
'''
- stins = find_token_backwards(lines, i, "\\begin_layout")
- if stins == -1:
- return False
- endins = find_end_of_layout(lines, stins)
- if endins < i:
- return False
- lay = get_value(lines, "\\begin_layout", stins)
+ j = i
+ while True:
+ stlay = find_token_backwards(lines, "\\begin_layout", j)
+ if stlay == -1:
+ return False
+ endlay = find_end_of_layout(lines, stlay)
+ if endlay > i:
+ break
+ j = stlay - 1
+
+ lay = get_value(lines, "\\begin_layout", stlay)
if lay == "":
# shouldn't happen
return False
- return (lay, stins, endins)
+ par_params = ["\\noindent", "\\indent", "\\indent-toggle", "\\leftindent",
+ "\\start_of_appendix", "\\paragraph_spacing single",
+ "\\paragraph_spacing onehalf", "\\paragraph_spacing double",
+ "\\paragraph_spacing other", "\\align", "\\labelwidthstring"]
+ stpar = stlay
+ while True:
+ stpar += 1
+ if lines[stpar] not in par_params:
+ break
+ return (lay, stlay, endlay, stpar)
+
+
+def count_pars_in_inset(lines, i):
+ '''
+ Counts the paragraphs within this inset
+ '''
+ ins = get_containing_inset(lines, i)
+ if ins == -1:
+ return -1
+ pars = 0
+ for j in range(ins[1], ins[2]):
+ m = re.match(r'\\begin_layout (.*)', lines[j])
+ if m and get_containing_inset(lines, j)[0] == ins[0]:
+ pars += 1
+
+ return pars
+
+
+def find_end_of_sequence(lines, i):
+ '''
+ Returns the end of a sequence of identical layouts.
+ '''
+ lay = get_containing_layout(lines, i)
+ if lay == False:
+ return -1
+ layout = lay[0]
+ endlay = lay[2]
+ i = endlay
+ while True:
+ m = re.match(r'\\begin_layout (.*)', lines[i])
+ if m and m.group(1) != layout:
+ return endlay
+ elif lines[i] == "\\begin_deeper":
+ j = find_end_of(lines, i, "\\begin_deeper", "\\end_deeper")
+ if j != -1:
+ i = j
+ continue
+ if m and m.group(1) == layout:
+ endlay = find_end_of_layout(lines, i)
+ i = endlay
+ continue
+ if i == len(lines) - 1:
+ break
+ i = i + 1
+
+ return endlay
+