bib-log-parser.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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. if (iterationCount >= 10000) {
  27. return result;
  28. }
  29. newEntry = process(match);
  30. result.push(newEntry);
  31. text = (match.input.slice(0, match.index)) + (match.input.slice(match.index + match[0].length + 1, match.input.length));
  32. }
  33. return [result, text];
  34. };
  35. MULTILINE_WARNING_REGEX = /^Warning--(.+)\n--line (\d+) of file (.+)$/m;
  36. SINGLELINE_WARNING_REGEX = /^Warning--(.+)$/m;
  37. MULTILINE_ERROR_REGEX = /^(.*)---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this entry$/m;
  38. BAD_CROSS_REFERENCE_REGEX = /^(A bad cross reference---entry ".+?"\nrefers to entry.+?, which doesn't exist)$/m;
  39. MULTILINE_COMMAND_ERROR_REGEX = /^(.*)\n---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this command$/m;
  40. warningParsers = [
  41. [
  42. MULTILINE_WARNING_REGEX, function(match) {
  43. var fileName, fullMatch, lineNumber, message;
  44. fullMatch = match[0], message = match[1], lineNumber = match[2], fileName = match[3];
  45. return {
  46. file: fileName,
  47. level: "warning",
  48. message: message,
  49. line: lineNumber,
  50. raw: fullMatch
  51. };
  52. }
  53. ], [
  54. SINGLELINE_WARNING_REGEX, function(match) {
  55. var fullMatch, message;
  56. fullMatch = match[0], message = match[1];
  57. return {
  58. file: '',
  59. level: "warning",
  60. message: message,
  61. line: '',
  62. raw: fullMatch
  63. };
  64. }
  65. ]
  66. ];
  67. errorParsers = [
  68. [
  69. MULTILINE_ERROR_REGEX, function(match) {
  70. var fileName, firstMessage, fullMatch, lineNumber, secondMessage;
  71. fullMatch = match[0], firstMessage = match[1], lineNumber = match[2], fileName = match[3], secondMessage = match[4];
  72. return {
  73. file: fileName,
  74. level: "error",
  75. message: firstMessage + '\n' + secondMessage,
  76. line: lineNumber,
  77. raw: fullMatch
  78. };
  79. }
  80. ], [
  81. BAD_CROSS_REFERENCE_REGEX, function(match) {
  82. var fullMatch, message;
  83. fullMatch = match[0], message = match[1];
  84. return {
  85. file: '',
  86. level: "error",
  87. message: message,
  88. line: '',
  89. raw: fullMatch
  90. };
  91. }
  92. ], [
  93. MULTILINE_COMMAND_ERROR_REGEX, function(match) {
  94. var fileName, firstMessage, fullMatch, lineNumber, secondMessage;
  95. fullMatch = match[0], firstMessage = match[1], lineNumber = match[2], fileName = match[3], secondMessage = match[4];
  96. return {
  97. file: fileName,
  98. level: "error",
  99. message: firstMessage + '\n' + secondMessage,
  100. line: lineNumber,
  101. raw: fullMatch
  102. };
  103. }
  104. ]
  105. ];
  106. (function() {
  107. this.parseBibtex = function() {
  108. var allErrors, allWarnings, ref, ref1, remainingText, result;
  109. result = {
  110. all: [],
  111. errors: [],
  112. warnings: [],
  113. files: [],
  114. typesetting: []
  115. };
  116. ref = warningParsers.reduce(function(accumulator, parser) {
  117. var _remainingText, currentWarnings, process, ref, regex, text, warnings;
  118. currentWarnings = accumulator[0], text = accumulator[1];
  119. regex = parser[0], process = parser[1];
  120. ref = consume(text, regex, process), warnings = ref[0], _remainingText = ref[1];
  121. return [currentWarnings.concat(warnings), _remainingText];
  122. }, [[], this.text]), allWarnings = ref[0], remainingText = ref[1];
  123. ref1 = errorParsers.reduce(function(accumulator, parser) {
  124. var _remainingText, currentErrors, errors, process, ref1, regex, text;
  125. currentErrors = accumulator[0], text = accumulator[1];
  126. regex = parser[0], process = parser[1];
  127. ref1 = consume(text, regex, process), errors = ref1[0], _remainingText = ref1[1];
  128. return [currentErrors.concat(errors), _remainingText];
  129. }, [[], remainingText]), allErrors = ref1[0], remainingText = ref1[1];
  130. result.warnings = allWarnings;
  131. result.errors = allErrors;
  132. result.all = allWarnings.concat(allErrors);
  133. return result;
  134. };
  135. this.parseBiber = function() {
  136. var result;
  137. result = {
  138. all: [],
  139. errors: [],
  140. warnings: [],
  141. files: [],
  142. typesetting: []
  143. };
  144. this.lines.forEach(function(line) {
  145. var _, fileName, fullLine, lineMatch, lineNumber, match, message, messageType, newEntry, realMessage;
  146. match = line.match(LINE_SPLITTER_REGEX);
  147. if (match) {
  148. fullLine = match[0], lineNumber = match[1], messageType = match[2], message = match[3];
  149. newEntry = {
  150. file: '',
  151. level: MESSAGE_LEVELS[messageType] || "INFO",
  152. message: message,
  153. line: '',
  154. raw: fullLine
  155. };
  156. lineMatch = newEntry.message.match(/^BibTeX subsystem: \/.+\/(\w+\.\w+)_.+, line (\d+), (.+)$/);
  157. if (lineMatch && lineMatch.length === 4) {
  158. _ = lineMatch[0], fileName = lineMatch[1], lineNumber = lineMatch[2], realMessage = lineMatch[3];
  159. newEntry.file = fileName;
  160. newEntry.line = lineNumber;
  161. newEntry.message = realMessage;
  162. }
  163. result.all.push(newEntry);
  164. switch (newEntry.level) {
  165. case 'error':
  166. return result.errors.push(newEntry);
  167. case 'warning':
  168. return result.warnings.push(newEntry);
  169. }
  170. }
  171. });
  172. return result;
  173. };
  174. return this.parse = function() {
  175. var firstLine;
  176. firstLine = this.lines[0];
  177. if (firstLine.match(/^.*INFO - This is Biber.*$/)) {
  178. return this.parseBiber();
  179. } else if (firstLine.match(/^This is BibTeX, Version.+$/)) {
  180. return this.parseBibtex();
  181. } else {
  182. throw new Error("BibLogParser Error: cannot determine whether text is biber or bibtex output");
  183. }
  184. };
  185. }).call(BibLogParser.prototype);
  186. BibLogParser.parse = function(text, options) {
  187. return new BibLogParser(text, options).parse();
  188. };
  189. return BibLogParser;
  190. });