/* LanguageTool, a natural language style checker
* Copyright (C) 2013 Daniel Naber (http://www.danielnaber.de)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package org.languagetool.dev.wikipedia;
import xtc.tree.Location;
public class LocationHelper {
private LocationHelper() {
}
/**
* Get an absolute position (character-based) for a line/column-based location.
*/
public static int absolutePositionFor(Location location, String text) {
int line = 1;
int col = 1;
int pos = 0;
int ignoreLevel = 0;
boolean inReference = false;
StringBuilder relevantLine = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (line == location.line) {
relevantLine.append(ch);
}
//System.out.println(line + "/" + col + ", ignoreLevel: " + ignoreLevel);
if (line == location.line && col == location.column) {
return pos;
}
char prevCh = i > 0 ? text.charAt(i - 1) : '-';
if (isReferenceStart(text, i)) {
ignoreLevel++;
inReference = true;
} else if (inReference && (isFullReferenceEndTag(text, i) || isShortReferenceEndTag(text, i))) {
ignoreLevel--;
inReference = false;
if (isShortReferenceEndTag(text, i)) {
// this makes SuggestionReplacerTest.testReference2() work, not sure why
col++;
}
} else if (isHtmlCommentStart(text, i)) {
ignoreLevel++;
} else if (isHtmlCommentEnd(text, i)) {
ignoreLevel--;
} else if (ch == '}' && prevCh == '}') {
if (ignoreLevel > 0) {
ignoreLevel--;
}
} else if (ch == '{' && prevCh == '{') {
// ignore templates
ignoreLevel++;
} else if (ch == '\n' && ignoreLevel == 0) {
line++;
col = 1;
} else if (ignoreLevel == 0) {
col++;
}
pos++;
}
if (line == location.line && col == location.column) {
return pos;
}
throw new RuntimeException("Could not find location " + location + " in text. " +
"Max line/col was: " + line + "/" + col + ", Content of relevant line (" + location.line + "): '"
+ relevantLine + "' (" + relevantLine.length() + " chars)");
}
private static boolean isReferenceStart(String text, int i) {
return i < text.length() - 4 && text.substring(i, i + 4).equals("<ref");
}
private static boolean isFullReferenceEndTag(String text, int i) {
return i < text.length() - 6 && text.substring(i, i + 6).equals("</ref>");
}
private static boolean isShortReferenceEndTag(String text, int i) {
return i < text.length() - 2 && text.substring(i, i + 2).equals("/>");
}
private static boolean isHtmlCommentStart(String text, int i) {
return i < text.length() - 4 && text.substring(i, i + 4).equals("<!--");
}
private static boolean isHtmlCommentEnd(String text, int i) {
return i < text.length() - 3 && text.substring(i, i + 3).equals("-->");
}
}