#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# autolatex/utils/latex_log_parser.py
# Copyright (C) 2013 Stephane Galland <
[email protected]>
#
# 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