bib-log-parser.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Generated by CoffeeScript 1.10.0
  2. define(function() {
  3. var BAD_CROSS_REFERENCE_REGEX, BibLogParser, LINE_SPLITTER_REGEX, MESSAGE_LEVELS, MULTILINE_COMMAND_ERROR_REGEX, MULTILINE_ERROR_REGEX, MULTILINE_WARNING_REGEX, SINGLELINE_WARNING_REGEX, consume, errorParsers, warningParsers;
  4. LINE_SPLITTER_REGEX = /^\[(\d+)].*>\s(INFO|WARN|ERROR)\s-\s(.*)$/;
  5. MESSAGE_LEVELS = {
  6. "INFO": "info",
  7. "WARN": "warning",
  8. "ERROR": "error"
  9. };
  10. BibLogParser = function(text, options) {
  11. if (typeof text !== 'string') {
  12. throw new Error("BibLogParser Error: text parameter must be a string");
  13. }
  14. this.text = text.replace(/(\r\n)|\r/g, '\n');
  15. this.options = options || {};
  16. this.lines = text.split('\n');
  17. };
  18. consume = function(logText, regex, process) {
  19. var iterationCount, match, newEntry, re, result, text;
  20. text = logText;
  21. result = [];
  22. re = regex;
  23. iterationCount = 0;
  24. while (match = re.exec(text)) {
  25. iterationCount += 1;
  26. newEntry = process(match);
  27. // Too many log entries can cause browser crashes
  28. // Construct a too many files error from the last match
  29. var maxErrors = 100;
  30. if (iterationCount >= maxErrors) {
  31. var level = newEntry.level + "s";
  32. newEntry.message = [
  33. "Over",
  34. maxErrors,
  35. level,
  36. "returned. Download raw logs to see full list"
  37. ].join(" ");
  38. newEntry.line = undefined;
  39. result.unshift(newEntry);
  40. return [result, ""];
  41. }
  42. result.push(newEntry);
  43. text = (match.input.slice(0, match.index)) + (match.input.slice(match.index + match[0].length + 1, match.input.length));
  44. }
  45. return [result, text];
  46. };
  47. MULTILINE_WARNING_REGEX = /^Warning--(.+)\n--line (\d+) of file (.+)$/m;
  48. SINGLELINE_WARNING_REGEX = /^Warning--(.+)$/m;
  49. MULTILINE_ERROR_REGEX = /^(.*)---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this entry$/m;
  50. BAD_CROSS_REFERENCE_REGEX = /^(A bad cross reference---entry ".+?"\nrefers to entry.+?, which doesn't exist)$/m;
  51. MULTILINE_COMMAND_ERROR_REGEX = /^(.*)\n?---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this command$/m;
  52. // Errors hit in BST file have a slightly different format
  53. BST_ERROR_REGEX = /^(.*?)\nwhile executing---line (\d+) of file (.*)/m;
  54. warningParsers = [
  55. [
  56. MULTILINE_WARNING_REGEX, function(match) {
  57. var fileName, fullMatch, lineNumber, message;
  58. fullMatch = match[0], message = match[1], lineNumber = match[2], fileName = match[3];
  59. return {
  60. file: fileName,
  61. level: "warning",
  62. message: message,
  63. line: lineNumber,
  64. raw: fullMatch
  65. };
  66. }
  67. ], [
  68. SINGLELINE_WARNING_REGEX, function(match) {
  69. var fullMatch, message;
  70. fullMatch = match[0], message = match[1];
  71. return {
  72. file: '',
  73. level: "warning",
  74. message: message,
  75. line: '',
  76. raw: fullMatch
  77. };
  78. }
  79. ]
  80. ];
  81. errorParsers = [
  82. [
  83. MULTILINE_ERROR_REGEX, function(match) {
  84. var fileName, firstMessage, fullMatch, lineNumber, secondMessage;
  85. fullMatch = match[0], firstMessage = match[1], lineNumber = match[2], fileName = match[3], secondMessage = match[4];
  86. return {
  87. file: fileName,
  88. level: "error",
  89. message: firstMessage + '\n' + secondMessage,
  90. line: lineNumber,
  91. raw: fullMatch
  92. };
  93. }
  94. ], [
  95. BAD_CROSS_REFERENCE_REGEX, function(match) {
  96. var fullMatch, message;
  97. fullMatch = match[0], message = match[1];
  98. return {
  99. file: '',
  100. level: "error",
  101. message: message,
  102. line: '',
  103. raw: fullMatch
  104. };
  105. }
  106. ], [
  107. MULTILINE_COMMAND_ERROR_REGEX, function(match) {
  108. var fileName, firstMessage, fullMatch, lineNumber, secondMessage;
  109. fullMatch = match[0], firstMessage = match[1], lineNumber = match[2], fileName = match[3], secondMessage = match[4];
  110. return {
  111. file: fileName,
  112. level: "error",
  113. message: firstMessage + '\n' + secondMessage,
  114. line: lineNumber,
  115. raw: fullMatch
  116. };
  117. }
  118. ],[
  119. BST_ERROR_REGEX, function(match) {
  120. var fileName, firstMessage, fullMatch, lineNumber, secondMessage;
  121. fullMatch = match[0], firstMessage = match[1], lineNumber = match[2], fileName = match[3];
  122. return {
  123. file: fileName,
  124. level: "error",
  125. message: firstMessage,
  126. line: lineNumber,
  127. raw: fullMatch
  128. };
  129. }
  130. ]
  131. ];
  132. (function() {
  133. this.parseBibtex = function() {
  134. var allErrors, allWarnings, ref, ref1, remainingText, result;
  135. result = {
  136. all: [],
  137. errors: [],
  138. warnings: [],
  139. files: [],
  140. typesetting: []
  141. };
  142. ref = warningParsers.reduce(function(accumulator, parser) {
  143. var _remainingText, currentWarnings, process, ref, regex, text, warnings;
  144. currentWarnings = accumulator[0], text = accumulator[1];
  145. regex = parser[0], process = parser[1];
  146. ref = consume(text, regex, process), warnings = ref[0], _remainingText = ref[1];
  147. return [currentWarnings.concat(warnings), _remainingText];
  148. }, [[], this.text]), allWarnings = ref[0], remainingText = ref[1];
  149. ref1 = errorParsers.reduce(function(accumulator, parser) {
  150. var _remainingText, currentErrors, errors, process, ref1, regex, text;
  151. currentErrors = accumulator[0], text = accumulator[1];
  152. regex = parser[0], process = parser[1];
  153. ref1 = consume(text, regex, process), errors = ref1[0], _remainingText = ref1[1];
  154. return [currentErrors.concat(errors), _remainingText];
  155. }, [[], remainingText]), allErrors = ref1[0], remainingText = ref1[1];
  156. result.warnings = allWarnings;
  157. result.errors = allErrors;
  158. result.all = allWarnings.concat(allErrors);
  159. return result;
  160. };
  161. this.parseBiber = function() {
  162. var result;
  163. result = {
  164. all: [],
  165. errors: [],
  166. warnings: [],
  167. files: [],
  168. typesetting: []
  169. };
  170. this.lines.forEach(function(line) {
  171. var _, fileName, fullLine, lineMatch, lineNumber, match, message, messageType, newEntry, realMessage;
  172. match = line.match(LINE_SPLITTER_REGEX);
  173. if (match) {
  174. fullLine = match[0], lineNumber = match[1], messageType = match[2], message = match[3];
  175. newEntry = {
  176. file: '',
  177. level: MESSAGE_LEVELS[messageType] || "INFO",
  178. message: message,
  179. line: '',
  180. raw: fullLine
  181. };
  182. lineMatch = newEntry.message.match(/^BibTeX subsystem: \/.+\/(\w+\.\w+)_.+, line (\d+), (.+)$/);
  183. if (lineMatch && lineMatch.length === 4) {
  184. _ = lineMatch[0], fileName = lineMatch[1], lineNumber = lineMatch[2], realMessage = lineMatch[3];
  185. newEntry.file = fileName;
  186. newEntry.line = lineNumber;
  187. newEntry.message = realMessage;
  188. }
  189. result.all.push(newEntry);
  190. switch (newEntry.level) {
  191. case 'error':
  192. return result.errors.push(newEntry);
  193. case 'warning':
  194. return result.warnings.push(newEntry);
  195. }
  196. }
  197. });
  198. return result;
  199. };
  200. return this.parse = function() {
  201. var firstLine;
  202. firstLine = this.lines[0];
  203. if (firstLine.match(/^.*INFO - This is Biber.*$/)) {
  204. return this.parseBiber();
  205. } else if (firstLine.match(/^This is BibTeX, Version.+$/)) {
  206. return this.parseBibtex();
  207. } else {
  208. throw new Error("BibLogParser Error: cannot determine whether text is biber or bibtex output");
  209. }
  210. };
  211. }).call(BibLogParser.prototype);
  212. BibLogParser.parse = function(text, options) {
  213. return new BibLogParser(text, options).parse();
  214. };
  215. return BibLogParser;
  216. });