/** * This method is used to parse string labels, field names, entry type and numbers outside * brackets. */ private String parseTextToken() throws IOException { StringBuffer token = new StringBuffer(20); while (true) { int c = read(); // Util.pr(".. "+c); if (c == -1) { _eof = true; return token.toString(); } if (Character.isLetterOrDigit((char) c) || (c == ':') || (c == '-') || (c == '_') || (c == '*') || (c == '+') || (c == '.') || (c == '/') || (c == '\'')) { token.append((char) c); } else { unread(c); // Util.pr("Pasted text token: "+token.toString()); return token.toString(); } } }
private String skipAndRecordWhitespace(int j) throws IOException { int c; StringBuffer sb = new StringBuffer(); if (j != ' ') sb.append((char) j); while (true) { c = read(); if ((c == -1) || (c == 65535)) { _eof = true; return sb.toString(); } if (Character.isWhitespace((char) c)) { if (c != ' ') sb.append((char) c); continue; } else // found non-whitespace char // Util.pr("SkipWhitespace, stops: "+c); unread(c); /* * try { Thread.currentThread().sleep(500); } catch * (InterruptedException ex) {} */ break; } return sb.toString(); }
/** This method is used to parse the bibtex key for an entry. */ private String parseKey() throws IOException, NoLabelException { StringBuffer token = new StringBuffer(20); while (true) { int c = read(); // Util.pr(".. '"+(char)c+"'\t"+c); if (c == -1) { _eof = true; return token.toString(); } // Ikke: #{}\uFFFD~\uFFFD // // G\uFFFDr: $_*+.-\/?"^ if (!Character.isWhitespace((char) c) && (Character.isLetterOrDigit((char) c) || ((c != '#') && (c != '{') && (c != '}') && (c != '\uFFFD') && (c != '~') && (c != '\uFFFD') && (c != ',') && (c != '=')))) { token.append((char) c); } else { if (Character.isWhitespace((char) c)) { // We have encountered white space instead of the comma at // the end of // the key. Possibly the comma is missing, so we try to // return what we // have found, as the key and try to restore the rest in fixKey(). return token.toString() + fixKey(); } else if (c == ',') { unread(c); return token.toString(); // } else if (Character.isWhitespace((char)c)) { // throw new NoLabelException(token.toString()); } else if (c == '=') { // If we find a '=' sign, it is either an error, or // the entry lacked a comma signifying the end of the key. return token.toString(); // throw new NoLabelException(token.toString()); } else throw new IOException( "Error in line " + line + ":" + "Character '" + (char) c + "' is not " + "allowed in bibtex keys."); } } }
private void skipWhitespace() throws IOException { int c; while (true) { c = read(); if ((c == -1) || (c == 65535)) { _eof = true; return; } if (Character.isWhitespace((char) c)) { continue; } else // found non-whitespace char // Util.pr("SkipWhitespace, stops: "+c); unread(c); /* * try { Thread.currentThread().sleep(500); } catch * (InterruptedException ex) {} */ break; } }
/** * pushes buffer back into input * * @param sb * @throws IOException can be thrown if buffer is bigger than LOOKAHEAD */ private void unreadBuffer(StringBuilder sb) throws IOException { for (int i = sb.length() - 1; i >= 0; --i) { unread(sb.charAt(i)); } }
/** * Tries to restore the key * * @return rest of key on success, otherwise empty string * @throws IOException on Reader-Error */ private String fixKey() throws IOException { StringBuilder key = new StringBuilder(); int lookahead_used = 0; char currentChar; // Find a char which ends key (','&&'\n') or entryfield ('='): do { currentChar = (char) read(); key.append(currentChar); lookahead_used++; } while ((currentChar != ',' && currentChar != '\n' && currentChar != '=') && (lookahead_used < LOOKAHEAD)); // Consumed a char too much, back into reader and remove from key: unread(currentChar); key.deleteCharAt(key.length() - 1); // Restore if possible: switch (currentChar) { case '=': // Get entryfieldname, push it back and take rest as key key = key.reverse(); boolean matchedAlpha = false; for (int i = 0; i < key.length(); i++) { currentChar = key.charAt(i); /// Skip spaces: if (!matchedAlpha && currentChar == ' ') { continue; } matchedAlpha = true; // Begin of entryfieldname (e.g. author) -> push back: unread(currentChar); if (currentChar == ' ' || currentChar == '\n') { /* * found whitespaces, entryfieldname completed -> key in * keybuffer, skip whitespaces */ StringBuilder newKey = new StringBuilder(); for (int j = i; j < key.length(); j++) { currentChar = key.charAt(j); if (!Character.isWhitespace(currentChar)) { newKey.append(currentChar); } } // Finished, now reverse newKey and remove whitespaces: _pr.addWarning( Globals.lang("Line %0: Found corrupted BibTeX-key.", String.valueOf(line))); key = newKey.reverse(); } } break; case ',': _pr.addWarning( Globals.lang( "Line %0: Found corrupted BibTeX-key (contains whitespaces).", String.valueOf(line))); case '\n': _pr.addWarning( Globals.lang( "Line %0: Found corrupted BibTeX-key (comma missing).", String.valueOf(line))); break; default: // No more lookahead, give up: unreadBuffer(key); return ""; } return removeWhitespaces(key).toString(); }
private int peek() throws IOException { int c = read(); unread(c); return c; }