/*
Copyright (C) 2013-2020 Nicola L.C. Talbot
www.dickimaw-books.com
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 3 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; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.dickimawbooks.makeglossariesgui;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.nio.charset.Charset;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.Element;
public class Glossaries
{
public Glossaries(MakeGlossariesInvoker invoker, String istName, String order)
{
this.invoker = invoker;
this.istName = istName;
this.order = order;
glossaryList = new Vector<Glossary>();
}
public Glossaries(MakeGlossariesInvoker invoker)
{
this.invoker = invoker;
glossaryList = new Vector<Glossary>();
}
public void clear()
{
glossaryList.clear();
}
public void add(Glossary glossary)
{
glossaryList.add(glossary);
}
public Glossary getGlossary(int i)
{
return glossaryList.get(i);
}
public Glossary getGlossary(String label)
{
for (int i = 0, n = glossaryList.size(); i < n; i++)
{
Glossary g = glossaryList.get(i);
if (g.label.equals(label))
{
return g;
}
}
return null;
}
public static Glossaries loadGlossaries(MakeGlossariesInvoker invoker,
File file)
throws IOException
{
Glossaries glossaries = new Glossaries(invoker);
Hashtable<String,String> languages = new Hashtable<String,String>();
Hashtable<String,String> codePages = new Hashtable<String,String>();
invoker.getMessageSystem().message(
invoker.getLabelWithValues("message.loading", file));
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream(file), invoker.getEncoding()));
String line;
boolean override = invoker.getProperties().isOverride();
while ((line = in.readLine()) != null)
{
glossaries.parseAux(file.getParentFile(),
line, override, languages, codePages);
}
in.close();
if (glossaries.noidx)
{
glossaries.addDiagnosticMessage(invoker.getLabel("diagnostics.noidx"));
}
else if (glossaries.requiresBib2Gls && glossaries.istName == null)
{
String base = file.getName();
if (base.endsWith(".aux"))
{
base = base.substring(0, base.length()-4);
}
glossaries.addDiagnosticMessage(String.format("%s %s",
invoker.getLabelWithValues(
"diagnostics.bib2gls", base),
invoker.getLabel("diagnostics.build")));
if (!glossaries.hasRecords && !glossaries.selectionAllFound)
{
glossaries.addDiagnosticMessage(invoker.getLabel(
"diagnostics.bib2gls_norecords"));
}
// Is bib2gls on the system PATH?
File bib2gls = invoker.findApp("bib2gls", "bib2gls.exe", "bib2gls.sh");
if (bib2gls == null)
{
glossaries.addDiagnosticMessage(invoker.getLabelWithValues(
"error.missing_application", "bib2gls", System.getenv("PATH")));
}
else
{
glossaries.addDiagnosticMessage(invoker.getLabelWithValues(
"message.found", bib2gls));
}
}
else if (!override)
{
for (Enumeration<String> en = languages.keys(); en.hasMoreElements();)
{
String label = en.nextElement();
String language = languages.get(label);
Glossary g = glossaries.getGlossary(label);
if (g == null)
{
glossaries.addErrorMessage(invoker.getLabelWithValues(
"error.language_no_glossary", language, label));
glossaries.addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.language_no_glossary", language, label));
}
else
{
g.setLanguage(language);
}
}
for (Enumeration<String> en = codePages.keys(); en.hasMoreElements();)
{
String label = en.nextElement();
String code = codePages.get(label);
Glossary g = glossaries.getGlossary(label);
if (g == null)
{
glossaries.addErrorMessage(invoker.getLabelWithValues(
"error.codepage_no_glossary", code, label));
glossaries.addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.codepage_no_glossary", code, label));
}
else
{
g.setCodePage(code);
}
}
}
if (glossaries.requiresBib2Gls)
{
}
return glossaries;
}
private void parseAux(File dir, String line, boolean override,
Hashtable<String,String> languages, Hashtable<String,String> codePages)
throws IOException
{
Matcher matcher = newGlossaryPattern.matcher(line);
if (matcher.matches())
{
add(new Glossary(invoker, matcher.group(1), matcher.group(2),
matcher.group(3), matcher.group(4)));
return;
}
matcher = istFilePattern.matcher(line);
if (matcher.matches())
{
istName = matcher.group(1);
return;
}
matcher = bib2glsPattern.matcher(line);
if (matcher.matches())
{
requiresBib2Gls = true;
matcher = selectAllPattern.matcher(matcher.group(1));
if (matcher.matches())
{
selectionAllFound = true;
}
return;
}
matcher = orderPattern.matcher(line);
if (matcher.matches())
{
order = matcher.group(1);
return;
}
if (!override)
{
matcher = languagePattern.matcher(line);
if (matcher.matches())
{
String label = matcher.group(1);
String language = matcher.group(2);
if (language.isEmpty())
{
language = invoker.getDefaultLanguage();
String variant = invoker.getDefaultXindyVariant();
if (variant != null && !variant.isEmpty())
{
language = String.format("%s-%s", language, variant);
}
addErrorMessage(invoker.getLabelWithValues(
"error.no_language", label));
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.no_language", label, language));
}
languages.put(label, language);
return;
}
matcher = codepagePattern.matcher(line);
if (matcher.matches())
{
String label = matcher.group(1);
String code = matcher.group(2);
if (code.isEmpty())
{
code = invoker.getDefaultCodePage();
addErrorMessage(invoker.getLabelWithValues(
"error.no_codepage", label));
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.no_codepage", label, code));
}
codePages.put(label, code);
return;
}
}
matcher = glsreferencePattern.matcher(line);
if (matcher.matches())
{
noidx = true;
return;
}
matcher = glsrecordPattern.matcher(line);
if (matcher.matches())
{
hasRecords = true;
return;
}
matcher = extraMakeIndexOptsPattern.matcher(line);
if (matcher.matches())
{
String opts = matcher.group(1);
extraMakeIndexOpts = splitArgs(opts);
return;
}
matcher = inputPattern.matcher(line);
if (matcher.matches())
{
BufferedReader in = null;
String aux = matcher.group(1)+".aux";
String[] split = aux.split("/");
File f = dir;
for (int i = 0; i < split.length; i++)
{
f = new File(f, split[i]);
}
try
{
invoker.getMessageSystem().message(
invoker.getLabelWithValues("message.loading", f));
in = new BufferedReader(new InputStreamReader(
new FileInputStream(f), invoker.getEncoding()));
while ((line = in.readLine()) != null)
{
parseAux(f.getParentFile(), line, override, languages, codePages);
}
}
finally
{
if (in != null)
{
in.close();
}
}
return;
}
}
public static Vector<String> splitArgs(String str)
{
Vector<String> args = new Vector<String>();
StringBuilder builder = null;
int delim = -1;
for (int i = 0, n = str.length(); i < n; i++)
{
char c = str.charAt(i);
if (builder == null)
{
if (Character.isWhitespace(c))
{
continue;
}
builder = new StringBuilder();
if (c == '\'' || c == '"')
{
delim = c;
}
else
{
delim = -1;
builder.append(c);
}
}
else if (c == '\\')
{
i++;
if (i < n)
{
c = str.charAt(i);
}
builder.append(c);
}
else if (delim == c
|| (delim == -1 && Character.isWhitespace(c)))
{
args.add(builder.toString());
builder = null;
}
else
{
builder.append(c);
}
}
if (builder != null)
{
args.add(builder.toString());
}
return args;
}
public void process()
throws GlossaryException,IOException,InterruptedException
{
File file = invoker.getFile();
String baseName = file.getName();
int idx = baseName.lastIndexOf(".");
if (idx != -1)
{
baseName = baseName.substring(0, idx);
}
File dir = file.getParentFile();
Vector<Charset> indexerEncodings = new Vector<Charset>();
if (!noidx)
{
String mess = getIndexerError();
if (mess != null)
{
if (invoker.isBatchMode())
{
throw new GlossaryException(mess);
}
addErrorMessage(mess);
parseLog(dir, baseName);
return;
}
String lang = null;
String codePage = null;
if (invoker.getProperties().isOverride())
{
lang = invoker.getDefaultLanguage();
codePage = invoker.getDefaultCodePage();
String variant = invoker.getDefaultXindyVariant();
if (variant != null && !variant.isEmpty())
{
lang = String.format("%s-%s", lang, variant);
}
}
if (glossaryList.isEmpty())
{
addDiagnosticMessage(invoker.getLabel("diagnostics.no_glossaries"));
addErrorMessage(invoker.getLabel("error.no_glossaries"));
}
for (int i = 0, n = getNumGlossaries(); i < n; i++)
{
Glossary g = getGlossary(i);
try
{
if (useXindy())
{
if (lang != null)
{
g.setLanguage(lang);
}
if (codePage != null)
{
g.setCodePage(codePage);
}
g.xindy(dir, baseName, isWordOrder(), istName);
}
else
{
g.makeindex(dir, baseName, isWordOrder(), istName,
extraMakeIndexOpts);
}
String errMess = g.getErrorMessages();
if (errMess != null)
{
addErrorMessage(errMess);
}
}
catch (IOException e)
{
File istFile = new File(dir, istName);
if (!istFile.exists())
{
throw new GlossaryException(invoker.getLabelWithValues(
"error.no_ist", istName),
invoker.getLabel("diagnostics.no_ist"), e);
}
else
{
throw e;
}
}
Charset encoding = invoker.getEncoding();
if (!indexerEncodings.contains(encoding))
{
indexerEncodings.add(encoding);
}
}
}
// Skip the log file check when in batch mode
if (invoker.isBatchMode()) return;
parseLog(dir, baseName);
// Now the log has been parsed, the document encodings should
// be known (if support has been provided).
if (supportedEncodings == null)
{
// No document encoding detected, assume ASCII (which is
// fine for makeindex). Provide advisory note for xindy.
if (useXindy())
{
addAdvisoryMessage(invoker.getLabel(
"diagnostics.xindy_no_doc_encoding"));
}
}
else
{
for (Charset encoding: indexerEncodings)
{
if (!supportedEncodings.contains(encoding))
{
addAdvisoryMessage(invoker.getLabelWithValues(
"diagnostics.doc_indexer_encoding_mismatch", encoding,
supportedEncodings.size(), inputEnc));
}
}
}
}
public void parseLog(File dir, String baseName)
throws IOException
{
// Now check the log file for any problems
File log = new File(dir, baseName+".log");
if (!log.exists())
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.no_log", log.getAbsolutePath()));
// Are there other .aux files in the same directory?
File[] list = dir.listFiles(new FileFilter()
{
public boolean accept(File f)
{
return f.getName().toLowerCase().endsWith(".aux");
}
});
if (list != null && list.length > 1)
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.multi_aux", dir));
}
return;
}
BufferedReader reader = null;
boolean checkNonAscii = false;
String vers = null;
String build = null;
int makeglossDisabledLine = -1;
int makeglossRestoredLine = -1;
try
{
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(log), invoker.getEncoding()));
String line;
while ((line = reader.readLine()) != null)
{
Matcher m;
if (istName == null && line.startsWith("Package glossaries Info:") && !line.endsWith("."))
{
String nextLine;
while ((nextLine = reader.readLine()) != null)
{
line += nextLine;
if (nextLine.endsWith("."))
{
break;
}
}
// Need to determine which option was the last in
// effect but line numbers may refer to different files.
m = makeglossDisabledPattern.matcher(line);
if (m.matches())
{
String lineRef = m.group(1);
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.makeglossdisabled", lineRef));
makeglossDisabledLine = 1;
if (makeglossRestoredLine > -1)
{
makeglossRestoredLine = 0;
}
}
m = makeglossRestoredPattern.matcher(line);
if (m.matches())
{
String lineRef = m.group(1);
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.makeglossrestored", lineRef));
makeglossRestoredLine = 1;
if (makeglossDisabledLine > -1)
{
makeglossDisabledLine = 0;
}
}
}
if (latexFormat == null)
{
m = formatPattern.matcher(line);
if (m.matches())
{
latexFormat = m.group(1);
if (latexFormat.startsWith("xe")
|| latexFormat.startsWith("lua"))
{
addSupportedEncoding("utf8");
}
continue;
}
}
m = inputEncPattern.matcher(line);
if (m.matches())
{
addSupportedEncoding(m.group(1));
continue;
}
m = glossariesStyPattern.matcher(line);
if (m.matches())
{
Calendar cal = Calendar.getInstance();
String year = m.group(1);
String mon = m.group(2);
String day = m.group(3);
vers = m.group(4);
try
{
cal.set(Integer.parseInt(year),
Integer.parseInt(mon),
Integer.parseInt(day));
}
catch (NumberFormatException e)
{// shouldn't happen
invoker.getMessageSystem().debug(e);
}
Calendar v416 = Calendar.getInstance();
v416.set(2015, 7, 8);
if (cal.before(v416))
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.oldversion", vers,
// use same format as LaTeX package info:
String.format("%s/%s/%s", year, mon, day)
));
}
continue;
}
m = wrongGloTypePattern.matcher(line);
if (m.matches())
{
String type = m.group(2);
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.wrong_type", type));
addErrorMessage(invoker.getLabelWithValues(
"error.wrong_type", type));
continue;
}
if (invoker.isDocDefCheckOn())
{
m = docDefsPattern.matcher(line);
if (m.matches())
{
File f = new File(dir, baseName+".glsdefs");
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.doc_defs", f.getAbsolutePath()));
continue;
}
}
if (invoker.isMissingLangCheckOn())
{
m = missingLangPattern.matcher(line);
if (m.matches())
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.missing_lang", m.group(1)));
continue;
}
}
m = missingStyPattern.matcher(line);
if (m.matches())
{
String sty = m.group(1);
if (sty.equals("datatool-base"))
{
addDiagnosticMessage(invoker.getLabel(
"diagnostics.missing_datatool_base"));
}
else
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.missing_sty", sty));
}
continue;
}
m = glsGroupHeadingPattern.matcher(line);
if (m.matches())
{
String val = m.group(1);
if (!problemGroupLabels.contains(val))
{
addDiagnosticMessage(String.format("%s<pre>%s</pre>%s",
invoker.getLabelWithValues(
"diagnostics.problem_group_label", val),
invoker.escapeHTML(line),
invoker.getLabel(isUnicodeEngine() ?
"diagnostics.suggest_bib2gls" :
"diagnostics.suggest_unicode_or_bib2gls")));
problemGroupLabels.add(val);
}
continue;
}
m = warningPattern.matcher(line);
if (m.matches())
{
StringBuilder builder = new StringBuilder(line);
while ((line = reader.readLine()) != null)
{
if (line.isEmpty())
{
break;
}
builder.append(line);
}
String msg = builder.toString();
if (msg.contains("Package inputenc Error: Unicode char"))
{
// If a warning message contains this, it's likely
// that an entry label contains non-ASCII
// characters.
checkNonAscii = true;
continue;
}
if (requiresBib2Gls)
{
m = missingGlsTeXPattern.matcher(msg);
if (m.matches())
{
addDiagnosticMessage(invoker.getLabelWithValues(
istName == null ? "diagnostics.missing_glstex" :
"diagnostics.missing_glstex_hybrid",
m.group(1)));
if (build == null)
{
if (istName == null)
{
build = invoker.getLabelWithValues(
"diagnostics.bib2gls_build", getLaTeXFormat(),
baseName
);
}
else
{
build = invoker.getLabelWithValues(
"diagnostics.hybrid_build", getLaTeXFormat(),
baseName,
"makeglossaries"
);
}
addDiagnosticMessage(build);
}
continue;
}
}
addDiagnosticMessage(msg);
if (noidx)
{
m = emptyNoIdxGlossaryPattern.matcher(msg);
if (m.matches())
{
String type = m.group(1);
if (!glossaryList.contains(type))
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.wrong_type_noidx", type));
}
}
}
continue;
}
m = systemPattern.matcher(line);
if (m.matches())
{
StringBuilder builder = new StringBuilder(line);
while (!line.endsWith(".") && (line = reader.readLine()) != null)
{
if (line.isEmpty())
{
break;
}
builder.append(line);
}
m = disabledSystemPattern.matcher(builder);
if (m.matches())
{
String cmd = m.group(1);
String rest = m.group(2);
if (m.groupCount() == 2)
{
addAdvisoryMessage(invoker.getLabelWithValues(
"diagnostics.shell_disabled", cmd+rest));
}
else
{
addAdvisoryMessage(invoker.getLabelWithValues(
"diagnostics.shell_restricted", cmd+rest, cmd));
}
}
continue;
}
m = undefControlSequencePattern.matcher(line);
if (m.matches())
{
line = reader.readLine();
m = fragileBrokenPattern.matcher(line);
if (m.matches())
{
addDiagnosticMessage(invoker.getLabel(
"diagnostics.fragile"));
continue;
}
if (line.contains("\\GenericError"))
{
// Too complicated, so don't show to avoid
// overcluttering the diagnostic panel.
continue;
}
if (line.endsWith("\\indexspace "))
{
addDiagnosticMessage(invoker.getLabel(
"diagnostics.undef_indexspace"));
continue;
}
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.undef_cs", line));
continue;
}
m = unknownOptPattern.matcher(line);
if (m.matches())
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.undef_opt", m.group(1)));
continue;
}
m = infoPattern.matcher(line);
if (m.matches())
{
StringBuilder builder = new StringBuilder(m.group(1));
while (!line.endsWith(".")
&& (line = reader.readLine()) != null
&& !line.isEmpty())
{
builder.append(line);
}
m = wrglossaryPattern.matcher(builder);
if (m.matches())
{
String type = m.group(1);
String info = m.group(2);
String lineNum = m.group(3);
addDiagnosticMessage(String.format("%s%n<pre>%s</pre>%n",
invoker.getLabelWithValues(
"diagnostics.wrglossary", type, lineNum),
info));
}
continue;
}
m = inputPattern.matcher(line);
if (m.matches())
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.include", m.group(1)));
continue;
}
m = istFilePattern.matcher(line);
if (m.matches())
{
addDiagnosticMessage(invoker.getLabel(
"diagnostics.ist_in_log"));
continue;
}
}
}
finally
{
if (reader != null)
{
reader.close();
}
}
if (makeglossDisabledLine > -1)
{
if (makeglossRestoredLine == -1)
{
addDiagnosticMessage(invoker.getLabel("diagnostics.restoremakegloss"));
}
else if (makeglossRestoredLine < makeglossDisabledLine)
{
addDiagnosticMessage(
invoker.getLabel("diagnostics.restoremakegloss.cancelled"));
}
else
{
addDiagnosticMessage(
invoker.getLabel("diagnostics.restoremakegloss.late"));
}
}
if (vers == null)
{
addDiagnosticMessage(invoker.getLabel(
"diagnostics.no_version"));
}
if (checkNonAscii)
{
addDiagnosticMessage(invoker.getLabel(
"diagnostics.inputenc"));
for (int i = 0, n = glossaryList.size(); i < n; i++)
{
Glossary glossary = glossaryList.get(i);
glossary.checkNonAsciiLabels();
}
}
}
public String getLaTeXFormat()
{
return latexFormat == null ? "latex" : latexFormat;
}
public boolean isUnicodeEngine()
{
if (latexFormat == null)
{
return false;
}
return latexFormat.startsWith("xe") || latexFormat.startsWith("lua");
}
public String displayGlossaryList()
{
String str = null;
for (int i = 0, n = glossaryList.size(); i < n; i++)
{
Glossary glossary = glossaryList.get(i);
if (str == null)
{
str = glossary.label;
}
else
{
str += ", " + glossary.label;
}
}
return str;
}
public String getDisplayGlossaryListError()
{
return getNumGlossaries() == 0 ?
invoker.getLabel("error.no_glossaries"):
null;
}
public String displayEncoding()
{
return invoker.getEncoding().name();
}
private void addSupportedEncoding(String encLabel)
{
Charset charset = invoker.getCharset(encLabel);
if (charset == null)
{
addDiagnosticMessage(invoker.getLabelWithValues(
"diagnostics.unknown.encoding", encLabel));
}
else
{
if (supportedEncodings == null)
{
supportedEncodings = new Vector<Charset>();
}
supportedEncodings.add(charset);
}
if (inputEnc == null)
{
inputEnc = encLabel;
}
else
{
inputEnc = String.format("%s, %s", inputEnc, encLabel);
}
}
public String displayDocumentEncoding()
{
return inputEnc == null ? invoker.getLabel("error.unknown") : inputEnc;
}
public String getOrder()
{
return order;
}
public boolean isWordOrder()
{
if (order == null) return false;
return order.equals("word");
}
public boolean isLetterOrder()
{
if (order == null) return false;
return order.equals("letter");
}
public boolean isValidOrder()
{
if (order == null) return false;
return order.equals("word") || order.equals("letter");
}
public String getOrderError()
{
if (order == null) return invoker.getLabel("error.missing_order");
return isValidOrder() ? null
: invoker.getLabelWithValues("error.invalid_order", order);
}
public String displayFormat()
{
if (istName == null)
{
if (requiresBib2Gls)
{
return "bib2gls";
}
else
{
return invoker.getLabel("error.unknown");
}
}
return useXindy() ? "xindy" : "makeindex";
}
public String getIstName()
{
return istName;
}
public String getIstNameError()
{
return istName == null ? invoker.getLabel("error.missing_ist") : null;
}
public boolean useXindy()
{
if (istName == null) return false;
return istName.endsWith(".xdy");
}
public String getIndexerError()
{
if (noidx) return null;
if (istName == null)
{
return
invoker.getLabel(requiresBib2Gls ? "error.bib2gls_indexer" :
"error.cant_determine_indexer");
}
if (useXindy())
{
if (invoker.getXindyApp() == null)
{
return invoker.getLabel("error.no_xindy");
}
}
else
{
if (invoker.getMakeIndexApp() == null)
{
return invoker.getLabel("error.no_makeindex");
}
}
return null;
}
public int getNumGlossaries()
{
return glossaryList.size();
}
public String getDiagnostics()
{
String mess;
if (!noidx && istName == null && order == null)
{
mess = getDiagnosticMessages();
if (mess != null)
{
return mess;
}
else if (glossaryList.size() == 0)
{
return invoker.getFileName().toLowerCase().endsWith(".aux") ?
invoker.getLabel("diagnostics.no_glossaries"):
invoker.getLabel("diagnostics.not_aux");
}
else
{
return invoker.getLabel("diagnostics.no_makeglossaries");
}
}
mess = getIndexerError();
if (mess != null)
{
return String.format("%s%n%s", mess,
invoker.getLabelWithValues("diagnostics.no_indexer",
displayFormat()));
}
mess = getDiagnosticMessages();
for (int i = 0, n = getNumGlossaries(); i < n; i++)
{
String errmess = getGlossary(i).getDiagnosticMessages();
if (errmess != null)
{
if (mess == null)
{
mess = errmess;
}
else
{
mess = String.format("%s%n<p>%s", mess, errmess);
}
}
}
return mess;
}
private String getDiagnosticMessages()
{
return diagnosticMessages == null ? null : diagnosticMessages.toString();
}
public void addDiagnosticMessage(String mess)
{
if (diagnosticMessages == null)
{
diagnosticMessages = new StringBuilder(mess);
}
else
{
diagnosticMessages.append(String.format("<p>%s", mess));
}
}
public String getAdvisoryMessages()
{
return advisoryMessages == null ? null : advisoryMessages.toString();
}
public void addAdvisoryMessage(String mess)
{
if (advisoryMessages == null)
{
advisoryMessages = new StringBuilder(mess);
}
else
{
advisoryMessages.append(String.format("<p>%s", mess));
}
}
public void addErrorMessage(String mess)
{
if (errorMessages == null)
{
errorMessages = new StringBuilder(mess);
}
else
{
errorMessages.append(String.format("%n%s", mess));
}
}
public String getErrorMessages()
{
return errorMessages == null ? null : errorMessages.toString();
}
public static int getNumFields()
{
return fields.length;
}
public static String getFieldTag(int i)
{
return fields[i];
}
public static Element getFieldElement(HTMLDocument doc, int i)
{
return doc.getElement(fields[i]);
}
public static Element getFieldLabelElement(HTMLDocument doc, int i)
{
return doc.getElement(fields[i]+"label");
}
public String getFieldLabel(int i)
{
return invoker.getLabel("main", fields[i]);
}
public String getField(int i)
{
switch (i)
{
case AUX: return invoker.getFileName();
case ORDER: return getOrder();
case IST: return getIstName();
case INDEXER: return displayFormat();
case GLOSSARIES: return displayGlossaryList();
case ENCODING: return displayEncoding();
case DOC_ENCODING: return displayDocumentEncoding();
}
return null;
}
public String getFieldError(int i)
{
switch (i)
{
case AUX: return invoker.getFileName() == null ?
invoker.getLabel("error.no_such_file") :
null;
case ORDER: return getOrderError();
case IST: return getIstNameError();
case INDEXER: return getIndexerError();
case GLOSSARIES: return getDisplayGlossaryListError();
}
return null;
}
private Vector<Glossary> glossaryList;
private String istName;
private Vector<String> extraMakeIndexOpts;
private boolean noidx = false;
private String order;
private boolean requiresBib2Gls = false;
private StringBuilder errorMessages, diagnosticMessages, advisoryMessages;
private static final Pattern newGlossaryPattern
= Pattern.compile("\\\\@newglossary\\{([^\\}]+)\\}\\{([^\\}]+)\\}\\{([^\\}]+)\\}\\{([^\\}]+)\\}");
private static final Pattern istFilePattern
= Pattern.compile("\\\\@istfilename\\{([^\\}]+)\\}");
private static final Pattern bib2glsPattern
= Pattern.compile("\\\\glsxtr@resource\\{(.*)\\}\\{(.*?)\\}");
private static final Pattern selectAllPattern
= Pattern.compile(".*selection\\s*=\\s*(all|\\{all\\}).*");
private static final Pattern orderPattern
= Pattern.compile("\\\\@glsorder\\{([^\\}]+)\\}");
private static final Pattern languagePattern
= Pattern.compile("\\\\@xdylanguage\\{([^\\}]+)\\}\\{([^\\}]*)\\}");
private static final Pattern codepagePattern
= Pattern.compile("\\\\@gls@codepage\\{([^\\}]+)\\}\\{([^\\}]*)\\}");
private static final Pattern glsreferencePattern
= Pattern.compile("\\\\@gls@reference\\{.*?\\}\\{.*?\\}\\{.*\\}");
private static final Pattern glsrecordPattern
= Pattern.compile("\\\\glsxtr@record\\{.*?\\}\\{.*?\\}\\{.*\\}");
private static final Pattern extraMakeIndexOptsPattern
= Pattern.compile("\\\\@gls@extramakeindexopts\\{(.*)\\}");
private static final Pattern glossariesStyPattern
= Pattern.compile("Package: glossaries (\\d+)\\/(\\d+)\\/(\\d+) v([\\d\\.a-z]+) \\(NLCT\\).*");
private static final Pattern glossariesXtrStyPattern
= Pattern.compile("Package: glossaries-extra (\\d+)\\/(\\d+)\\/(\\d+) v([\\d\\.a-z]+) \\(NLCT\\).*");
private static final Pattern wrongGloTypePattern
= Pattern.compile("No file (.*?)\\.\\\\@glotype@(.*?)@in\\s*\\.");
private static final Pattern docDefsPattern
= Pattern.compile("\\\\openout\\d+\\s*=\\s*`.*\\.glsdefs'.");
private static final Pattern missingLangPattern
= Pattern.compile("Package glossaries Warning: No language module detected for `(.*)'.\\s*");
private static final Pattern missingStyPattern
= Pattern.compile(".*`(.*?)\\.sty' not found.*");
private static final Pattern missingGlsTeXPattern
= Pattern.compile(".*No file `(.*?\\.glstex)'.*");
private static final Pattern warningPattern
= Pattern.compile("Package glossaries(-extra)? Warning: .*");
private static final Pattern emptyNoIdxGlossaryPattern
= Pattern.compile(".*Empty glossary for \\\\printnoidxglossary\\[type=\\{(.*?)\\}\\]\\..*");
private static final Pattern systemPattern
= Pattern.compile("runsystem\\(.*");
private static final Pattern disabledSystemPattern
= Pattern.compile("runsystem\\(([^ ]+)(.*)\\)\\.\\.\\.disabled(\\s+\\(restricted\\))?\\.");
private static final Pattern undefControlSequencePattern
= Pattern.compile(".* Undefined control sequence.");
private static final Pattern fragileBrokenPattern
= Pattern.compile(".*\\\\in@ #1#2->\\\\begingroup \\\\def \\\\in@@\\s*");
private static final Pattern unknownOptPattern
= Pattern.compile(".*Unknown option `(.*)' for package `glossaries'.*");
private static final Pattern infoPattern
= Pattern.compile("Package glossaries Info:\\s*(.*)");
private static final Pattern wrglossaryPattern
= Pattern.compile("wrglossary\\((.*?)\\)\\((.*)\\) on input line (\\d+).*");
private static final Pattern inputPattern
= Pattern.compile("\\\\@input\\{(.*)\\.aux\\}");
private static final Pattern formatPattern
= Pattern.compile(".* format=(xelatex|lualatex|pdflatex|latex) .*");
private static final Pattern inputEncPattern
= Pattern.compile("File: (utf8|latin[0-9]+|cp[0-9]+(?:de)?|decmulti|applemac|macce|next|ansinew|ascii)\\.def.*");
private static final Pattern glsGroupHeadingPattern
= Pattern.compile(".*\\\\glsgroupheading\\{(.+?)\\}.*");
private static final Pattern makeglossDisabledPattern = Pattern.compile(
"Package glossaries Info: \\\\makeglossaries and \\\\makenoidxglossaries have been disabled on input line ([0-9]+)\\.");
private static final Pattern makeglossRestoredPattern = Pattern.compile(
"Package glossaries Info: \\\\makeglossaries and \\\\makenoidxglossaries have been restored on input line ([0-9]+)\\.");
private Vector<String> problemGroupLabels = new Vector<String>();
private static final String[] fields =
{
"aux",
"order",
"ist",
"indexer",
"list",
"encoding",
"docencoding"
};
public static final int AUX=0, ORDER=1, IST=2, INDEXER=3, GLOSSARIES=4,
ENCODING=5, DOC_ENCODING=6;
private String latexFormat = null;
private String inputEnc = null;
private Vector<Charset> supportedEncodings;
private MakeGlossariesInvoker invoker;
private boolean hasRecords = false;
private boolean selectionAllFound = false;
}