/*
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.io.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MakeGlossariesInvoker
{
public MakeGlossariesInvoker()
{
setMessageSystem(new GlossaryBatchMessage(this));
try
{
loadDictionary();
}
catch (IOException e)
{
getMessageSystem().error(
String.format("Unable to load dictionary file:%n%s",
e.getMessage()));
}
initLanguageMappings();
try
{
properties = MakeGlossariesProperties.fetchProperties();
}
catch (IOException e)
{
getMessageSystem().error(
getLabelWithValues("error.prop_io", e.getMessage()));
properties = new MakeGlossariesProperties();
}
}
public void setFile(File file)
{
setFile(file.getAbsolutePath());
}
public void setFile(String filename)
{
if (filename.toLowerCase().endsWith(".tex"))
{
int idx = filename.length()-4;
filename = filename.substring(0, idx)+".aux";
}
else if (!filename.endsWith(".aux"))
{
filename = filename+".aux";
}
currentFileName = filename;
}
public void load(File file)
{
String lc = file.getName().toLowerCase();
if (lc.endsWith(".tex") || lc.endsWith(".log"))
{
int idx = file.getName().length()-4;
file = new File(file.getParentFile(),
file.getName().substring(0, idx)+".aux");
}
setFile(file);
reload(file);
}
public void reload()
{
reload(new File(currentFileName));
}
public void reload(File file)
{
if (!file.exists())
{
// Does the log file exists?
File log = null;
String name = file.getName();
if (!isBatchMode() && name.toLowerCase().endsWith(".aux"))
{
name = name.substring(0, name.length()-4);
log = new File(file.getParentFile(), name+".log");
if (!log.exists())
{
log = null;
}
else
{
glossaries = new Glossaries(this);
glossaries.addDiagnosticMessage(
getLabel("diagnostics.no_aux"));
glossaries.addErrorMessage(getLabelWithValues(
"error.io.file_doesnt_exist", file));
try
{
glossaries.parseLog(log.getParentFile(), name);
}
catch (Exception e)
{
getMessageSystem().error(e);
}
getMessageSystem().showMessages();
}
}
if (log == null)
{
getMessageSystem().error(getLabelWithValues(
"error.io.file_doesnt_exist", file.getAbsolutePath()));
}
return;
}
try
{
glossaries = Glossaries.loadGlossaries(this, file);
glossaries.process();
}
catch (InterruptedException e)
{
getMessageSystem().error(e);
}
catch (GlossaryException e)
{
String mess = e.getDiagnosticMessage();
if (mess != null)
{
glossaries.addDiagnosticMessage(mess);
}
getMessageSystem().message(e);
}
catch (IOException e)
{
glossaries.addDiagnosticMessage(getLabel("diagnostics.io_error"));
getMessageSystem().error(e);
}
String errMess = glossaries.getErrorMessages();
if (errMess != null)
{
getMessageSystem().error(errMess);
}
getMessageSystem().showMessages();
}
public void setMessageSystem(GlossaryMessage msg)
{
messageSystem = msg;
}
public GlossaryMessage getMessageSystem()
{
return messageSystem;
}
public static String escapeHTML(String text)
{
if (text == null || text.isEmpty()) return "";
int n = text.length();
StringBuilder builder = new StringBuilder(n);
for (int i = 0; i < n; i++)
{
char c = text.charAt(i);
if (c == '&')
{
builder.append("&");
}
else if (c == '<')
{
builder.append("<");
}
else if (c == '>')
{
builder.append(">");
}
else
{
builder.append(c);
}
}
return builder.toString();
}
public String getLabelOrDef(String label, String alt)
{
if (messages == null)
{
return alt;
}
String val = messages.getMessageIfExists(label);
return val == null ? alt : val;
}
public String getLabel(String label)
{
return getLabel(null, label);
}
public String getLabel(String parent, String label)
{
if (messages == null)
{
messageSystem.debug("Dictionary not loaded.");
return null;
}
String propLabel;
if (parent == null)
{
propLabel = label;
}
else
{
propLabel = String.format("%s.%s", parent, label);
}
return messages.getMessage(propLabel);
}
public int getMnemonic(String label)
{
return getMnemonic(null, label);
}
public int getMnemonic(String parent, String label)
{
if (messages == null)
{
messageSystem.debug("Dictionary not loaded.");
return -1;
}
String propLabel = label+".mnemonic";
if (parent != null)
{
propLabel = String.format("%s.%s", parent, propLabel);
}
String val = messages.getMessageIfExists(propLabel);
if (val == null || val.isEmpty())
{
return -1;
}
return val.codePointAt(0);
}
public String getLabelWithValues(String label, Object... values)
{
if (messages == null)
{
return null;
}
return messages.getMessage(label, values);
}
public MakeGlossariesProperties getProperties()
{
return properties;
}
public boolean isDocDefCheckOn()
{
return properties.isDocDefsCheckOn();
}
public boolean isMissingLangCheckOn()
{
return properties.isMissingLangCheckOn();
}
public String getDefaultLanguage()
{
return properties.getDefaultLanguage();
}
public String getDefaultXindyVariant()
{
return properties.getDefaultXindyVariant();
}
public String getDefaultCodePage()
{
return properties.getDefaultCodePage();
}
// Convert xindy and inputenc encoding labels to Charset
// Uses String.contains rather than String.equals as
// the xindy codepage may contain additional information,
// such as din5007-
public static Charset getCharset(String encodingLabel)
throws IllegalCharsetNameException,
IllegalArgumentException,
UnsupportedCharsetException
{
if (encodingLabel == null)
{
throw new IllegalArgumentException(
"Illegal encoding label (null)");
}
if (encodingLabel.contains("utf8"))
{
return StandardCharsets.UTF_8;
}
if (encodingLabel.contains("ascii"))
{
return Charset.forName("US-ASCII");
}
if (encodingLabel.contains("latin10"))
{
return Charset.forName("ISO-8859-16");
}
if (encodingLabel.contains("latin1"))
{
return StandardCharsets.ISO_8859_1;
}
if (encodingLabel.contains("latin2"))
{
return Charset.forName("ISO-8859-2");
}
if (encodingLabel.contains("latin3"))
{
return Charset.forName("ISO-8859-3");
}
if (encodingLabel.contains("latin4"))
{
return Charset.forName("ISO-8859-4");
}
if (encodingLabel.contains("latin5"))
{
return Charset.forName("ISO-8859-9");
}
if (encodingLabel.contains("latin6"))
{
return Charset.forName("ISO-8859-10");
}
if (encodingLabel.contains("latin7"))
{
return Charset.forName("ISO-8859-13");
}
if (encodingLabel.contains("latin8"))
{
return Charset.forName("ISO-8859-14");
}
if (encodingLabel.contains("latin9"))
{
return Charset.forName("ISO-8859-15");
}
if (encodingLabel.contains("cp1250"))
{
return Charset.forName("Cp1250");
}
if (encodingLabel.contains("cp1252")
|| encodingLabel.contains("ansinew"))
{
return Charset.forName("Cp1252");
}
if (encodingLabel.contains("cp1257"))
{
return Charset.forName("Cp1257");
}
if (encodingLabel.contains("cp437"))
{
return Charset.forName("Cp437");
}
if (encodingLabel.contains("cp850"))
{
return Charset.forName("Cp850");
}
if (encodingLabel.contains("cp852"))
{
return Charset.forName("Cp852");
}
if (encodingLabel.contains("cp858"))
{
return Charset.forName("Cp858");
}
if (encodingLabel.contains("cp865"))
{
return Charset.forName("Cp865");
}
if (encodingLabel.contains("decmulti"))
{
return Charset.forName("DEC-MCS");
}
if (encodingLabel.contains("applemac"))
{
return Charset.forName("MacRoman");
}
if (encodingLabel.contains("macce"))
{
return Charset.forName("MacCentralEurope");
}
// don't know appropriate Java name for inputenc's 'next'
return null;
}
// indexer character encoding
public Charset getEncoding()
{
return defaultCharset;
}
public void setEncoding(Charset charset)
{
defaultCharset = charset;
}
private void loadDictionary()
throws IOException
{
Locale locale = Locale.getDefault();
String lang = locale.getLanguage();
String resource = "/resources/dictionaries/makeglossariesgui-"
+lang+".prop";
InputStream in = getClass().getResourceAsStream(resource);
if (in == null && !lang.equals("en"))
{
resource = "/resources/dictionaries/makeglossariesgui-en.prop";
in = getClass().getResourceAsStream(resource);
}
BufferedReader reader = null;
try
{
Charset defCharset = Charset.defaultCharset();
reader = new BufferedReader(new InputStreamReader(in, defCharset));
// First line should be # Encoding: <encoding name>
Charset charset = null;
String encoding=null;
try
{
String line = reader.readLine();
Pattern p = Pattern.compile("# Encoding: (.+)");
Matcher m = p.matcher(line);
if (!m.matches())
{
throw new InvalidSyntaxException(
"Missing encoding comment on line 1 of dictionary file: !"
+ resource);
}
encoding = m.group(1);
charset = Charset.forName(encoding);
}
catch (UnsupportedCharsetException|IllegalCharsetNameException e)
{
throw new InvalidSyntaxException(String.format(
"Invalid encoding '%s' on line 1 of dictionary file: !%s",
encoding, resource), e);
}
if (!charset.equals(defCharset))
{
reader.close();
reader = new BufferedReader(new InputStreamReader(in, charset));
}
Properties dictionary = new Properties();
dictionary.load(reader);
messages = new MakeGlossariesDictionary(dictionary);
}
finally
{
if (reader != null)
{
reader.close();
}
in.close();
}
}
public Glossaries getGlossaries()
{
return glossaries;
}
public String getFileName()
{
return currentFileName;
}
public File getFile()
{
return currentFileName == null ? null : new File(currentFileName);
}
public File getCurrentDirectory()
{
if (currentFileName == null)
{
return new File(properties.getDefaultDirectory());
}
File file = getFile().getParentFile();
if (file == null)
{
file = new File(properties.getDefaultDirectory());
}
return file;
}
public String getCurrentDirectoryName()
{
return getCurrentDirectory().getAbsolutePath();
}
public String getXindyApp()
{
return properties.getXindyApp();
}
public String getMakeIndexApp()
{
return properties.getMakeIndexApp();
}
private void initLanguageMappings()
{
languageMap = new Hashtable<String,String>();
languageMap.put("american", "english");
languageMap.put("british", "english");
languageMap.put("francais", "french");
languageMap.put("frenchb", "french");
languageMap.put("germanb", "german");
languageMap.put("magyar", "hungarian");
languageMap.put("ngermanb", "german");
languageMap.put("ngerman", "german");
languageMap.put("norsk", "norwegian");
languageMap.put("portuges", "portuguese");
languageMap.put("russianb", "russian");
languageMap.put("UKenglish", "english");
languageMap.put("ukraineb", "ukrainian");
languageMap.put("USenglish", "english");
languageMap.put("usorbian", "upper-sorbian");
}
public String getLanguage(String language)
{
String map = languageMap.get(language);
return map == null ? language : map;
}
public File findApp(String name)
{
return findApp(name, name+".exe", null);
}
public File findApp(String name, String altName, String altName2)
{
String filename = name;
String filename2 = (altName == null ? null : altName);
String filename3 = (altName2 == null ? null : altName2);
String path = System.getenv("PATH");
String[] split = path.split(File.pathSeparator);
for (int i = 0; i < split.length; i++)
{
File file = new File(split[i], filename);
if (file.exists())
{
return file;
}
if (filename2 != null)
{
file = new File(split[i], filename2);
if (file.exists())
{
return file;
}
}
if (filename3 != null)
{
file = new File(split[i], filename3);
if (file.exists())
{
return file;
}
}
}
return null;
}
public void help()
{
System.out.println(getLabel("syntax.cmdline"));
System.out.println();
System.out.println(getLabelWithValues("syntax.filename", "--batch"));
System.out.println();
System.out.println(getLabel("syntax.options"));
System.out.println();
System.out.println(getLabelWithValues("syntax.help", "--help", "-h"));
System.out.println(getLabelWithValues("syntax.version",
"--version", "-v"));
System.out.println(getLabelWithValues("syntax.debug", "--debug"));
System.out.println(getLabelWithValues("syntax.dryrun", "--dry-run",
"-n"));
System.out.println(getLabelWithValues("syntax.nodryrun", "--nodry-run"));
System.out.println(getLabelWithValues("syntax.batch", "--batch", "-b"));
System.out.println(getLabelWithValues("syntax.gui", "--gui"));
System.out.println(getLabelWithValues("syntax.quiet", "--quiet"));
}
public void version()
{
String translator = getLabelOrDef("about.translator_info", null);
System.out.println(APP_NAME);
System.out.println(getLabelWithValues("about.version",
APP_VERSION, APP_DATE));
System.out.println(getLabelWithValues("about.copyright",
"Nicola L. C. Talbot",
String.format("2011-%s", APP_DATE.substring(0, 4))));
System.out.println("
https://www.dickimaw-books.com/");
if (translator != null && !translator.isEmpty())
{
System.out.println(translator);
}
}
public boolean isQuiet()
{
return quiet;
}
public void setQuietMode(boolean isSet)
{
quiet = isSet;
}
public boolean isDebugMode()
{
return debug;
}
public void setDebugMode(boolean isSet)
{
debug = isSet;
}
public boolean isBatchMode()
{
return batchMode;
}
public void setDryRunMode(boolean isDryRun)
{
dryRun = isDryRun;
}
public boolean isDryRunMode()
{
return dryRun;
}
public static void main(String[] args)
{
MakeGlossariesInvoker invoker = new MakeGlossariesInvoker();
for (int i = 0; i < args.length; i++)
{
if (args[i].equals("--help") || args[i].equals("-h"))
{
invoker.batchMode = true;
invoker.help();
System.exit(0);
}
else if (args[i].equals("--version") || args[i].equals("-v"))
{
invoker.batchMode = true;
invoker.version();
System.exit(0);
}
else if (args[i].equals("--batch") || args[i].equals("-b"))
{
invoker.batchMode = true;
}
else if (args[i].equals("--gui"))
{
invoker.batchMode = false;
}
else if (args[i].equals("--quiet"))
{
invoker.setQuietMode(true);
}
else if (args[i].equals("--debug"))
{
invoker.setDebugMode(true);
}
else if (args[i].equals("--dry-run") || args[i].equals("-n"))
{
invoker.setDryRunMode(true);
}
else if (args[i].equals("--nodry-run"))
{
invoker.setDryRunMode(false);
}
else if (args[i].startsWith("-"))
{
System.err.println(invoker.getLabelWithValues("error.unknown_opt",
args[i]));
System.exit(1);
}
else if (invoker.getFileName() == null)
{
invoker.setFile(args[i]);
}
else
{
System.err.println(invoker.getLabel("error.one_input"));
System.exit(1);
}
}
if (invoker.batchMode)
{
if (invoker.getFileName() == null)
{
System.err.println(invoker.getLabel("error.input_required"));
System.exit(1);
}
invoker.reload();
}
else
{
MakeGlossariesGUI.createAndShowGUI(invoker);
}
}
private String currentFileName = null;
private MakeGlossariesProperties properties;
private MakeGlossariesDictionary messages;
public static final String APP_NAME = "MakeGlossariesGUI";
public static final String APP_VERSION = "2.2";
public static final String APP_DATE = "2020-03-09";
private boolean quiet=false, debug=false, batchMode=false, dryRun=false;
protected Glossaries glossaries;
private Charset defaultCharset=Charset.defaultCharset();
private Hashtable<String,String> languageMap;
private GlossaryMessage messageSystem;
}