#!/usr/bin/env python # -*- coding: utf-8 -*- # # autolatex/utils/latex_log_parser.py # Copyright (C) 2013 Stephane Galland # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. #--------------------------------- # IMPORTS #--------------------------------- # Import standard python libs import os import re # Import AutoLaTeX libraries import utils #--------------------------------- # INTERNATIONALIZATION #--------------------------------- import gettext _T = gettext.gettext class TeXWarning: def __init__(self, filename, extension, line, message): self._data = {} if extension: self._filename = filename.strip()+extension else: self._filename = filename.strip() self._linenumber = line expr = re.compile("[\n\r\f\t ]+") self._message = re.sub(expr, ' ', message) def append(self, message): self._message = self._message + message def set_data(self, key, value): self._data[key] = value def get_data(self, key): return self._data[key] def get_all_data(self): return self._data def get_filename(self): return self._filename def get_line_number(self): return self._linenumber def get_message(self): return self._message def set_message(self, message): self._message = message def __str__(self): s = str(self._filename)+":"+str(self._linenumber)+":"+str(self._message)+"\n" if self._data: s = s + self._data return s class Parser: def __init__(self, log_file): self._directory = os.path.dirname(log_file) # self._warnings = [] # Parsing the log file regex_start = re.compile("^\\!\\!\\!\\!\\[BeginWarning\\](.*)$") regex_end = re.compile("^\\!\\!\\!\\!\\[EndWarning\\]") regex_warn = re.compile("^(.*?):([^:]*):([0-9]+):\\s*(.*?)\\s*$") f = open(log_file, 'r') current_log_block = '' warning = False line = f.readline() while line: if warning: mo = re.match(regex_end, line) if mo: mo = re.match(regex_warn, current_log_block) if mo: w = TeXWarning( mo.group(1), mo.group(2), mo.group(3), mo.group(4)) self._warnings.append(w) warning = False current_log_block = '' else: l = line if not l.endswith(".\n"): l = l.rstrip() current_log_block = current_log_block + l else: mo = re.match(regex_start, line) if mo: l = mo.group(1) if not l.endswith(".\n"): l = l.rstrip() current_log_block = l warning = True line = f.readline() if warning and current_log_block: mo = re.match(regex_warn, current_log_block) if mo: w = TeXWarning( mo.group(1), mo.group(2), mo.group(3), mo.group(4)) self._warnings.append(w) def __str__(self): text = "" for w in self._warnings: text = text + str(w) + "\n" return text def get_undefined_citation_warnings(self): regex = re.compile( "^.*citation\\s*\\`([^']+)\\'.+undefined.*$", re.I|re.S) warnings = [] for warning in self._warnings: message = warning.get_message() mo = re.match(regex, message) if mo: warning.set_message( warning.get_filename()+":"+ str(warning.get_line_number())+": "+ (_T("Citation '%s' undefined") % mo.group(1))) warnings.append(warning) return warnings def get_undefined_reference_warnings(self): regex = re.compile( "^.*reference\\s*\\`([^']+)\\'.+undefined.*$", re.I|re.S) warnings = [] for warning in self._warnings: message = warning.get_message() mo = re.match(regex, message) if mo: warning.set_message( warning.get_filename()+":"+ str(warning.get_line_number())+": "+ (_T("Reference '%s' undefined") % mo.group(1))) warnings.append(warning) return warnings def get_multidefined_label_warnings(self): regex = re.compile( "^.*label\\s*\\`([^']+)\\'.+multiply\\s+defined.*$", re.I|re.S) warnings = [] for warning in self._warnings: message = warning.get_message() mo = re.match(regex, message) if mo: warning.set_message( warning.get_filename()+":"+ str(warning.get_line_number())+": "+ (_T("Label '%s' multiply defined") % mo.group(1))) warnings.append(warning) return warnings