/* * $Id$ * * Copyright (c) 2004-2005 by the TeXlapse Team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package net.sourceforge.texlipse.editor; import net.sourceforge.texlipse.TexlipsePlugin; import net.sourceforge.texlipse.texparser.LatexParserUtils; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.source.ICharacterPairMatcher; import org.eclipse.jface.text.BadLocationException; /** * @author Esa Seuranen * @author Boris von Loesch * * A pair finder class for implementing the pair matching. */ public class TexPairMatcher implements ICharacterPairMatcher { //current anchor position private int fAnchor = LatexParserUtils.LEFT; //string of pairs, so that two consecutive characters form a pair and the first //character is the "left" and the latter is the "right" private String pairs; /** * Constructs a TexPairMatcher. The matching pairs are given in as a string * parameter so that two consecutive characters form a pair (in which * the first character is "left" and the latter is "right. * * Example: String "(){}[]" has three pairs: 1. ( and ) 2. { and } 3. [ and ] * * @param pairs of matching characters */ public TexPairMatcher(String pairs) { this.pairs = pairs; if((pairs.length() % 2) == 1) { TexlipsePlugin.stat("Bad parameter for TexPairMatcher constructor: " + pairs); this.pairs = ""; } } /** * Disposes the TexPairMatcher * * @see org.eclipse.jface.text.source.ICharacterPairMatcher#dispose() */ public void dispose() { } /** * Clears all internal state information in preparation for <code>match</code> * * @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear() */ public void clear() { } /** * Matches smallest region between a pair. If there is another pair (of same type) * inside the region, it is taken into consideration. Example (numbers indicate * matching parens): * <pre> * (there is a region (inside) another region) * 1 2 2 1 * </pre> * * @param document * @param offset * @return region (the pair included) between the matching pair, or <code>null</code> * if there is no counterpair for the character at the offset (either it is * not a matching pair character or it's pair does not exist) * * @see org.eclipse.jface.text.source.ICharacterPairMatcher#match(org.eclipse.jface.text.IDocument, int) */ public IRegion match(IDocument document, int offset) { offset--; // we want to match pairs after we have entered the pair // character if (offset < 0) return null; try { int index = pairs.indexOf(document.getChar(offset)); if (index == -1) { return null; } // Check for a backslash then it is no brace but a command if (offset > 0 && document.getChar(offset - 1) == '\\') return null; String docString = document.get(); int peerIndex; if ((index % 2) == 1) { fAnchor = LatexParserUtils.RIGHT; peerIndex = LatexParserUtils.findPeerChar(docString, offset, fAnchor, pairs.charAt(index), pairs.charAt(index - 1)); if (peerIndex != -1) return new Region(peerIndex, offset - peerIndex + 1); } else { fAnchor = LatexParserUtils.LEFT; peerIndex = LatexParserUtils.findPeerChar(docString, offset, fAnchor, pairs.charAt(index), pairs.charAt(index + 1)); if (peerIndex != -1) return new Region(offset, peerIndex - offset + 1); } } catch (BadLocationException ble) { TexlipsePlugin.log("Bad location in TexPairMatcher.match()", ble); } return null; } /** * Returns anchor, i.e. whether the current character (in the document's * current position) is RIGHT (0) if the character is "right" character in a pair, * or LEFT (1) if the current character is anything else. * * @see org.eclipse.jface.text.source.ICharacterPairMatcher#getAnchor() */ public int getAnchor() { return fAnchor; } }