# 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
'''
More documentaton is below, but here is a quick guide to what
they do. Optional arguments are marked by brackets.
-find_token(lines, token, start[, end[, exact]]):
+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 exact 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.
-del_token(lines, token, start, end):
+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_beginning_of(lines, i, start_token, end_token):
+ Here, start_token and end_token are meant to be a matching
+ pair, like "\begin_layout" and "\end_layout". We look for
+ the start_token that pairs with the end_token that occurs
+ on or after line i. Returns -1 if not found.
+ So, in the layout case, this would find the \begin_layout
+ for the layout line i is in.
+ Example:
+ ec = find_token(document.body, "</cell", i)
+ bc = find_beginning_of(document.body, ec, \
+ "<cell", "</cell")
+ Now, assuming no -1s, bc-ec wraps the cell for line i.
+
+find_end_of(lines, i, start_token, end_token):
+ Like find_beginning_of, but looking for the matching
+ end_token. This might look like:
+ bc = find_token_(document.body, "<cell", i)
+ ec = find_end_of(document.body, bc, "<cell", "</cell")
+ Now, assuming no -1s, bc-ec wrap the next cell.
+
+find_end_of_inset(lines, i):
+ Specialization of find_end_of for insets.
+
+find_end_of_layout(lines, i):
+ Specialization of find_end_of for layouts.
+
+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,
+ returns False.
+ Example:
+ is_in_inset(document.body, i, "\\begin_inset Tabular")
+ returns False unless i is within a table. If it is, then
+ it returns the line on which the table begins and the one
+ on which it ends. Note that this pair will evaulate to
+ boolean True, so
+ if is_in_inset(...):
+ will do what you expect.
+
+get_containing_inset(lines, i):
+ Finds out what kind of inset line i is within. Returns a
+ list containing what follows \begin_inset on the the line
+ 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.
+ So get_containing_inset(document.body, i) might return:
+ ("CommandInset ref", 300, 306)
+ if i is within an InsetRef beginning on line 300 and ending
+ on line 306.
+
+get_containing_layout(lines, i):
+ 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):
+ Finds the next non-empty line.
+
+check_token(line, token):
+ Does line begin with token?
+
+is_nonempty_line(line):
+ Does line contain something besides whitespace?
+
'''
+import re
+
# Utilities for one line
def check_token(line, token):
""" check_token(line, token) -> bool
# Utilities for a list of lines
-def find_token(lines, token, start, end = 0, exact = False):
- """ find_token(lines, token, start[[, end], exact]) -> int
+def find_token(lines, token, start, end = 0, ignorews = False):
+ """ find_token(lines, token, start[[, end], ignorews]) -> int
Return the lowest line where token is found, and is the first
element, in lines[start, end].
- If exact is True (default is False), then differences in
- whitespace are ignored.
+ If ignorews is True (default is False), then differences in
+ whitespace are ignored, except that there must be no extra
+ whitespace following token itself.
Return -1 on failure."""
end = len(lines)
m = len(token)
for i in xrange(start, end):
- if exact:
+ if ignorews:
x = lines[i].split()
y = token.split()
if len(x) < len(y):
return find_token(lines, token, start, end, True)
-def find_tokens(lines, tokens, start, end = 0, exact = False):
- """ find_tokens(lines, tokens, start[[, end], exact]) -> int
+def find_tokens(lines, tokens, start, end = 0, ignorews = False):
+ """ find_tokens(lines, tokens, start[[, end], ignorews]) -> int
Return the lowest line where one token in tokens is found, and is
the first element, in lines[start, end].
Return -1 on failure."""
- if end == 0:
+ if end == 0 or end > len(lines):
end = len(lines)
for i in xrange(start, end):
for token in tokens:
- if exact:
+ if ignorews:
x = lines[i].split()
y = token.split()
if len(x) < len(y):
Return -1 on failure."""
- if end == 0:
+ if end == 0 or end > len(lines):
end = len(lines)
for i in xrange(start, end):
if rexp.match(lines[i]):
return val.strip('"')
-def del_token(lines, token, start, end):
+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
Find the first line in lines where token is the first element
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)