0001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
0002 *
0003 * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>.
0004 *
0005 * "Hilbert II" is free software; you can redistribute
0006 * it and/or modify it under the terms of the GNU General Public
0007 * License as published by the Free Software Foundation; either
0008 * version 2 of the License, or (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0013 * GNU General Public License for more details.
0014 */
0015
0016 package org.qedeq.kernel.bo.service.latex;
0017
0018 import java.io.File;
0019 import java.io.FileInputStream;
0020 import java.io.FileOutputStream;
0021 import java.io.IOException;
0022 import java.io.InputStream;
0023 import java.util.Locale;
0024
0025 import org.qedeq.base.io.IoUtility;
0026 import org.qedeq.base.io.Parameters;
0027 import org.qedeq.base.io.SourcePosition;
0028 import org.qedeq.base.io.TextInput;
0029 import org.qedeq.base.io.TextOutput;
0030 import org.qedeq.base.trace.Trace;
0031 import org.qedeq.base.utility.DateUtility;
0032 import org.qedeq.base.utility.EqualsUtility;
0033 import org.qedeq.base.utility.StringUtility;
0034 import org.qedeq.kernel.bo.log.QedeqLog;
0035 import org.qedeq.kernel.bo.module.InternalModuleServiceCall;
0036 import org.qedeq.kernel.bo.module.KernelNodeBo;
0037 import org.qedeq.kernel.bo.module.KernelQedeqBo;
0038 import org.qedeq.kernel.bo.module.Reference;
0039 import org.qedeq.kernel.bo.service.basis.ControlVisitor;
0040 import org.qedeq.kernel.bo.service.basis.ModuleServicePluginExecutor;
0041 import org.qedeq.kernel.se.base.list.Element;
0042 import org.qedeq.kernel.se.base.list.ElementList;
0043 import org.qedeq.kernel.se.base.module.Add;
0044 import org.qedeq.kernel.se.base.module.Author;
0045 import org.qedeq.kernel.se.base.module.AuthorList;
0046 import org.qedeq.kernel.se.base.module.Axiom;
0047 import org.qedeq.kernel.se.base.module.ChangedRule;
0048 import org.qedeq.kernel.se.base.module.ChangedRuleList;
0049 import org.qedeq.kernel.se.base.module.Chapter;
0050 import org.qedeq.kernel.se.base.module.Conclusion;
0051 import org.qedeq.kernel.se.base.module.ConditionalProof;
0052 import org.qedeq.kernel.se.base.module.Existential;
0053 import org.qedeq.kernel.se.base.module.FormalProof;
0054 import org.qedeq.kernel.se.base.module.FormalProofLine;
0055 import org.qedeq.kernel.se.base.module.FormalProofLineList;
0056 import org.qedeq.kernel.se.base.module.FunctionDefinition;
0057 import org.qedeq.kernel.se.base.module.Header;
0058 import org.qedeq.kernel.se.base.module.Hypothesis;
0059 import org.qedeq.kernel.se.base.module.Import;
0060 import org.qedeq.kernel.se.base.module.ImportList;
0061 import org.qedeq.kernel.se.base.module.InitialFunctionDefinition;
0062 import org.qedeq.kernel.se.base.module.InitialPredicateDefinition;
0063 import org.qedeq.kernel.se.base.module.Latex;
0064 import org.qedeq.kernel.se.base.module.LatexList;
0065 import org.qedeq.kernel.se.base.module.LinkList;
0066 import org.qedeq.kernel.se.base.module.LiteratureItem;
0067 import org.qedeq.kernel.se.base.module.LiteratureItemList;
0068 import org.qedeq.kernel.se.base.module.LocationList;
0069 import org.qedeq.kernel.se.base.module.ModusPonens;
0070 import org.qedeq.kernel.se.base.module.Node;
0071 import org.qedeq.kernel.se.base.module.PredicateDefinition;
0072 import org.qedeq.kernel.se.base.module.Proof;
0073 import org.qedeq.kernel.se.base.module.Proposition;
0074 import org.qedeq.kernel.se.base.module.Qedeq;
0075 import org.qedeq.kernel.se.base.module.Rename;
0076 import org.qedeq.kernel.se.base.module.Rule;
0077 import org.qedeq.kernel.se.base.module.Section;
0078 import org.qedeq.kernel.se.base.module.SectionList;
0079 import org.qedeq.kernel.se.base.module.Specification;
0080 import org.qedeq.kernel.se.base.module.Subsection;
0081 import org.qedeq.kernel.se.base.module.SubsectionList;
0082 import org.qedeq.kernel.se.base.module.SubsectionType;
0083 import org.qedeq.kernel.se.base.module.SubstFree;
0084 import org.qedeq.kernel.se.base.module.SubstFunc;
0085 import org.qedeq.kernel.se.base.module.SubstPred;
0086 import org.qedeq.kernel.se.base.module.Universal;
0087 import org.qedeq.kernel.se.base.module.UsedByList;
0088 import org.qedeq.kernel.se.common.ModuleAddress;
0089 import org.qedeq.kernel.se.common.ModuleContext;
0090 import org.qedeq.kernel.se.common.ModuleDataException;
0091 import org.qedeq.kernel.se.common.ModuleService;
0092 import org.qedeq.kernel.se.common.RuleKey;
0093 import org.qedeq.kernel.se.common.SourceFileExceptionList;
0094
0095
0096 /**
0097 * Transfer a QEDEQ module into a LaTeX file.
0098 * <p>
0099 * <b>This is just a quick written generator. No parsing or validation
0100 * of inline LaTeX text is done. This class just generates some LaTeX output to be able to
0101 * get a visual impression of a QEDEQ module.</b>
0102 *
0103 * @author Michael Meyling
0104 */
0105 public final class Qedeq2LatexExecutor extends ControlVisitor implements ModuleServicePluginExecutor {
0106
0107 /** This class. */
0108 private static final Class CLASS = Qedeq2LatexExecutor.class;
0109
0110 // TODO m31 20100316: check number area for error codes
0111 // TODO m31 20100803: add JUnit tests for all error codes
0112
0113 /** Output goes here. */
0114 private TextOutput printer;
0115
0116 /** Filter text to get and produce text in this language. */
0117 private String language;
0118
0119 /** Filter for this detail level. */
0120 // private String level;
0121
0122 /** Should additional information be put into LaTeX output? E.g. QEDEQ reference names. */
0123 private final boolean info;
0124
0125 /** Should only names and formulas be be printed? */
0126 private final boolean brief;
0127
0128 /** Current node id. */
0129 private String id;
0130
0131 /** Current node title. */
0132 private String title;
0133
0134 /** Sub context like "getIntroduction()". */
0135 private String subContext = "";
0136
0137 /** Remembered proof line label. */
0138 private String label = "";
0139
0140 /** Remembered proof line formula. */
0141 private String formula = "";
0142
0143 /** Remembered proof line reason. */
0144 private String reason = "";
0145
0146 /** Remembered proof line tabulator level. */
0147 private int tabLevel = 0;
0148
0149 /** Alphabet for tagging. */
0150 private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
0151
0152 /**
0153 * Constructor.
0154 *
0155 * @param plugin This plugin we work for.
0156 * @param prop QEDEQ BO object.
0157 * @param parameters Parameters.
0158 */
0159 public Qedeq2LatexExecutor(final ModuleService plugin, final KernelQedeqBo prop, final Parameters parameters) {
0160 super(plugin, prop);
0161 info = parameters.getBoolean("info");
0162 brief = parameters.getBoolean("brief");
0163 }
0164
0165 private ModuleService getPlugin() {
0166 return (ModuleService) getService();
0167 }
0168
0169 public Object executePlugin(final InternalModuleServiceCall call, final Object data) {
0170 final String method = "executePlugin(QedeqBo, Map)";
0171 try {
0172 QedeqLog.getInstance().logRequest("Generate LaTeX", getKernelQedeqBo().getUrl());
0173 final String[] languages = getKernelQedeqBo().getSupportedLanguages();
0174 for (int j = 0; j < languages.length; j++) {
0175 language = languages[j];
0176 // level = "1";
0177 final String result = generateLatex(call, languages[j], "1").toString();
0178 if (languages[j] != null) {
0179 QedeqLog.getInstance().logSuccessfulReply(
0180 "LaTeX for language \"" + languages[j]
0181 + "\" was generated from into \"" + result + "\"", getKernelQedeqBo().getUrl());
0182 } else {
0183 QedeqLog.getInstance().logSuccessfulReply(
0184 "LaTeX for default language "
0185 + "was generated into \"" + result + "\"", getKernelQedeqBo().getUrl());
0186 }
0187 }
0188 if (languages.length == 0) {
0189 QedeqLog.getInstance().logMessage("no supported language found, assuming 'en'");
0190 final String result = generateLatex(call, "en", "1").toString();
0191 QedeqLog.getInstance().logSuccessfulReply(
0192 "LaTeX for language \"en"
0193 + "\" was generated into \"" + result + "\"", getKernelQedeqBo().getUrl());
0194 }
0195 } catch (final SourceFileExceptionList e) {
0196 final String msg = "Generation failed";
0197 Trace.fatal(CLASS, this, method, msg, e);
0198 QedeqLog.getInstance().logFailureReply(msg, getKernelQedeqBo().getUrl(), e.getMessage());
0199 } catch (IOException e) {
0200 final String msg = "Generation failed";
0201 Trace.fatal(CLASS, this, method, msg, e);
0202 QedeqLog.getInstance().logFailureReply(msg, getKernelQedeqBo().getUrl(), e.getMessage());
0203 } catch (final RuntimeException e) {
0204 Trace.fatal(CLASS, this, method, "unexpected problem", e);
0205 QedeqLog.getInstance().logFailureReply(
0206 "Generation failed", getKernelQedeqBo().getUrl(), "unexpected problem: "
0207 + (e.getMessage() != null ? e.getMessage() : e.toString()));
0208 }
0209 return null;
0210 }
0211
0212 /**
0213 * Get an input stream for the LaTeX creation.
0214 *
0215 * @param call This process executes us.
0216 * @param language Filter text to get and produce text in this language only.
0217 * @param level Filter for this detail level. LATER mime 20050205: not supported
0218 * yet.
0219 * @return Resulting LaTeX.
0220 * @throws SourceFileExceptionList Major problem occurred.
0221 * @throws IOException File IO failed.
0222 */
0223 public InputStream createLatex(final InternalModuleServiceCall call, final String language, final String level)
0224 throws SourceFileExceptionList, IOException {
0225 return new FileInputStream(generateLatex(call, language, level));
0226 }
0227
0228 /**
0229 * Gives a LaTeX representation of given QEDEQ module as InputStream.
0230 *
0231 * @param call This process executes us.
0232 * @param language Filter text to get and produce text in this language only.
0233 * <code>null</code> is ok.
0234 * @param level Filter for this detail level. LATER mime 20050205: not supported
0235 * yet.
0236 * @return Resulting LaTeX.
0237 * @throws SourceFileExceptionList Major problem occurred.
0238 * @throws IOException File IO failed.
0239 */
0240 public File generateLatex(final InternalModuleServiceCall call, final String language, final String level)
0241 throws SourceFileExceptionList, IOException {
0242 final String method = "generateLatex(String, String)";
0243 this.language = language;
0244 // this.level = level;
0245 // first we try to get more information about required modules and their predicates..
0246 try {
0247 getServices().loadRequiredModules(call.getInternalServiceProcess(), getKernelQedeqBo());
0248 getServices().checkWellFormedness(call.getInternalServiceProcess(), getKernelQedeqBo());
0249 } catch (Exception e) {
0250 // we continue and ignore external predicates
0251 Trace.trace(CLASS, method, e);
0252 }
0253 String tex = getKernelQedeqBo().getModuleAddress().getFileName();
0254 if (tex.toLowerCase(Locale.US).endsWith(".xml")) {
0255 tex = tex.substring(0, tex.length() - 4);
0256 }
0257 if (language != null && language.length() > 0) {
0258 tex = tex + "_" + language;
0259 }
0260 // the destination is the configured destination directory plus the (relative)
0261 // localized file (or path) name
0262 File destination = new File(getServices().getConfig()
0263 .getGenerationDirectory(), tex + ".tex").getCanonicalFile();
0264
0265 init();
0266
0267 try {
0268 // TODO 20110204 m31: here we should choose the correct encoding; perhaps GUI configurable?
0269 if ("de".equals(language)) {
0270 printer = new TextOutput(getKernelQedeqBo().getName(), new FileOutputStream(destination),
0271 "ISO-8859-1") {
0272 public void append(final String txt) {
0273 super.append(escapeUmlauts(txt));
0274 }
0275 };
0276 } else {
0277 printer = new TextOutput(getKernelQedeqBo().getName(), new FileOutputStream(destination),
0278 "UTF-8") {
0279 public void append(final String txt) {
0280 super.append(escapeUmlauts(txt));
0281 }
0282 };
0283 }
0284 traverse(call.getInternalServiceProcess());
0285 } finally {
0286 getKernelQedeqBo().addPluginErrorsAndWarnings(getPlugin(), getErrorList(), getWarningList());
0287 if (printer != null) {
0288 printer.flush();
0289 printer.close();
0290 }
0291 }
0292 if (printer != null && printer.checkError()) {
0293 throw printer.getError();
0294 }
0295 try {
0296 QedeqBoDuplicateLanguageChecker.check(call);
0297 } catch (SourceFileExceptionList warnings) {
0298 getKernelQedeqBo().addPluginErrorsAndWarnings(getPlugin(), null, warnings);
0299 }
0300 return destination.getCanonicalFile();
0301 }
0302
0303 /**
0304 * Reset counters and other variables. Should be executed before {@link #traverse()}.
0305 */
0306 protected void init() {
0307 id = null;
0308 title = null;
0309 subContext = "";
0310 }
0311
0312 public final void visitEnter(final Qedeq qedeq) {
0313 printer.println("% -*- TeX"
0314 + (language != null ? ":" + language.toUpperCase(Locale.US) : "") + " -*-");
0315 printer.println("%%% ====================================================================");
0316 printer.println("%%% @LaTeX-file " + printer.getName());
0317 printer.println("%%% Generated from " + getKernelQedeqBo().getModuleAddress());
0318 printer.println("%%% Generated at " + DateUtility.getTimestamp());
0319 printer.println("%%% ====================================================================");
0320 printer.println();
0321 printer.println(
0322 "%%% Permission is granted to copy, distribute and/or modify this document");
0323 printer.println("%%% under the terms of the GNU Free Documentation License, Version 1.2");
0324 printer.println("%%% or any later version published by the Free Software Foundation;");
0325 printer.println(
0326 "%%% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.");
0327 printer.println();
0328 printer.println("\\documentclass[a4paper,german,10pt,twoside]{book}");
0329 if ("de".equals(language)) {
0330 printer.println("\\usepackage[german]{babel}");
0331 } else {
0332 if (!"en".equals(language)) {
0333 printer.println("%%% TODO unknown language: " + language);
0334 }
0335 printer.println("\\usepackage[english]{babel}");
0336 }
0337 printer.println("\\usepackage{makeidx}");
0338 printer.println("\\usepackage{amsmath,amsthm,amssymb}");
0339 printer.println("\\usepackage{color}");
0340 printer.println("\\usepackage{xr}");
0341 printer.println("\\usepackage{tabularx}");
0342 // printer.println("\\usepackage{epsfig,longtable}");
0343 // printer.println("\\usepackage{ltabptch}"); // not installed on our server
0344 printer.println("\\usepackage[bookmarks=true,bookmarksnumbered,bookmarksopen,");
0345 printer.println(" unicode=true,colorlinks=true,linkcolor=webgreen,");
0346 printer.println(" pagebackref=true,pdfnewwindow=true,pdfstartview=FitH]{hyperref}");
0347 printer.println("\\definecolor{webgreen}{rgb}{0,.5,0}");
0348 printer.println("\\usepackage{epsfig,longtable}");
0349 printer.println("\\usepackage{graphicx}");
0350 printer.println("\\usepackage[all]{hypcap}");
0351 printer.println();
0352 if ("de".equals(language)) {
0353 // TODO m31 20100313: validate different counter types
0354 // printer.println("\\newtheorem{thm}{Theorem}[chapter]");
0355 printer.println("\\newtheorem{thm}{Theorem}");
0356 printer.println("\\newtheorem{cor}[thm]{Korollar}");
0357 printer.println("\\newtheorem{lem}[thm]{Lemma}");
0358 printer.println("\\newtheorem{prop}[thm]{Proposition}");
0359 printer.println("\\newtheorem{ax}{Axiom}");
0360 printer.println("\\newtheorem{rul}{Regel}");
0361 printer.println();
0362 printer.println("\\theoremstyle{definition}");
0363 printer.println("\\newtheorem{defn}{Definition}");
0364 printer.println("\\newtheorem{idefn}[defn]{Initiale Definition}");
0365 printer.println();
0366 printer.println("\\theoremstyle{remark}");
0367 printer.println("\\newtheorem{rem}[thm]{Bemerkung}");
0368 printer.println("\\newtheorem*{notation}{Notation}");
0369 } else {
0370 if (!"en".equals(language)) {
0371 printer.println("%%% TODO unknown language: " + language);
0372 }
0373 // TODO m31 20100313: validate different counter types
0374 // printer.println("\\newtheorem{thm}{Theorem}[chapter]");
0375 printer.println("\\newtheorem{thm}{Theorem}");
0376 printer.println("\\newtheorem{cor}[thm]{Corollary}");
0377 printer.println("\\newtheorem{lem}[thm]{Lemma}");
0378 printer.println("\\newtheorem{prop}[thm]{Proposition}");
0379 printer.println("\\newtheorem{ax}{Axiom}");
0380 printer.println("\\newtheorem{rul}{Rule}");
0381 printer.println();
0382 printer.println("\\theoremstyle{definition}");
0383 printer.println("\\newtheorem{defn}{Definition}");
0384 printer.println("\\newtheorem{idefn}[defn]{Initial Definition}");
0385 printer.println();
0386 printer.println("\\theoremstyle{remark}");
0387 printer.println("\\newtheorem{rem}[thm]{Remark}");
0388 printer.println("\\newtheorem*{notation}{Notation}");
0389 }
0390 printer.println();
0391 printer.println();
0392 printer.println("\\addtolength{\\textheight}{7\\baselineskip}");
0393 printer.println("\\addtolength{\\topmargin}{-5\\baselineskip}");
0394 printer.println();
0395 printer.println("\\setlength{\\parindent}{0pt}");
0396 printer.println();
0397 printer.println("\\frenchspacing \\sloppy");
0398 printer.println();
0399 printer.println("\\makeindex");
0400 printer.println();
0401 printer.println();
0402 }
0403
0404 public final void visitLeave(final Qedeq qedeq) {
0405 printer.println("\\addcontentsline{toc}{chapter}{\\indexname} \\printindex");
0406 printer.println();
0407 printer.println("\\end{document}");
0408 printer.println();
0409 }
0410
0411 public void visitEnter(final Header header) {
0412 final LatexList tit = header.getTitle();
0413 printer.print("\\title{");
0414 printer.print(getLatexListEntry("getTitle()", tit));
0415 printer.println("}");
0416 printer.println("\\author{");
0417 final AuthorList authors = getKernelQedeqBo().getQedeq().getHeader().getAuthorList();
0418 final StringBuffer authorList = new StringBuffer();
0419 for (int i = 0; i < authors.size(); i++) {
0420 if (i > 0) {
0421 authorList.append(", ");
0422 printer.println(", ");
0423 }
0424 final Author author = authors.get(i);
0425 final String name = author.getName().getLatex().trim();
0426 printer.print(name);
0427 authorList.append(name);
0428 String email = author.getEmail();
0429 if (email != null && email.trim().length() > 0) {
0430 authorList.append(" \\href{mailto:" + email + "}{" + email + "}");
0431 }
0432 }
0433 printer.println();
0434 printer.println("}");
0435 printer.println();
0436 printer.println("\\begin{document}");
0437 printer.println();
0438 printer.println("\\maketitle");
0439 printer.println();
0440 printer.println("\\setlength{\\parskip}{5pt plus 2pt minus 1pt}");
0441 printer.println("\\mbox{}");
0442 printer.println("\\vfill");
0443 printer.println();
0444 final String url = getKernelQedeqBo().getUrl();
0445 if (url != null && url.length() > 0) {
0446 printer.println("\\par");
0447 if ("de".equals(language)) {
0448 printer.println("Die Quelle f{\"ur} dieses Dokument ist hier zu finden:");
0449 } else {
0450 if (!"en".equals(language)) {
0451 printer.println("%%% TODO unknown language: " + language);
0452 }
0453 printer.println("The source for this document can be found here:");
0454 }
0455 printer.println("\\par");
0456 printer.println("\\url{" + url + "}");
0457 printer.println();
0458 }
0459 {
0460 printer.println("\\par");
0461 if ("de".equals(language)) {
0462 printer.println("Die vorliegende Publikation ist urheberrechtlich gesch{\"u}tzt.");
0463 } else {
0464 if (!"en".equals(language)) {
0465 printer.println("%%% TODO unknown language: " + language);
0466 }
0467 printer.println("Copyright by the authors. All rights reserved.");
0468 }
0469 }
0470 final String email = header.getEmail();
0471 if (email != null && email.length() > 0) {
0472 final String emailUrl = "\\href{mailto:" + email + "}{" + email + "}";
0473 printer.println("\\par");
0474 if ("de".equals(language)) {
0475 printer.println("Bei Fragen, Anregungen oder Bitte um Aufnahme in die Liste der"
0476 + " abh\u00e4ngigen Module schicken Sie bitte eine EMail an die Adresse "
0477 + emailUrl);
0478 printer.println();
0479 printer.println("\\par");
0480 printer.println("Die Autoren dieses Dokuments sind:");
0481 printer.println(authorList);
0482 } else {
0483 if (!"en".equals(language)) {
0484 printer.println("%%% TODO unknown language: " + language);
0485 }
0486 printer.println("If you have any questions, suggestions or want to add something"
0487 + " to the list of modules that use this one, please send an email to the"
0488 + " address " + emailUrl);
0489 printer.println();
0490 printer.println("\\par");
0491 printer.println("The authors of this document are:");
0492 printer.println(authorList);
0493 }
0494 printer.println();
0495 }
0496 }
0497
0498 public void visitLeave(final Header header) {
0499 printer.println();
0500 printer.println();
0501 printer.println("\\setlength{\\parskip}{0pt}");
0502 printer.println("\\tableofcontents");
0503 printer.println();
0504 printer.println("\\setlength{\\parskip}{5pt plus 2pt minus 1pt}");
0505 printer.println();
0506 }
0507
0508 public void visitEnter(final ImportList imports) throws ModuleDataException {
0509 printer.println();
0510 printer.println();
0511 printer.println("\\par");
0512 if ("de".equals(language)) {
0513 printer.println("Benutzte QEDEQ module:");
0514 } else {
0515 if (!"en".equals(language)) {
0516 printer.println("%%% TODO unknown language: " + language);
0517 }
0518 printer.println("Used other QEDEQ modules:");
0519 }
0520 printer.println();
0521 printer.println("\\par");
0522 printer.println();
0523 }
0524
0525 public void visitEnter(final Import imp) throws ModuleDataException {
0526 printer.println();
0527 printer.println("\\par");
0528 printer.print("\\textbf{" + imp.getLabel() + "} ");
0529 final Specification spec = imp.getSpecification();
0530 printer.print(getLatex(spec.getName()));
0531 if (spec.getLocationList() != null && spec.getLocationList().size() > 0
0532 && spec.getLocationList().get(0).getLocation().length() > 0) {
0533 printer.print(" ");
0534 printer.print("\\url{" + getPdfLink((KernelQedeqBo) getKernelQedeqBo()
0535 .getLabels().getReferences().getQedeqBo(imp.getLabel())) + "}");
0536 }
0537 printer.println();
0538 }
0539
0540 /**
0541 * Get URL for QEDEQ XML module.
0542 *
0543 * @param address Current module address.
0544 * @param specification Find URL for this location list.
0545 * @return URL or <code>""</code> if none (valid?) was found.
0546 */
0547 private String getUrl(final ModuleAddress address, final Specification specification) {
0548 final LocationList list = specification.getLocationList();
0549 if (list == null || list.size() <= 0) {
0550 return "";
0551 }
0552 try {
0553 return address.getModulePaths(specification)[0].getUrl();
0554 } catch (IOException e) {
0555 return "";
0556 }
0557 }
0558
0559 public void visitEnter(final Chapter chapter) {
0560 // check if we print only brief and test for non text subnodes
0561 if (brief) {
0562 boolean hasFormalContent = false;
0563 do {
0564 final SectionList sections = chapter.getSectionList();
0565 if (sections == null) {
0566 break;
0567 }
0568 for (int i = 0; i < sections.size() && !hasFormalContent; i++) {
0569 final Section section = sections.get(i);
0570 if (section == null) {
0571 continue;
0572 }
0573 final SubsectionList subSections = section.getSubsectionList();
0574 if (subSections == null) {
0575 continue;
0576 }
0577 for (int j = 0; j < subSections.size(); j++) {
0578 final SubsectionType subSection = subSections.get(j);
0579 if (!(subSection instanceof Subsection)) {
0580 hasFormalContent = true;
0581 break;
0582 }
0583 }
0584 }
0585 } while (false);
0586 if (!hasFormalContent) {
0587 setBlocked(true);
0588 return;
0589 }
0590 }
0591 printer.print("\\chapter");
0592 if (chapter.getNoNumber() != null && chapter.getNoNumber().booleanValue()) {
0593 printer.print("*");
0594 }
0595 printer.print("{");
0596 printer.print(getLatexListEntry("getTitle()", chapter.getTitle()));
0597 final String chapterLabel = "chapter" + getCurrentNumbers().getAbsoluteChapterNumber();
0598 printer.println("} \\label{" + chapterLabel + "} \\hypertarget{" + chapterLabel + "}{}");
0599 if (chapter.getNoNumber() != null && chapter.getNoNumber().booleanValue()) {
0600 printer.println("\\addcontentsline{toc}{chapter}{"
0601 + getLatexListEntry("getTitle()", chapter.getTitle()) + "}");
0602 }
0603 printer.println();
0604 if (chapter.getIntroduction() != null && !brief) {
0605 printer.println(getLatexListEntry("getIntroduction()", chapter.getIntroduction()));
0606 printer.println();
0607 }
0608 }
0609
0610 public void visitLeave(final Chapter chapter) {
0611 printer.println("%% end of chapter " + getLatexListEntry("getTitle()", chapter.getTitle()));
0612 printer.println();
0613 setBlocked(false);
0614 }
0615
0616 public void visitLeave(final SectionList list) {
0617 printer.println();
0618 }
0619
0620 public void visitEnter(final Section section) {
0621 // check if we print only brief and test for non text subnodes
0622 if (brief) {
0623 boolean hasFormalContent = false;
0624 do {
0625 final SubsectionList subSections = section.getSubsectionList();
0626 if (subSections == null) {
0627 break;
0628 }
0629 for (int j = 0; j < subSections.size(); j++) {
0630 final SubsectionType subSection = subSections.get(j);
0631 if (!(subSection instanceof Subsection)) {
0632 hasFormalContent = true;
0633 break;
0634 }
0635 }
0636 } while (false);
0637 if (!hasFormalContent) {
0638 setBlocked(true);
0639 return;
0640 }
0641 }
0642 printer.print("\\section");
0643 if (section.getNoNumber() != null && section.getNoNumber().booleanValue()) {
0644 printer.print("*");
0645 }
0646 printer.print("{");
0647 printer.print(getLatexListEntry("getTitle()", section.getTitle()));
0648 final String chapterLabel = "chapter" + getCurrentNumbers().getAbsoluteChapterNumber()
0649 + "_section" + getCurrentNumbers().getAbsoluteSectionNumber();
0650 printer.println("} \\label{" + chapterLabel + "} \\hypertarget{" + chapterLabel + "}{}");
0651 if (section.getIntroduction() != null && !brief) {
0652 printer.println(getLatexListEntry("getIntroduction()", section.getIntroduction()));
0653 printer.println();
0654 }
0655 }
0656
0657 public void visitLeave(final Section section) {
0658 setBlocked(false);
0659 }
0660
0661 public void visitEnter(final Subsection subsection) {
0662 /* LATER mime 20070131: use this information?
0663 if (subsection.getId() != null) {
0664 printer.print(" id=\"" + subsection.getId() + "\"");
0665 }
0666 if (subsection.getLevel() != null) {
0667 printer.print(" level=\"" + subsection.getLevel() + "\"");
0668 }
0669 */
0670 if (brief) {
0671 return;
0672 }
0673 if (subsection.getTitle() != null) {
0674 printer.print("\\subsection{");
0675 printer.println(getLatexListEntry("getTitle()", subsection.getTitle()));
0676 printer.println("}");
0677 }
0678 if (subsection.getId() != null) {
0679 printer.println("\\label{" + subsection.getId() + "} \\hypertarget{"
0680 + subsection.getId() + "}{}");
0681 }
0682 printer.println(getLatexListEntry("getLatex()", subsection.getLatex()));
0683 }
0684
0685 public void visitLeave(final Subsection subsection) {
0686 if (brief) {
0687 return;
0688 }
0689 printer.println();
0690 printer.println();
0691 }
0692
0693 public void visitEnter(final Node node) {
0694 /** TODO mime 20070131: level filter
0695 if (node.getLevel() != null) {
0696 printer.print(" level=\"" + node.getLevel() + "\"");
0697 }
0698 */
0699 if (node.getPrecedingText() != null && !brief) {
0700 printer.println("\\par");
0701 printer.println(getLatexListEntry("getPrecedingText()", node.getPrecedingText()));
0702 printer.println();
0703 }
0704 id = node.getId();
0705 title = null;
0706 if (node.getTitle() != null) {
0707 title = getLatexListEntry("getTitle()", node.getTitle());
0708 }
0709 }
0710
0711 public void visitLeave(final Node node) {
0712 printer.println();
0713 if (node.getSucceedingText() != null && !brief) {
0714 printer.println(getLatexListEntry("getSucceedingText()", node.getSucceedingText()));
0715 printer.println();
0716 }
0717 printer.println();
0718 }
0719
0720 public void visitEnter(final Axiom axiom) {
0721 printer.println("\\begin{ax}" + (title != null ? "[" + title + "]" : ""));
0722 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
0723 if (info) {
0724 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
0725 }
0726 printFormula(axiom.getFormula().getElement());
0727 printer.println(getLatexListEntry("getDescription()", axiom.getDescription()));
0728 printer.println("\\end{ax}");
0729 }
0730
0731 public void visitEnter(final Proposition proposition) {
0732 printer.println("\\begin{prop}" + (title != null ? "[" + title + "]" : ""));
0733 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
0734 if (info) {
0735 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
0736 }
0737 printTopFormula(proposition.getFormula().getElement(), id);
0738 printer.println(getLatexListEntry("getDescription()", proposition.getDescription()));
0739 printer.println("\\end{prop}");
0740 }
0741
0742 public void visitEnter(final Proof proof) {
0743 /* LATER mime 20070131: filter level and kind
0744 if (proof.getKind() != null) {
0745 printer.print(" kind=\"" + proof.getKind() + "\"");
0746 }
0747 if (proof.getLevel() != null) {
0748 printer.print(" level=\"" + proof.getLevel() + "\"");
0749 }
0750 */
0751 if (brief) {
0752 setBlocked(true);
0753 return;
0754 }
0755 printer.println("\\begin{proof}");
0756 printer.println(getLatexListEntry("getNonFormalProof()", proof.getNonFormalProof()));
0757 printer.println("\\end{proof}");
0758 }
0759
0760 public void visitLeave(final Proof proof) {
0761 setBlocked(false);
0762 }
0763
0764 public void visitEnter(final FormalProof proof) {
0765 if (brief) {
0766 setBlocked(true);
0767 return;
0768 }
0769 tabLevel = 0;
0770 printer.println("\\begin{proof}");
0771 // if ("de".equals(language)) {
0772 // printer.println("Beweis (formal):");
0773 // } else {
0774 // printer.println("Proof (formal):");
0775 // }
0776 }
0777
0778 public void visitEnter(final FormalProofLineList lines) {
0779 if (tabLevel == 0) {
0780 printer.println("\\mbox{}\\\\");
0781 printer.println("\\begin{longtable}[h!]{r@{\\extracolsep{\\fill}}p{9cm}@{\\extracolsep{\\fill}}p{4cm}}");
0782 }
0783 }
0784
0785 public void visitLeave(final FormalProofLineList lines) {
0786 if (tabLevel == 0) {
0787 printer.println(" & & \\qedhere");
0788 printer.println("\\end{longtable}");
0789 }
0790 }
0791
0792 public void visitEnter(final FormalProofLine line) {
0793 if (line.getLabel() != null) {
0794 label = line.getLabel();
0795 } else {
0796 label = "";
0797 }
0798 if (line.getFormula() != null) {
0799 formula = "$" + getKernelQedeqBo().getElement2Latex().getLatex(line.getFormula().getElement()) + "$";
0800 } else {
0801 formula = "";
0802 }
0803 if (line.getReason() != null) {
0804 reason = line.getReason().toString();
0805 } else {
0806 reason = "";
0807 }
0808 }
0809
0810 public void visitLeave(final FormalProofLine line) {
0811 if (brief) {
0812 return;
0813 }
0814 linePrintln();
0815 }
0816
0817 /**
0818 * Print proof line made out of label, formula and reason.
0819 */
0820 private void linePrintln() {
0821 if (formula.length() == 0 && reason.length() == 0) {
0822 return;
0823 }
0824 if (label.length() > 0) {
0825 String display = getNodeBo().getNodeVo().getId() + "!" + label;
0826 printer.print("\\label{" + display + "} \\hypertarget{" + display
0827 + "}{\\mbox{(" + label + ")}} ");
0828 }
0829 printer.print(" \\ & \\ ");
0830 for (int i = 0; i < tabLevel; i++) {
0831 printer.print("\\mbox{\\qquad}");
0832 }
0833 if (formula.length() > 0) {
0834 printer.print(formula);
0835 }
0836 printer.print(" \\ & \\ ");
0837 if (reason.length() > 0) {
0838 printer.print("{\\tiny ");
0839 printer.print(reason);
0840 printer.print("}");
0841 }
0842 printer.println(" \\\\ ");
0843 reason = "";
0844 formula = "";
0845 label = "";
0846 }
0847
0848 private String getReference(final String reference) {
0849 return getReference(reference, "getReference()");
0850 }
0851
0852 private String getReference(final String reference, final String subContext) {
0853 final String context = getCurrentContext().getLocationWithinModule();
0854 try {
0855 getCurrentContext().setLocationWithinModule(context + "." + subContext);
0856 return (getReference(reference, null, null));
0857 } finally {
0858 getCurrentContext().setLocationWithinModule(context);
0859 }
0860 }
0861
0862 public void visitEnter(final ModusPonens r) throws ModuleDataException {
0863 if (brief) {
0864 return;
0865 }
0866 reason = getRuleReference(r.getName());
0867 boolean one = false;
0868 if (r.getReference1() != null) {
0869 reason += " " + getReference(r.getReference1(), "getReference1()");
0870 one = true;
0871 }
0872 if (r.getReference1() != null) {
0873 if (one) {
0874 reason += ",";
0875 }
0876 reason += " " + getReference(r.getReference2(), "getReference2()");
0877 }
0878 }
0879
0880 public void visitEnter(final Add r) throws ModuleDataException {
0881 if (brief) {
0882 return;
0883 }
0884 reason = getRuleReference(r.getName());
0885 if (r.getReference() != null) {
0886 reason += " " + getReference(r.getReference());
0887 }
0888 }
0889
0890 public void visitEnter(final Rename r) throws ModuleDataException {
0891 if (brief) {
0892 return;
0893 }
0894 reason = getRuleReference(r.getName());
0895 if (r.getOriginalSubjectVariable() != null) {
0896 reason += " $" + getKernelQedeqBo().getElement2Latex().getLatex(
0897 r.getOriginalSubjectVariable()) + "$";
0898 }
0899 if (r.getReplacementSubjectVariable() != null) {
0900 reason += " by $" + getKernelQedeqBo().getElement2Latex().getLatex(
0901 r.getReplacementSubjectVariable()) + "$";
0902 }
0903 if (r.getReference() != null) {
0904 reason += " in " + getReference(r.getReference());
0905 }
0906 }
0907
0908 public void visitEnter(final SubstFree r) throws ModuleDataException {
0909 if (brief) {
0910 return;
0911 }
0912 reason = getRuleReference(r.getName());
0913 if (r.getSubjectVariable() != null) {
0914 reason += " $" + getKernelQedeqBo().getElement2Latex().getLatex(
0915 r.getSubjectVariable()) + "$";
0916 }
0917 if (r.getSubstituteTerm() != null) {
0918 reason += " by $" + getKernelQedeqBo().getElement2Latex().getLatex(
0919 r.getSubstituteTerm()) + "$";
0920 }
0921 if (r.getReference() != null) {
0922 reason += " in " + getReference(r.getReference());
0923 }
0924 }
0925
0926 public void visitEnter(final SubstFunc r) throws ModuleDataException {
0927 if (brief) {
0928 return;
0929 }
0930 reason = getRuleReference(r.getName());
0931 if (r.getFunctionVariable() != null) {
0932 reason += " $" + getKernelQedeqBo().getElement2Latex().getLatex(
0933 r.getFunctionVariable()) + "$";
0934 }
0935 if (r.getSubstituteTerm() != null) {
0936 reason += " by $" + getKernelQedeqBo().getElement2Latex().getLatex(
0937 r.getSubstituteTerm()) + "$";
0938 }
0939 if (r.getReference() != null) {
0940 reason += " in " + getReference(r.getReference());
0941 }
0942 }
0943
0944 public void visitEnter(final SubstPred r) throws ModuleDataException {
0945 if (brief) {
0946 return;
0947 }
0948 reason = getRuleReference(r.getName());
0949 if (r.getPredicateVariable() != null) {
0950 reason += " $" + getKernelQedeqBo().getElement2Latex().getLatex(
0951 r.getPredicateVariable()) + "$";
0952 }
0953 if (r.getSubstituteFormula() != null) {
0954 reason += " by $" + getKernelQedeqBo().getElement2Latex().getLatex(
0955 r.getSubstituteFormula()) + "$";
0956 }
0957 if (r.getReference() != null) {
0958 reason += " in " + getReference(r.getReference());
0959 }
0960 }
0961
0962 public void visitEnter(final Existential r) throws ModuleDataException {
0963 if (brief) {
0964 return;
0965 }
0966 reason = getRuleReference(r.getName());
0967 if (r.getSubjectVariable() != null) {
0968 reason += " with $" + getKernelQedeqBo().getElement2Latex().getLatex(
0969 r.getSubjectVariable()) + "$";
0970 }
0971 if (r.getReference() != null) {
0972 reason += " in " + getReference(r.getReference());
0973 }
0974 }
0975
0976 public void visitEnter(final Universal r) throws ModuleDataException {
0977 if (brief) {
0978 return;
0979 }
0980 reason = getRuleReference(r.getName());
0981 if (r.getSubjectVariable() != null) {
0982 reason += " with $" + getKernelQedeqBo().getElement2Latex().getLatex(
0983 r.getSubjectVariable()) + "$";
0984 }
0985 if (r.getReference() != null) {
0986 reason += " in " + getReference(r.getReference());
0987 }
0988 }
0989
0990 public void visitEnter(final ConditionalProof r) throws ModuleDataException {
0991 if (brief) {
0992 return;
0993 }
0994 reason = getRuleReference(r.getName());
0995 printer.print(" \\ & \\ ");
0996 for (int i = 0; i < tabLevel; i++) {
0997 printer.print("\\mbox{\\qquad}");
0998 }
0999 printer.println("Conditional Proof");
1000 printer.print(" \\ & \\ ");
1001 printer.println(" \\\\ ");
1002 tabLevel++;
1003 }
1004
1005 public void visitLeave(final ConditionalProof proof) {
1006 if (brief) {
1007 return;
1008 }
1009 tabLevel--;
1010 }
1011
1012 public void visitEnter(final Hypothesis hypothesis) {
1013 if (brief) {
1014 return;
1015 }
1016 reason = "Hypothesis";
1017 if (hypothesis.getLabel() != null) {
1018 label = hypothesis.getLabel();
1019 }
1020 if (hypothesis.getFormula() != null) {
1021 formula = "$" + getKernelQedeqBo().getElement2Latex().getLatex(
1022 hypothesis.getFormula().getElement()) + "$";
1023 }
1024 }
1025
1026 public void visitLeave(final Hypothesis hypothesis) {
1027 if (brief) {
1028 return;
1029 }
1030 linePrintln();
1031 }
1032
1033 public void visitEnter(final Conclusion conclusion) {
1034 if (brief) {
1035 return;
1036 }
1037 tabLevel--;
1038 reason = "Conclusion";
1039 if (conclusion.getLabel() != null) {
1040 label = conclusion.getLabel();
1041 }
1042 if (conclusion.getFormula() != null) {
1043 formula = "$" + getKernelQedeqBo().getElement2Latex().getLatex(
1044 conclusion.getFormula().getElement()) + "$";
1045 }
1046 }
1047
1048 public void visitLeave(final Conclusion conclusion) {
1049 if (brief) {
1050 return;
1051 }
1052 linePrintln();
1053 tabLevel++;
1054 }
1055
1056 public void visitLeave(final FormalProof proof) {
1057 if (!getBlocked()) {
1058 printer.println("\\end{proof}");
1059 }
1060 setBlocked(false);
1061 }
1062
1063 public void visitEnter(final InitialPredicateDefinition definition) {
1064 printer.println("\\begin{idefn}" + (title != null ? "[" + title + "]" : ""));
1065 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
1066 if (info) {
1067 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
1068 }
1069 printer.print("$$");
1070 printer.println(getLatex(definition.getPredCon()));
1071 printer.println("$$");
1072 printer.println(getLatexListEntry("getDescription()", definition.getDescription()));
1073 printer.println("\\end{idefn}");
1074 }
1075
1076 public void visitEnter(final PredicateDefinition definition) {
1077 printer.println("\\begin{defn}" + (title != null ? "[" + title + "]" : ""));
1078 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
1079 if (info) {
1080 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
1081 }
1082 printer.print("$$");
1083 printer.print(getLatex(definition.getFormula().getElement()));
1084 printer.println("$$");
1085 printer.println(getLatexListEntry("getDescription()", definition.getDescription()));
1086 printer.println("\\end{defn}");
1087 }
1088
1089 public void visitEnter(final InitialFunctionDefinition definition) {
1090 printer.println("\\begin{idefn}" + (title != null ? "[" + title + "]" : ""));
1091 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
1092 if (info) {
1093 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
1094 }
1095 printer.print("$$");
1096 printer.print(getLatex(definition.getFunCon()));
1097 printer.println("$$");
1098 printer.println(getLatexListEntry("getDescription()", definition.getDescription()));
1099 printer.println("\\end{defn}");
1100 }
1101
1102 public void visitEnter(final FunctionDefinition definition) {
1103 printer.println("\\begin{defn}" + (title != null ? "[" + title + "]" : ""));
1104 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
1105 if (info) {
1106 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
1107 }
1108 printer.print("$$");
1109 printer.print(getLatex(definition.getFormula().getElement()));
1110 printer.println("$$");
1111 printer.println("\\end{defn}");
1112 }
1113
1114 public void visitLeave(final FunctionDefinition definition) {
1115 // nothing to do
1116 }
1117
1118 public void visitEnter(final Rule rule) {
1119 printer.println("\\begin{rul}" + (title != null ? "[" + title + "]" : ""));
1120 printer.println("\\label{" + id + "} \\hypertarget{" + id + "}{}");
1121 if (info) {
1122 printer.println("{\\tt \\tiny [\\verb]" + id + "]]}");
1123 }
1124 printer.println();
1125 printer.println("\\par");
1126 printer.println("{\\em "
1127 + (rule.getName() != null ? " Name: \\verb]" + rule.getName() + "]" : "")
1128 + (rule.getVersion() != null ? " - Version: \\verb]" + rule.getVersion() + "]" : "")
1129 + "}");
1130 printer.println();
1131 printer.println();
1132 printer.println(getLatexListEntry("getDescription()", rule.getDescription()));
1133 printer.println("\\end{rul}");
1134 }
1135
1136 public void visitLeave(final Rule rule) {
1137 // nothing to do
1138 }
1139
1140 public void visitEnter(final LinkList linkList) {
1141 if (linkList.size() <= 0) {
1142 return;
1143 }
1144 if ("de".equals(language)) {
1145 printer.println("Basierend auf: ");
1146 } else {
1147 if (!"en".equals(language)) {
1148 printer.println("%%% TODO unknown language: " + language);
1149 }
1150 printer.println("Based on: ");
1151 }
1152 for (int i = 0; i < linkList.size(); i++) {
1153 if (linkList.get(i) != null) {
1154 printer.print(" " + getReference(linkList.get(i), "get(" + i + ")"));
1155 }
1156 };
1157 printer.println();
1158 }
1159
1160 public void visitEnter(final ChangedRuleList list) {
1161 if (list.size() <= 0) {
1162 return;
1163 }
1164 if ("de".equals(language)) {
1165 printer.println("Die folgenden Regeln m\u00fcssen erweitert werden.");
1166 } else {
1167 if (!"en".equals(language)) {
1168 printer.println("%%% TODO unknown language: " + language);
1169 }
1170 printer.println("The following rules have to be extended.");
1171 }
1172 printer.println();
1173 }
1174
1175 public void visitEnter(final ChangedRule rule) {
1176 printer.println("\\par");
1177 printer.println("\\label{" + id + "!" + rule.getName() + "} \\hypertarget{" + id + "!"
1178 + rule.getName() + "}{}");
1179 printer.print("{\\em "
1180 + (rule.getName() != null ? " Name: \\verb]" + rule.getName() + "]" : "")
1181 + (rule.getVersion() != null ? " - Version: \\verb]" + rule.getVersion() + "]" : ""));
1182 RuleKey old = getLocalRuleKey(rule.getName());
1183 if (old == null && getKernelQedeqBo().getExistenceChecker() != null) {
1184 old = getKernelQedeqBo().getExistenceChecker().getParentRuleKey(rule.getName());
1185 }
1186 if (old != null) {
1187 printer.print(" - Old Version: "
1188 + getRuleReference(rule.getName(), old.getVersion()));
1189 }
1190 printer.println("}");
1191 rule.getName();
1192 printer.println();
1193 if (rule.getDescription() != null) {
1194 printer.println(getLatexListEntry("getDescription()", rule.getDescription()));
1195 printer.println();
1196 printer.println();
1197 }
1198 }
1199
1200
1201 public void visitEnter(final LiteratureItemList list) {
1202 printer.println("\\backmatter");
1203 printer.println();
1204 printer.println("\\begin{thebibliography}{99}");
1205 if ("de".equals(language)) {
1206 printer.println("\\addcontentsline{toc}{chapter}{Literaturverzeichnis}");
1207 } else {
1208 if (!"en".equals(language)) {
1209 printer.println("%%% TODO unknown language: " + language);
1210 }
1211 printer.println("\\addcontentsline{toc}{chapter}{Bibliography}");
1212 }
1213 final ImportList imports = getKernelQedeqBo().getQedeq().getHeader().getImportList();
1214 if (imports != null && imports.size() > 0) {
1215 printer.println();
1216 printer.println();
1217 printer.println("%% Used other QEDEQ modules:");
1218 for (int i = 0; i < imports.size(); i++) {
1219 final Import imp = imports.get(i);
1220 printer.print("\\bibitem{" + imp.getLabel() + "} ");
1221 final Specification spec = imp.getSpecification();
1222 printer.print(getLatex(spec.getName()));
1223 if (spec.getLocationList() != null && spec.getLocationList().size() > 0
1224 && spec.getLocationList().get(0).getLocation().length() > 0) {
1225 printer.print(" ");
1226 // TODO m31 20070205, 2010727: later on here must stand the location that was used
1227 // to verify the document contents.
1228 // Also get other informations like authors, title, etc.
1229 // It might also be better to link to URL?
1230 // printer.print("\\url{" + getUrl(getQedeqBo().getModuleAddress(), spec) + "}");
1231 printer.print("\\url{" + getPdfLink((KernelQedeqBo) getKernelQedeqBo()
1232 .getLabels().getReferences().getQedeqBo(imp.getLabel())) + "}");
1233 }
1234 printer.println();
1235 }
1236 printer.println();
1237 printer.println();
1238 printer.println("%% Other references:");
1239 printer.println();
1240 }
1241 }
1242
1243 public void visitLeave(final LiteratureItemList list) {
1244 final UsedByList usedby = getKernelQedeqBo().getQedeq().getHeader().getUsedByList();
1245 if (usedby != null && usedby.size() > 0) {
1246 printer.println();
1247 printer.println();
1248 printer.println("%% QEDEQ modules that use this one:");
1249 for (int i = 0; i < usedby.size(); i++) {
1250 final Specification spec = usedby.get(i);
1251 printer.print("\\bibitem{" + spec.getName() + "} ");
1252 printer.print(getLatex(spec.getName()));
1253 final String url = getUrl(getKernelQedeqBo().getModuleAddress(), spec);
1254 if (url != null && url.length() > 0) {
1255 printer.print(" ");
1256 printer.print("\\url{" + url + "}");
1257 }
1258 printer.println();
1259 }
1260 printer.println();
1261 printer.println();
1262 }
1263 printer.println("\\end{thebibliography}");
1264 }
1265
1266 public void visitEnter(final LiteratureItem item) {
1267 printer.print("\\bibitem{" + item.getLabel() + "} ");
1268 printer.println(getLatexListEntry("getItem()", item.getItem()));
1269 printer.println();
1270 }
1271
1272 /**
1273 * Print top level formula. If the formula has the form <code>AND(.., .., ..)</code> the
1274 * formula is broken down in several labeled lines.
1275 *
1276 * @param element Formula to print.
1277 * @param mainLabel Main formula label.
1278 */
1279 private void printTopFormula(final Element element, final String mainLabel) {
1280 if (!element.isList() || !element.getList().getOperator().equals("AND")) {
1281 printFormula(element);
1282 return;
1283 }
1284 final ElementList list = element.getList();
1285 printer.println("\\mbox{}");
1286 printer.println("\\begin{longtable}{{@{\\extracolsep{\\fill}}p{0.9\\linewidth}l}}");
1287 for (int i = 0; i < list.size(); i++) {
1288 String newLabel = "";
1289 if (list.size() >= ALPHABET.length() * ALPHABET.length()) {
1290 newLabel = "" + (i + 1);
1291 } else {
1292 // TODO 20110303 m31: this dosn't work if we have more than 26 * 26 elements
1293 if (list.size() > ALPHABET.length()) {
1294 final int div = (i / ALPHABET.length());
1295 newLabel = "" + ALPHABET.charAt(div);
1296 }
1297 newLabel += ALPHABET.charAt(i % ALPHABET.length());
1298 }
1299 // final String label = (i < ALPHABET.length() ? "" + ALPHABET .charAt(i) : "" + i);
1300 printer.println("\\centering $" + getLatex(list.getElement(i)) + "$"
1301 + " & \\label{" + mainLabel + "/" + newLabel + "} \\hypertarget{" + mainLabel + "/"
1302 + newLabel + "}{} \\mbox{\\emph{(" + newLabel + ")}} "
1303 + (i + 1 < list.size() ? "\\\\" : ""));
1304 }
1305 printer.println("\\end{longtable}");
1306 }
1307
1308 /**
1309 * Print formula.
1310 *
1311 * @param element Formula to print.
1312 */
1313 private void printFormula(final Element element) {
1314 printer.println("\\mbox{}");
1315 printer.println("\\begin{longtable}{{@{\\extracolsep{\\fill}}p{\\linewidth}}}");
1316 printer.println("\\centering $" + getLatex(element) + "$");
1317 printer.println("\\end{longtable}");
1318 }
1319
1320 /**
1321 * Get LaTeX element presentation.
1322 *
1323 * @param element Print this element.
1324 * @return LaTeX form of element.
1325 */
1326 private String getLatex(final Element element) {
1327 return getKernelQedeqBo().getElement2Latex().getLatex(element);
1328 }
1329
1330 /**
1331 * Filters correct entry out of LaTeX list. Filter criterion is for example the correct
1332 * language.
1333 * TODO mime 20050205: filter level too?
1334 *
1335 * @param method This method was called. Used to get the correct sub context.
1336 * Should not be null. If it is empty the <code>subContext</code>
1337 * is not changed.
1338 * @param list List of LaTeX texts.
1339 * @return Filtered text.
1340 */
1341 private String getLatexListEntry(final String method, final LatexList list) {
1342 if (list == null) {
1343 return "";
1344 }
1345 if (method.length() > 0) {
1346 subContext = method;
1347 }
1348 try {
1349 for (int i = 0; language != null && i < list.size(); i++) {
1350 if (language.equals(list.get(i).getLanguage())) {
1351 if (method.length() > 0) {
1352 subContext = method + ".get(" + i + ")";
1353 }
1354 return getLatex(list.get(i));
1355 }
1356 }
1357 // OK, we didn't found the language, so we take the default language
1358 final String def = getKernelQedeqBo().getOriginalLanguage();
1359 for (int i = 0; i < list.size(); i++) {
1360 if (EqualsUtility.equals(def, list.get(i).getLanguage())) {
1361 if (method.length() > 0) {
1362 subContext = method + ".get(" + i + ")";
1363 }
1364 return "MISSING! OTHER: " + getLatex(list.get(i));
1365 }
1366 }
1367 // OK, we didn't find wanted and default language, so we take the first non empty one
1368 for (int i = 0; i < list.size(); i++) {
1369 if (method.length() > 0) {
1370 subContext = method + ".get(" + i + ")";
1371 }
1372 if (null != list.get(i) && null != list.get(i).getLatex()
1373 && list.get(i).getLatex().trim().length() > 0) {
1374 return "MISSING! OTHER: " + getLatex(list.get(i));
1375 }
1376 }
1377 return "MISSING!";
1378 } finally {
1379 if (method.length() > 0) {
1380 subContext = "";
1381 }
1382 }
1383 }
1384
1385 /**
1386 * Get really LaTeX. Does some simple character replacements for umlauts. Also transforms
1387 * <code>\qref{key}</code> into LaTeX.
1388 *
1389 * @param latex Unescaped text.
1390 * @return Really LaTeX.
1391 */
1392 private String getLatex(final Latex latex) {
1393 if (latex == null || latex.getLatex() == null) {
1394 return "";
1395 }
1396 StringBuffer result = new StringBuffer(latex.getLatex());
1397
1398 // LATER mime 20080324: check if LaTeX is correct and no forbidden tags are used
1399
1400 transformQref(result);
1401
1402 return deleteLineLeadingWhitespace(result.toString());
1403 }
1404
1405 /**
1406 * Transform <code>\qref{key}</code> entries into common LaTeX code.
1407 *
1408 * LATER mime 20080324: write JUnitTests to be sure that no runtime exceptions are thrown if
1409 * reference is at end of latex etc.
1410 *
1411 * @param result Work on this buffer.
1412 */
1413 private void transformQref(final StringBuffer result) {
1414 final String method = "transformQref(StringBuffer)";
1415 final StringBuffer buffer = new StringBuffer(result.toString());
1416 final TextInput input = new TextInput(buffer);
1417 int last = 0;
1418 try {
1419 result.setLength(0);
1420 while (input.forward("\\qref{")) {
1421 final SourcePosition startPosition = input.getSourcePosition();
1422 final int start = input.getPosition();
1423 if (!input.forward("}")) {
1424 addWarning(LatexErrorCodes.QREF_END_NOT_FOUND_CODE,
1425 LatexErrorCodes.QREF_END_NOT_FOUND_TEXT, startPosition,
1426 input.getSourcePosition());
1427 continue;
1428 }
1429 String ref = input.getSubstring(start + "\\qref{".length(), input.getPosition()).trim();
1430 input.read(); // read }
1431 Trace.param(CLASS, this, method, "1 ref", ref);
1432 if (ref.length() == 0) {
1433 addWarning(LatexErrorCodes.QREF_EMPTY_CODE, LatexErrorCodes.QREF_EMPTY_TEXT,
1434 startPosition, input.getSourcePosition());
1435 continue;
1436 }
1437 if (ref.length() > 1024) {
1438 addWarning(LatexErrorCodes.QREF_END_NOT_FOUND_CODE,
1439 LatexErrorCodes.QREF_END_NOT_FOUND_TEXT, startPosition,
1440 input.getSourcePosition());
1441 continue;
1442 }
1443 if (ref.indexOf("{") >= 0) {
1444 addWarning(LatexErrorCodes.QREF_END_NOT_FOUND_CODE,
1445 LatexErrorCodes.QREF_END_NOT_FOUND_TEXT, startPosition,
1446 input.getSourcePosition());
1447 continue;
1448 }
1449 final int end = input.getPosition();
1450 final SourcePosition endPosition = input.getSourcePosition();
1451 result.append(buffer.substring(last, start));
1452 result.append(getReference(ref, startPosition, endPosition));
1453 last = end;
1454 }
1455 } finally { // thanks to findbugs
1456 IoUtility.close(input);
1457 if (last < buffer.length()) {
1458 result.append(buffer.substring(last));
1459 }
1460 }
1461 }
1462
1463 private String getReference(final String reference, final SourcePosition start, final SourcePosition end) {
1464 final String method = "getReference(String, String)";
1465 Trace.param(CLASS, this, method, "2 reference", reference); // qreference within module
1466
1467 final Reference ref = getReference(reference, getCurrentContext(start, end), true, false);
1468 if (ref.isNodeLocalReference() && ref.isSubReference()) {
1469 return "\\hyperlink{" + ref.getNodeLabel() + "/" + ref.getSubLabel() + "}{" + "("
1470 + ref.getSubLabel() + ")" + "}";
1471 }
1472
1473 if (ref.isNodeLocalReference() && ref.isProofLineReference()) {
1474 return "\\hyperlink{" + ref.getNodeLabel() + "!" + ref.getProofLineLabel() + "}{" + "("
1475 + ref.getProofLineLabel() + ")" + "}";
1476 }
1477
1478 if (!ref.isExternal()) {
1479 return "\\hyperlink{" + ref.getNodeLabel()
1480 + (ref.isSubReference() ? "/" + ref.getSubLabel() : "")
1481 + (ref.isProofLineReference() ? "!" + ref.getProofLineLabel() : "")
1482 + "}{"
1483 + getNodeDisplay(ref.getNodeLabel(), ref.getNode())
1484 + (ref.isSubReference() ? " (" + ref.getSubLabel() + ")" : "")
1485 + (ref.isProofLineReference() ? " (" + ref.getProofLineLabel() + ")" : "")
1486 + "}";
1487 }
1488
1489 // do we have an external module reference without node?
1490 if (ref.isExternalModuleReference()) {
1491 return "\\url{" + getPdfLink(ref.getExternalQedeq()) + "}~\\cite{"
1492 + ref.getExternalQedeqLabel() + "}";
1493 // if we want to show the text "description": \href{my_url}{description}
1494 }
1495
1496 String external = getPdfLink(ref.getExternalQedeq());
1497 if (external.startsWith("file://")) {
1498 external = "file:" + external.substring("file://".length());
1499 }
1500 return "\\hyperref{" + external + "}{}{"
1501 + ref.getNodeLabel()
1502 + (ref.isSubReference() ? "/" + ref.getSubLabel() : "")
1503 + (ref.isProofLineReference() ? "!" + ref.getProofLineLabel() : "")
1504 + "}{" + getNodeDisplay(ref.getNodeLabel(), ref.getNode())
1505 + (ref.isSubReference() ? " (" + ref.getSubLabel() + ")" : "")
1506 + (ref.isProofLineReference() ? " (" + ref.getProofLineLabel() + ")" : "")
1507 + "}~\\cite{" + ref.getExternalQedeqLabel() + "}";
1508 }
1509
1510 private String getNodeDisplay(final String label, final KernelNodeBo kNode) {
1511 return StringUtility.replace(getNodeDisplay(label, kNode, language), " ", "~");
1512 }
1513
1514 private String getRuleReference(final String ruleName) {
1515 return getRuleReference(ruleName, ruleName);
1516 }
1517
1518 private String getRuleReference(final String ruleName, final String caption) {
1519 final String method = "getRuleReference(String, String)";
1520 Trace.param(CLASS, this, method, "ruleName", ruleName);
1521 RuleKey key = getLocalRuleKey(ruleName);
1522 if (key == null && getKernelQedeqBo().getExistenceChecker() != null) {
1523 key = getKernelQedeqBo().getExistenceChecker().getParentRuleKey(ruleName);
1524 }
1525 if (key == null) {
1526 key = getKernelQedeqBo().getLabels().getRuleKey(ruleName);
1527 }
1528 KernelQedeqBo qedeq = getKernelQedeqBo();
1529 if (getKernelQedeqBo().getExistenceChecker() != null) {
1530 qedeq = getKernelQedeqBo().getExistenceChecker().getQedeq(key);
1531 }
1532 String localRef = getKernelQedeqBo().getLabels().getRuleLabel(key);
1533 final String refRuleName = qedeq.getLabels().getRule(key).getName();
1534 if (!ruleName.equals(refRuleName)) {
1535 localRef += "!" + ruleName;
1536 }
1537 qedeq.getLabels().getRule(key).getName();
1538 boolean local = getKernelQedeqBo().equals(qedeq);
1539 if (local) {
1540 return "\\hyperlink{" + localRef + "}{" + caption + "}";
1541 }
1542 String external = getPdfLink(qedeq);
1543 if (external.startsWith("file://")) {
1544 external = "file:" + external.substring("file://".length());
1545 }
1546 return "\\hyperref{" + external + "}{}{" + caption + "}{"
1547 + localRef + "}";
1548 }
1549
1550 /**
1551 * Get current module context. Uses sub context information.
1552 *
1553 * @param startDelta Skip position (relative to location start). Could be
1554 * <code>null</code>.
1555 * @param endDelta Mark until this column (relative to location start).
1556 * be <code>null</code>
1557 * @return Current module context.
1558 */
1559 public ModuleContext getCurrentContext(final SourcePosition startDelta,
1560 final SourcePosition endDelta) {
1561 if (subContext.length() == 0) {
1562 return super.getCurrentContext();
1563 }
1564 final ModuleContext c = new ModuleContext(super.getCurrentContext().getModuleLocation(),
1565 super.getCurrentContext().getLocationWithinModule() + "." + subContext,
1566 startDelta, endDelta);
1567 return c;
1568 }
1569
1570 // TODO 20110214 m31: decide about removal
1571 // public ModuleContext getCurrentContext() {
1572 // throw new IllegalStateException("programming error");
1573 // }
1574
1575
1576 /**
1577 * Add warning.
1578 *
1579 * @param code Warning code.
1580 * @param msg Warning message.
1581 * @param startDelta Skip position (relative to location start). Could be
1582 * <code>null</code>.
1583 * @param endDelta Mark until this column (relative to location start).
1584 * be <code>null</code>
1585 */
1586 private void addWarning(final int code, final String msg, final SourcePosition startDelta,
1587 final SourcePosition endDelta) {
1588 Trace.param(CLASS, this, "addWarning", "msg", msg);
1589 addWarning(new LatexContentException(code, msg, getCurrentContext(startDelta, endDelta)));
1590 }
1591
1592 /**
1593 * Get URL to for PDF version of module. If the referenced module doesn't
1594 * support the current language we switch to the original language.
1595 *
1596 * @param prop Get URL for this QEDEQ module.
1597 * @return URL to PDF.
1598 */
1599 private String getPdfLink(final KernelQedeqBo prop) {
1600 if (prop == null) {
1601 return "";
1602 }
1603 final String url = prop.getUrl();
1604 final int dot = url.lastIndexOf(".");
1605 if (prop.isSupportedLanguage(language)) {
1606 return url.substring(0, dot) + "_" + language + ".pdf";
1607 }
1608 final String a = prop.getOriginalLanguage();
1609 return url.substring(0, dot) + (a.length() > 0 ? "_" + a : "") + ".pdf";
1610 }
1611
1612 /**
1613 * Get LaTeX from string. Escapes common characters.
1614 * Also gets rid of leading spaces if they are equal among the lines.
1615 *
1616 * @param text Unescaped text.
1617 * @return LaTeX.
1618 */
1619 private String getLatex(final String text) {
1620 final StringBuffer buffer = new StringBuffer(text);
1621 StringUtility.replace(buffer, "\\", "\\textbackslash");
1622 StringUtility.replace(buffer, "$", "\\$");
1623 StringUtility.replace(buffer, "&", "\\&");
1624 StringUtility.replace(buffer, "%", "\\%");
1625 StringUtility.replace(buffer, "#", "\\#");
1626 StringUtility.replace(buffer, "_", "\\_");
1627 StringUtility.replace(buffer, "{", "\\{");
1628 StringUtility.replace(buffer, "}", "\\}");
1629 StringUtility.replace(buffer, "~", "\\textasciitilde");
1630 StringUtility.replace(buffer, "^", "\\textasciicircum");
1631 StringUtility.replace(buffer, "<", "\\textless");
1632 StringUtility.replace(buffer, ">", "\\textgreater");
1633 StringUtility.deleteLineLeadingWhitespace(buffer);
1634 return buffer.toString().trim();
1635 }
1636
1637 /**
1638 * Trims text. Also gets rid of leading spaces if they are equal among the lines.
1639 *
1640 * @param text Text.
1641 * @return Untrimed text.
1642 */
1643 private String deleteLineLeadingWhitespace(final String text) {
1644 final StringBuffer buffer = new StringBuffer(text);
1645 StringUtility.deleteLineLeadingWhitespace(buffer);
1646 return buffer.toString().trim();
1647 }
1648
1649 /**
1650 * Get really LaTeX. Does some simple character replacements for umlauts.
1651 * LATER mime 20050205: filter more than German umlauts
1652 *
1653 * @param nearlyLatex Unescaped text.
1654 * @return Really LaTeX.
1655 */
1656 private String escapeUmlauts(final String nearlyLatex) {
1657 if (nearlyLatex == null) {
1658 return "";
1659 }
1660 final StringBuffer buffer = new StringBuffer(nearlyLatex);
1661 // System.out.println("before");
1662 // System.out.println(buffer);
1663 // System.out.println();
1664 // System.out.println("after");
1665 // System.out.println(buffer);
1666 // System.out.println("*******************************************************************");
1667 StringUtility.replace(buffer, "\u00fc", "{\\\"u}");
1668 StringUtility.replace(buffer, "\u00f6", "{\\\"o}");
1669 StringUtility.replace(buffer, "\u00e4", "{\\\"a}");
1670 StringUtility.replace(buffer, "\u00dc", "{\\\"U}");
1671 StringUtility.replace(buffer, "\u00d6", "{\\\"O}");
1672 StringUtility.replace(buffer, "\u00c4", "{\\\"A}");
1673 StringUtility.replace(buffer, "\u00df", "{\\ss}");
1674 return buffer.toString();
1675 }
1676
1677 }
|