/plugins/LaTeXTools/tags/release-0-5-5/uk/co/antroy/latextools/parsers/BibTeXParser.java

# · Java · 257 lines · 168 code · 67 blank · 22 comment · 25 complexity · 02fed68a4de8e97ca8ea5ff39f9fadf7 MD5 · raw file

  1. /*
  2. * BibTeXParser.java - BibTeX Parser
  3. * Copyright (C) 2003 Anthony Roy
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. package uk.co.antroy.latextools.parsers;
  20. import gnu.regexp.RE;
  21. import gnu.regexp.REException;
  22. import gnu.regexp.REMatch;
  23. import java.io.File;
  24. import java.util.ArrayList;
  25. import java.util.Collections;
  26. import java.util.Enumeration;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.StringTokenizer;
  30. import javax.swing.tree.DefaultMutableTreeNode;
  31. import org.gjt.sp.jedit.Buffer;
  32. import org.gjt.sp.jedit.View;
  33. import org.gjt.sp.jedit.jEdit;
  34. import uk.co.antroy.latextools.macros.ProjectMacros;
  35. public class BibTeXParser {
  36. //~ Instance/static variables .............................................
  37. private List bibEntries = new ArrayList();
  38. private List bibFiles = new ArrayList();
  39. private Buffer buffer;
  40. private View view;
  41. private RE refRe;
  42. private RE titleRe;
  43. private RE authorRe;
  44. private RE contentsRe;
  45. //~ Constructors ..........................................................
  46. public BibTeXParser(View view, Buffer buff) {
  47. this.buffer = buff;
  48. this.view = view;
  49. try {
  50. refRe = new RE("@\\w+?\\s*?\\{\\s*?(.+?),");
  51. titleRe = new RE("\\btitle\\s*=\\s*\\{(.+?)\\}");
  52. authorRe = new RE("\\bauthor\\s*=\\s*\\{(.*?)\\}\\s*(?:,|\\})");
  53. contentsRe = new RE("((?:\\bauthor)|(?:\\bjournal)|(?:\\btitle))\\s*=\\s*\\{(.*?)\\}\\s*(?:,|\\})",
  54. RE.REG_MULTILINE | RE.REG_DOT_NEWLINE);
  55. } catch (REException e) {
  56. e.printStackTrace();
  57. return;
  58. }
  59. parse();
  60. }
  61. //~ Methods ...............................................................
  62. public List getBibEntries() {
  63. return bibEntries;
  64. }
  65. public Object[] getBibEntryArray() {
  66. return bibEntries.toArray();
  67. }
  68. public void parse() {
  69. bibEntries.clear();
  70. bibFiles.clear();
  71. if (ProjectMacros.isBibFile(buffer)) {
  72. File bibfile = new File(buffer.getPath());
  73. bibFiles.add(bibfile);
  74. loadBibEntries();
  75. return;
  76. }
  77. File texFile = new File(buffer.getPath());
  78. DefaultMutableTreeNode files = ProjectMacros.getProjectFiles(view,
  79. buffer);
  80. filesLoop:
  81. for (Enumeration it = files.getLastLeaf().pathFromAncestorEnumeration(
  82. files); it.hasMoreElements();) {
  83. DefaultMutableTreeNode node = (DefaultMutableTreeNode)it.nextElement();
  84. File in = (File)node.getUserObject();
  85. Buffer buff = jEdit.openTemporary(view, in.getParent(),
  86. in.getName(), false);
  87. bufferLoop:
  88. for (int i = buff.getLineCount() - 1; i > 0; i--) {
  89. String nextLine = buff.getLineText(i);
  90. if (nextLine.indexOf("%Bibliography") != -1 ||
  91. nextLine.indexOf("\\begin{document}") != -1) {
  92. break bufferLoop;
  93. }
  94. RE bibRe = null;
  95. RE theBibRe = null;
  96. try {
  97. bibRe = new RE("[^%]*?\\\\bibliography\\{(.+?)\\}.*");
  98. theBibRe = new RE("[^%]*?\\\\begin\\{thebibliography\\}.*");
  99. } catch (Exception e) {
  100. e.printStackTrace();
  101. }
  102. boolean index = bibRe.isMatch(nextLine);
  103. boolean tbindex = theBibRe.isMatch(nextLine);
  104. if (index) {
  105. StringTokenizer st = new StringTokenizer(bibRe.getMatch(nextLine).toString(
  106. 1),
  107. ",");
  108. //Add referenced bibtex files to bibFiles list.
  109. while (st.hasMoreTokens()) {
  110. String s = st.nextToken().trim();
  111. if (!s.endsWith(".bib")) {
  112. s = s + ".bib";
  113. }
  114. File f = new File(ProjectMacros.getMainTeXDir(buffer),
  115. s);
  116. if (!f.exists()) {
  117. f = new File(s);
  118. }
  119. bibFiles.add(f);
  120. }
  121. loadBibEntries();
  122. return;
  123. } else if (tbindex) {
  124. loadTheBibliography(i);
  125. return;
  126. }
  127. }
  128. }
  129. }
  130. private BibEntry getEntryIn(String segment, String ref) {
  131. REMatch[] entries = contentsRe.getAllMatches(segment);
  132. BibEntry out = new BibEntry(ref, "", "");
  133. for (int i = 0; i < entries.length; i++) {
  134. String key = entries[i].toString(1);
  135. String description = entries[i].toString(2);
  136. if (key.equals("title")) {
  137. out.setTitle(description);
  138. } else if (key.equals("author")) {
  139. out.setAuthor(description);
  140. } else if (key.equals("journal")) {
  141. out.setJournal(description);
  142. }
  143. }
  144. return out;
  145. }
  146. private void loadBibEntries() {
  147. Iterator it = bibFiles.iterator();
  148. File bib;
  149. while (it.hasNext()) {
  150. bib = (File)it.next();
  151. parseBibEntriesForFile(bib);
  152. }
  153. Collections.sort(bibEntries);
  154. }
  155. private void loadTheBibliography(int startIndex) {
  156. int index = startIndex;
  157. int refStart;
  158. int end = buffer.getLineText(index).indexOf("\\end{thebibliography}");
  159. while (end == -1) {
  160. String line = buffer.getLineText(index);
  161. refStart = line.indexOf("\\bibitem{");
  162. if (refStart != -1) {
  163. int refEnd = line.indexOf("}");
  164. String bibRef = line.substring(refStart + 9, refEnd);
  165. BibEntry be = new BibEntry(bibRef.trim(), "", "");
  166. bibEntries.add(be);
  167. }
  168. end = buffer.getLineText(++index).indexOf("\\end{thebibliography}");
  169. }
  170. Collections.sort(bibEntries);
  171. }
  172. private void parseBibEntriesForFile(File bib) {
  173. Buffer buff = jEdit.openTemporary(view, bib.getParent(), bib.getName(),
  174. false);
  175. REMatch[] references = refRe.getAllMatches(buff.getText(0,
  176. buff.getLength() - 1));
  177. REMatch second = null;
  178. for (int i = 0; i < references.length-1; i++) {
  179. REMatch first = references[i];
  180. second = references[i + 1];
  181. int end = second.getStartIndex() - first.getStartIndex();
  182. String segment = buff.getText(first.getStartIndex(), end);
  183. BibEntry be = getEntryIn(segment, first.toString(1));
  184. bibEntries.add(be);
  185. }
  186. String segment = buff.getText(second.getStartIndex(), buff.getLength() - second.getStartIndex());
  187. BibEntry be = getEntryIn(segment, second.toString(1));
  188. bibEntries.add(be);
  189. }
  190. }