Qedeq2UnicodeVisitor.java
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.unicode;
0017 
0018 import java.io.IOException;
0019 import java.util.ArrayList;
0020 import java.util.List;
0021 
0022 import org.apache.commons.lang.ArrayUtils;
0023 import org.qedeq.base.io.AbstractOutput;
0024 import org.qedeq.base.io.SourcePosition;
0025 import org.qedeq.base.io.TextOutput;
0026 import org.qedeq.base.trace.Trace;
0027 import org.qedeq.base.utility.DateUtility;
0028 import org.qedeq.base.utility.EqualsUtility;
0029 import org.qedeq.base.utility.StringUtility;
0030 import org.qedeq.kernel.bo.module.InternalServiceJob;
0031 import org.qedeq.kernel.bo.module.KernelNodeBo;
0032 import org.qedeq.kernel.bo.module.KernelQedeqBo;
0033 import org.qedeq.kernel.bo.module.Reference;
0034 import org.qedeq.kernel.bo.service.basis.ControlVisitor;
0035 import org.qedeq.kernel.se.base.list.Element;
0036 import org.qedeq.kernel.se.base.list.ElementList;
0037 import org.qedeq.kernel.se.base.module.Add;
0038 import org.qedeq.kernel.se.base.module.Author;
0039 import org.qedeq.kernel.se.base.module.AuthorList;
0040 import org.qedeq.kernel.se.base.module.Axiom;
0041 import org.qedeq.kernel.se.base.module.ChangedRule;
0042 import org.qedeq.kernel.se.base.module.ChangedRuleList;
0043 import org.qedeq.kernel.se.base.module.Chapter;
0044 import org.qedeq.kernel.se.base.module.Conclusion;
0045 import org.qedeq.kernel.se.base.module.ConditionalProof;
0046 import org.qedeq.kernel.se.base.module.Existential;
0047 import org.qedeq.kernel.se.base.module.FormalProof;
0048 import org.qedeq.kernel.se.base.module.FormalProofLine;
0049 import org.qedeq.kernel.se.base.module.Formula;
0050 import org.qedeq.kernel.se.base.module.FunctionDefinition;
0051 import org.qedeq.kernel.se.base.module.Header;
0052 import org.qedeq.kernel.se.base.module.Hypothesis;
0053 import org.qedeq.kernel.se.base.module.Import;
0054 import org.qedeq.kernel.se.base.module.ImportList;
0055 import org.qedeq.kernel.se.base.module.InitialFunctionDefinition;
0056 import org.qedeq.kernel.se.base.module.InitialPredicateDefinition;
0057 import org.qedeq.kernel.se.base.module.Latex;
0058 import org.qedeq.kernel.se.base.module.LatexList;
0059 import org.qedeq.kernel.se.base.module.LinkList;
0060 import org.qedeq.kernel.se.base.module.LiteratureItem;
0061 import org.qedeq.kernel.se.base.module.LiteratureItemList;
0062 import org.qedeq.kernel.se.base.module.LocationList;
0063 import org.qedeq.kernel.se.base.module.ModusPonens;
0064 import org.qedeq.kernel.se.base.module.Node;
0065 import org.qedeq.kernel.se.base.module.PredicateDefinition;
0066 import org.qedeq.kernel.se.base.module.Proof;
0067 import org.qedeq.kernel.se.base.module.Proposition;
0068 import org.qedeq.kernel.se.base.module.Qedeq;
0069 import org.qedeq.kernel.se.base.module.Rename;
0070 import org.qedeq.kernel.se.base.module.Rule;
0071 import org.qedeq.kernel.se.base.module.Section;
0072 import org.qedeq.kernel.se.base.module.SectionList;
0073 import org.qedeq.kernel.se.base.module.Specification;
0074 import org.qedeq.kernel.se.base.module.Subsection;
0075 import org.qedeq.kernel.se.base.module.SubsectionList;
0076 import org.qedeq.kernel.se.base.module.SubsectionType;
0077 import org.qedeq.kernel.se.base.module.SubstFree;
0078 import org.qedeq.kernel.se.base.module.SubstFunc;
0079 import org.qedeq.kernel.se.base.module.SubstPred;
0080 import org.qedeq.kernel.se.base.module.Universal;
0081 import org.qedeq.kernel.se.base.module.UsedByList;
0082 import org.qedeq.kernel.se.common.ModuleAddress;
0083 import org.qedeq.kernel.se.common.ModuleContext;
0084 import org.qedeq.kernel.se.common.ModuleDataException;
0085 import org.qedeq.kernel.se.common.ModuleService;
0086 import org.qedeq.kernel.se.common.SourceFileExceptionList;
0087 import org.qedeq.kernel.se.visitor.QedeqNumbers;
0088 
0089 
0090 /**
0091  * Transfer a QEDEQ module into unicode text.
0092  <p>
0093  <b>This is just a quick written generator. This class just generates some text output to be able
0094  * to get a visual impression of a QEDEQ module.</b>
0095  *
0096  @author  Michael Meyling
0097  */
0098 public class Qedeq2UnicodeVisitor extends ControlVisitor implements ReferenceFinder {
0099 
0100     /** This class. */
0101     private static final Class CLASS = Qedeq2UnicodeVisitor.class;
0102 
0103     /** Output goes here. */
0104     private AbstractOutput printer;
0105 
0106     /** Filter text to get and produce text in this language. */
0107     private String language;
0108 
0109     /** Filter for this detail level. */
0110 //    private String level;
0111 
0112     /** Should additional information be put into LaTeX output? E.g. QEDEQ reference names. */
0113     private final boolean info;
0114 
0115     /** Current node id. */
0116     private String id;
0117 
0118     /** Current node title. */
0119     private String title;
0120 
0121     /** Sub context like "getIntroduction()". */
0122     private String subContext = "";
0123 
0124     /** Maximum column number. If zero no line breaking is done automatically. */
0125     private int maxColumns;
0126 
0127     /** Should warning messages be generated if LaTeX problems occur? */
0128     private boolean addWarnings;
0129 
0130     /** Should only names and formulas be be printed? */
0131     private final boolean brief;
0132 
0133     /** Alphabet for tagging. */
0134     private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
0135 
0136     /** Printing data for a single formal proof line. */
0137     private ProofLineData lineData = new ProofLineData();
0138 
0139     /** This is the maximal formula width. All proof line formulas that are bigger are wrapped. */
0140     private int formulaWidth = 60;
0141 
0142     /** This is the maximal reason width. All proof line reasons that are bigger are wrapped. */
0143     private int reasonWidth = 35;
0144 
0145     /** Tabulation string. */
0146     private String tab = "";
0147 
0148     /**
0149      * Constructor.
0150      *
0151      @param   plugin          This plugin we work for.
0152      @param   prop            QEDEQ BO object.
0153      @param   info            Write reference info?
0154      @param   maximumColumn   Maximum column before automatic break.
0155      *                          0 means no automatic break.
0156      @param   addWarnings     Should warning messages be generated
0157      *                          if LaTeX problems occur?
0158      @param   brief           Should only names and formulas be be printed?
0159      */
0160     public Qedeq2UnicodeVisitor(final ModuleService plugin, final KernelQedeqBo prop,
0161             final boolean info, final int maximumColumn, final boolean addWarnings,
0162             final boolean brief) {
0163         super(plugin, prop);
0164         this.info = info;
0165         this.maxColumns = maximumColumn;
0166         this.addWarnings = addWarnings;
0167         this.brief = brief;
0168     }
0169 
0170     /**
0171      * Gives a UTF-8 representation of given QEDEQ module as InputStream.
0172      *
0173      @param   process     We run in this process.
0174      @param   printer     Print herein.
0175      @param   language    Filter text to get and produce text in this language only.
0176      @param   level       Filter for this detail level. LATER 20100205 m31: not yet supported
0177      *                      yet.
0178      @throws  SourceFileExceptionList Major problem occurred.
0179      @throws  IOException     File IO failed.
0180      */
0181     public void generateUtf8(final InternalServiceJob process, final AbstractOutput printer,
0182             final String language, final String levelthrows SourceFileExceptionList, IOException {
0183         setParameters(printer, language);
0184         try {
0185             traverse(process);
0186         finally {
0187             getKernelQedeqBo().addPluginErrorsAndWarnings((ModuleServicegetService(), getErrorList(),
0188                  getWarningList());
0189         }
0190     }
0191 
0192     /**
0193      * Set parameters.
0194      *
0195      @param   printer     Print herein.
0196      @param   language    Choose this language.
0197      */
0198     public void setParameters(final AbstractOutput printer,
0199             final String language) {
0200         this.printer = printer;
0201         this.printer.setColumns(maxColumns);
0202         // TODO 20110208 m31: perhaps we should have some config parameters for those percentage splittings
0203         if (maxColumns <= 0) {
0204             formulaWidth = 80;
0205             reasonWidth = 50;
0206         else if (maxColumns <= 50) {
0207             this.printer.setColumns(50);
0208             formulaWidth = 21;
0209             reasonWidth = 21;
0210         else if (maxColumns <= 100) {
0211             formulaWidth = (maxColumns - 850 100;
0212             reasonWidth = (maxColumns - 850 100;
0213         else if (maxColumns <= 120) {
0214             reasonWidth = 46 (maxColumns - 1005;
0215             formulaWidth = maxColumns - - reasonWidth;
0216         else {
0217             reasonWidth = 50 (maxColumns - 12010;
0218             formulaWidth = maxColumns - - reasonWidth;
0219         }
0220 //        System.out.println("maxColums    =" + this.printer.getColumns());
0221 //        System.out.println("formulaWidth =" + this.formulaWidth);
0222 //        System.out.println("reasonWidth  =" + this.reasonWidth);
0223         if (language == null) {
0224             this.language = "en";
0225         else {
0226             this.language = language;
0227         }
0228 //        if (level == null) {
0229 //            this.level = "1";
0230 //        } else {
0231 //            this.level = level;
0232 //        }
0233 
0234         init();
0235     }
0236 
0237     /**
0238      * Reset counters and other variables. Should be executed before {@link #traverse()}.
0239      */
0240     protected void init() {
0241         id = null;
0242         title = null;
0243         subContext = "";
0244     }
0245 
0246     public final void visitEnter(final Qedeq qedeq) {
0247         if (printer instanceof TextOutput) {
0248             printer.println("================================================================================");
0249             printer.println("UTF-8-file     " ((TextOutputprinter).getName());
0250             printer.println("Generated from " + getKernelQedeqBo().getModuleAddress());
0251             printer.println("Generated at   " + DateUtility.getTimestamp());
0252             printer.println("================================================================================");
0253             printer.println();
0254             printer.println("If the characters of this document don't display correctly try opening this");
0255             printer.println("document within a webbrowser and if necessary change the encoding to");
0256             printer.println("Unicode (UTF-8)");
0257             printer.println();
0258             printer.println("Permission is granted to copy, distribute and/or modify this document");
0259             printer.println("under the terms of the GNU Free Documentation License, Version 1.2");
0260             printer.println("or any later version published by the Free Software Foundation;");
0261             printer.println("with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.");
0262             printer.println();
0263             printer.println();
0264             printer.println();
0265         }
0266     }
0267 
0268     public final void visitLeave(final Qedeq qedeq) {
0269         printer.println();
0270     }
0271 
0272     public void visitEnter(final Header header) {
0273         final LatexList tit = header.getTitle();
0274         underlineBig(getLatexListEntry("getTitle()", tit));
0275         printer.println();
0276         final AuthorList authors = getKernelQedeqBo().getQedeq().getHeader().getAuthorList();
0277         final StringBuffer authorList = new StringBuffer();
0278         for (int i = 0; i < authors.size(); i++) {
0279             if (i > 0) {
0280                 authorList.append("    \n");
0281                 printer.println(", ");
0282             }
0283             final Author author = authors.get(i);
0284             final String name = author.getName().getLatex().trim();
0285             printer.print(name);
0286             authorList.append("    " + name);
0287             String email = author.getEmail();
0288             if (email != null && email.trim().length() 0) {
0289                 authorList.append(" <" + email + ">");
0290             }
0291         }
0292         printer.println();
0293         printer.println();
0294         final String url = getKernelQedeqBo().getUrl();
0295         if (url != null && url.length() 0) {
0296             printer.println();
0297             if ("de".equals(language)) {
0298                 printer.println("Die Quelle f\u00FCr dieses Dokument ist hier zu finden:");
0299             else {
0300                 if (!"en".equals(language)) {
0301                     printer.println("%%% TODO unknown language: " + language);
0302                 }
0303                 printer.println("The source for this document can be found here:");
0304             }
0305             printer.println();
0306             printer.println(url);
0307             printer.println();
0308         }
0309         {
0310             printer.println();
0311             if ("de".equals(language)) {
0312                 printer.println("Die vorliegende Publikation ist urheberrechtlich gesch\u00FCtzt.");
0313             else {
0314                 if (!"en".equals(language)) {
0315                     printer.println("%%% TODO unknown language: " + language);
0316                 }
0317                 printer.println("Copyright by the authors. All rights reserved.");
0318             }
0319         }
0320         final String email = header.getEmail();
0321         if (email != null && email.length() 0) {
0322             printer.println();
0323             printer.println();
0324             if ("de".equals(language)) {
0325                 printer.println("Bei Fragen, Anregungen oder Bitte um Aufnahme in die Liste der"
0326                     " abh\u00E4ngigen Module schicken Sie bitte eine EMail an die Adresse "
0327                     + email);
0328                 printer.println();
0329                 printer.println();
0330                 printer.println("Die Autoren dieses Dokuments sind:");
0331                 printer.println();
0332                 printer.println(authorList);
0333             else {
0334                 if (!"en".equals(language)) {
0335                     printer.println("%%% TODO unknown language: " + language);
0336                 }
0337                 printer.println("If you have any questions, suggestions or want to add something"
0338                     " to the list of modules that use this one, please send an email to the"
0339                     " address " + email);
0340                 printer.println();
0341                 printer.println();
0342                 printer.println("The authors of this document are:");
0343                 printer.println(authorList);
0344             }
0345             printer.println();
0346         }
0347         printer.println();
0348         printer.println();
0349     }
0350 
0351     public void visitEnter(final ImportList importsthrows ModuleDataException {
0352         // this method call is a little bit odd but we have to print the imports
0353         // also in the literature list and we don't want to have doubled code
0354         printImports();
0355     }
0356 
0357     /**
0358      * Get URL for QEDEQ XML module.
0359      *
0360      @param   address         Current module address.
0361      @param   specification   Find URL for this location list.
0362      @return  URL or <code>""</code> if none (valid?) was found.
0363      */
0364     private String getUrl(final ModuleAddress address, final Specification specification) {
0365         final LocationList list = specification.getLocationList();
0366         if (list == null || list.size() <= 0) {
0367             return "";
0368         }
0369         try {
0370             return address.getModulePaths(specification)[0].getUrl();
0371         catch (IOException e) {
0372             return "";
0373         }
0374     }
0375 
0376     public void visitEnter(final Chapter chapter) {
0377         // check if we print only brief and test for non text subnodes
0378         if (brief) {
0379             boolean hasFormalContent = false;
0380             do {
0381                 final SectionList sections = chapter.getSectionList();
0382                 if (sections == null) {
0383                     break;
0384                 }
0385                 for (int i = 0; i < sections.size() && !hasFormalContent; i++) {
0386                     final Section section = sections.get(i);
0387                     if (section == null) {
0388                         continue;
0389                     }
0390                     final SubsectionList subSections = section.getSubsectionList();
0391                     if (subSections == null) {
0392                         continue;
0393                     }
0394                     for (int j = 0; j < subSections.size(); j++) {
0395                         final SubsectionType subSection = subSections.get(j);
0396                         if (!(subSection instanceof Subsection)) {
0397                             hasFormalContent = true;
0398                             break;
0399                         }
0400                     }
0401                 }
0402             while (false);
0403             if (!hasFormalContent) {
0404                 setBlocked(true);
0405                 return;
0406             }
0407         }
0408         final QedeqNumbers numbers = getCurrentNumbers();
0409         if (numbers.isChapterNumbering()) {
0410             if ("de".equals(language)) {
0411                 printer.println("Kapitel " + numbers.getChapterNumber() " ");
0412             else {
0413                 printer.println("Chapter " + numbers.getChapterNumber() " ");
0414             }
0415             printer.println();
0416             printer.println();
0417         }
0418         underlineBig(getLatexListEntry("getTitle()", chapter.getTitle()));
0419         printer.println();
0420         if (chapter.getIntroduction() != null && !brief) {
0421             printer.append(getLatexListEntry("getIntroduction()", chapter.getIntroduction()));
0422             printer.println();
0423             printer.println();
0424             printer.println();
0425         }
0426     }
0427 
0428     public void visitLeave(final Header header) {
0429         printer.println();
0430         printer.println("___________________________________________________");
0431         printer.println();
0432         printer.println();
0433     }
0434 
0435     public void visitLeave(final Chapter chapter) {
0436         if (!getBlocked()) {
0437             printer.println();
0438             printer.println("___________________________________________________");
0439             printer.println();
0440             printer.println();
0441         }
0442         setBlocked(false);
0443     }
0444 
0445     public void visitEnter(final Section section) {
0446         // check if we print only brief and test for non text subnodes
0447         if (brief) {
0448             boolean hasFormalContent = false;
0449             do {
0450                 final SubsectionList subSections = section.getSubsectionList();
0451                 if (subSections == null) {
0452                     break;
0453                 }
0454                 for (int j = 0; j < subSections.size(); j++) {
0455                     final SubsectionType subSection = subSections.get(j);
0456                     if (!(subSection instanceof Subsection)) {
0457                         hasFormalContent = true;
0458                         break;
0459                     }
0460                 }
0461             while (false);
0462             if (!hasFormalContent) {
0463                 setBlocked(true);
0464                 return;
0465             }
0466         }
0467         final QedeqNumbers numbers = getCurrentNumbers();
0468         final StringBuffer buffer = new StringBuffer();
0469         if (numbers.isChapterNumbering()) {
0470             buffer.append(numbers.getChapterNumber());
0471         }
0472         if (numbers.isSectionNumbering()) {
0473             if (buffer.length() 0) {
0474                 buffer.append(".");
0475             }
0476             buffer.append(numbers.getSectionNumber());
0477         }
0478         if (buffer.length() && section.getTitle() != null) {
0479             buffer.append(" ");
0480         }
0481         buffer.append(getLatexListEntry("getTitle()", section.getTitle()));
0482         underline(buffer.toString());
0483         printer.println();
0484         if (section.getIntroduction() != null && !brief) {
0485             printer.append(getLatexListEntry("getIntroduction()", section.getIntroduction()));
0486             printer.println();
0487             printer.println();
0488             printer.println();
0489         }
0490     }
0491 
0492     public void visitLeave(final Section section) {
0493         if (!getBlocked()) {
0494             printer.println();
0495         }
0496         setBlocked(false);
0497     }
0498 
0499     public void visitEnter(final Subsection subsection) {
0500         if (brief) {
0501             return;
0502         }
0503         final QedeqNumbers numbers = getCurrentNumbers();
0504         final StringBuffer buffer = new StringBuffer();
0505         if (numbers.isChapterNumbering()) {
0506             buffer.append(numbers.getChapterNumber());
0507         }
0508         if (numbers.isSectionNumbering()) {
0509             if (buffer.length() 0) {
0510                 buffer.append(".");
0511             }
0512             buffer.append(numbers.getSectionNumber());
0513         }
0514         if (buffer.length() 0) {
0515             buffer.append(".");
0516         }
0517         buffer.append(numbers.getSubsectionNumber());
0518         if (buffer.length() && subsection.getTitle() != null) {
0519             buffer.append(" ");
0520         }
0521         if (subsection.getTitle() != null) {
0522             printer.print(buffer.toString());
0523             printer.print(getLatexListEntry("getTitle()", subsection.getTitle()));
0524         }
0525         if (subsection.getId() != null && info) {
0526             printer.print("  [" + subsection.getId() "]");
0527         }
0528         if (subsection.getTitle() != null) {
0529             printer.println();
0530             printer.println();
0531         }
0532         printer.append(getLatexListEntry("getLatex()", subsection.getLatex()));
0533         printer.println();
0534         printer.println();
0535     }
0536 
0537     public void visitEnter(final Node node) {
0538         if (node.getPrecedingText() != null && !brief) {
0539             printer.append(getLatexListEntry("getPrecedingText()", node.getPrecedingText()));
0540             printer.println();
0541             printer.println();
0542         }
0543         id = node.getId();
0544         title = null;
0545         if (node.getTitle() != null) {
0546             title = getLatexListEntry("getTitle()", node.getTitle());
0547         }
0548     }
0549 
0550     public void visitLeave(final Node node) {
0551         if (node.getSucceedingText() != null && !brief) {
0552             printer.append(getLatexListEntry("getSucceedingText()", node.getSucceedingText()));
0553             printer.println();
0554             printer.println();
0555         }
0556         printer.println();
0557     }
0558 
0559     public void visitEnter(final Axiom axiom) {
0560         final QedeqNumbers numbers = getCurrentNumbers();
0561         printer.print("\u2609 ");
0562         printer.print("Axiom " + numbers.getAxiomNumber());
0563         printer.print(" ");
0564         if (title != null && title.length() 0) {
0565             printer.print(" (" + title + ")");
0566         }
0567         if (info) {
0568             printer.print("  [" + id + "]");
0569         }
0570         printer.println();
0571         printer.println();
0572         printer.print("     ");
0573         printFormula(axiom.getFormula().getElement());
0574         printer.println();
0575         if (axiom.getDescription() != null) {
0576             printer.append(getLatexListEntry("getDescription()", axiom.getDescription()));
0577             printer.println();
0578             printer.println();
0579         }
0580     }
0581 
0582     public void visitEnter(final Proposition proposition) {
0583         final QedeqNumbers numbers = getCurrentNumbers();
0584         printer.print("\u2609 ");
0585         printer.print("Proposition " + numbers.getPropositionNumber());
0586         printer.print(" ");
0587         if (title != null && title.length() 0) {
0588             printer.print(" (" + title + ")");
0589         }
0590         if (info) {
0591             printer.print("  [" + id + "]");
0592         }
0593         printer.println();
0594         printer.println();
0595         printTopFormula(proposition.getFormula().getElement(), id);
0596         printer.println();
0597         if (proposition.getDescription() != null) {
0598             printer.append(getLatexListEntry("getDescription()", proposition.getDescription()));
0599             printer.println();
0600             printer.println();
0601         }
0602     }
0603 
0604     public void visitEnter(final Proof proof) {
0605         if (brief) {
0606             setBlocked(true);
0607             return;
0608         }
0609         if ("de".equals(language)) {
0610             printer.println("Beweis:");
0611         else {
0612             printer.println("Proof:");
0613         }
0614         printer.append(getLatexListEntry("getNonFormalProof()", proof.getNonFormalProof()));
0615     }
0616 
0617     public void visitLeave(final Proof proof) {
0618         printer.println();
0619         printer.println("q.e.d.");
0620         printer.println();
0621         setBlocked(false);
0622     }
0623 
0624     public void visitEnter(final FormalProof proof) {
0625         if (brief) {
0626             setBlocked(true);
0627             return;
0628         }
0629         if ("de".equals(language)) {
0630             printer.println("Beweis (formal):");
0631         else {
0632             printer.println("Proof (formal):");
0633         }
0634     }
0635 
0636     public void visitLeave(final FormalProof proof) {
0637         if (!brief) {
0638             printer.println("q.e.d.");
0639             printer.println();
0640         }
0641         setBlocked(false);
0642     }
0643 
0644 
0645     public void visitEnter(final FormalProofLine line) {
0646         lineData.init();
0647         if (line.getLabel() != null) {
0648             lineData.setLineLabel(line.getLabel());
0649         }
0650         if (line.getReason() != null) {
0651             setReason(line.getReason().toString());
0652         }
0653         setFormula(line.getFormula());
0654     }
0655 
0656     public void visitLeave(final FormalProofLine line) {
0657         linePrintln();
0658     }
0659 
0660     /**
0661      * Print formula and reason.
0662      */
0663     private void linePrintln() {
0664         if (!lineData.containsData()) {
0665             return;
0666         }
0667         if (lineData.getLineLabel().length() 0) {
0668             printer.print(StringUtility.alignRight("(" + lineData.getLineLabel() ")"5" ");
0669         }
0670         for (int i = 0; i < lineData.lines(); i++) {
0671             printer.skipToColumn(6);
0672             printer.print(tab);
0673             if (i < lineData.getFormula().length) {
0674                 printer.print(lineData.getFormula()[i]);
0675             }
0676             if (i < lineData.getReason().length) {
0677                 printer.skipToColumn(+ formulaWidth);
0678                 printer.print(lineData.getReason()[i]);
0679             }
0680             printer.println();
0681         }
0682         lineData.init();
0683     }
0684 
0685     public void visitEnter(final ConditionalProof rthrows ModuleDataException {
0686         lineData.init();
0687         printer.skipToColumn(6);
0688         printer.print(tab);
0689         printer.println("Conditional Proof");
0690         tab = tab + "  ";
0691     }
0692 
0693     public void visitLeave(final ConditionalProof proof) {
0694         tab = StringUtility.substring(tab, 0, tab.length() 2);
0695     }
0696 
0697     public void visitEnter(final Hypothesis hypothesis) {
0698         lineData.init();
0699         if (hypothesis.getLabel() != null) {
0700             lineData.setLineLabel(hypothesis.getLabel());
0701         }
0702         setReason("Hypothesis");
0703         setFormula(hypothesis.getFormula());
0704     }
0705 
0706     public void visitLeave(final Hypothesis hypothesis) {
0707         linePrintln();
0708     }
0709 
0710     public void visitEnter(final Conclusion conclusion) {
0711         tab = StringUtility.substring(tab, 0, tab.length() 2);
0712         lineData.init();
0713         if (conclusion.getLabel() != null) {
0714             lineData.setLineLabel(conclusion.getLabel());
0715         }
0716         setReason("Conclusion");
0717         setFormula(conclusion.getFormula());
0718         linePrintln();
0719     }
0720 
0721     public void visitLeave(final Conclusion conclusion) {
0722         linePrintln();
0723         tab = tab + "  ";
0724     }
0725 
0726     private void setReason(final String reasonString) {
0727         final List list = new ArrayList();
0728         int index = 0;
0729         while (index < reasonString.length()) {
0730             list.add(StringUtility.substring(reasonString, index, reasonWidth));
0731             index += reasonWidth;
0732         }
0733         lineData.setReason((String[]) list.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
0734     }
0735 
0736     private void setFormula(final Formula f) {
0737         if (f != null && f.getElement() != null) {
0738             lineData.setFormula(getUtf8(f.getElement(),
0739                 formulaWidth - tab.length()));
0740         }
0741     }
0742 
0743     private String getReference(final String reference) {
0744         return getReference(reference, "getReference()");
0745     }
0746 
0747     private String getReference(final String reference, final String subContext) {
0748         final String context = getCurrentContext().getLocationWithinModule();
0749         try {
0750             getCurrentContext().setLocationWithinModule(context + "." + subContext);
0751             return (getReferenceLink(reference, null, null));
0752         finally {
0753             getCurrentContext().setLocationWithinModule(context);
0754         }
0755     }
0756 
0757     public void visitEnter(final ModusPonens rthrows ModuleDataException {
0758         String buffer = r.getName();
0759         boolean one = false;
0760         if (r.getReference1() != null) {
0761             buffer += " " + getReference(r.getReference1()"getReference1()");
0762             one = true;
0763         }
0764         if (r.getReference1() != null) {
0765             if (one) {
0766                 buffer += ",";
0767             }
0768             buffer += " " + getReference(r.getReference2()"getReference2()");
0769         }
0770         setReason(buffer);
0771     }
0772 
0773     public void visitEnter(final Add rthrows ModuleDataException {
0774         String buffer = r.getName();
0775         if (r.getReference() != null) {
0776             buffer += " " + getReference(r.getReference());
0777         }
0778         setReason(buffer);
0779     }
0780 
0781     public void visitEnter(final Rename rthrows ModuleDataException {
0782         String buffer = r.getName();
0783         if (r.getOriginalSubjectVariable() != null) {
0784             buffer += " " + getUtf8(r.getOriginalSubjectVariable());
0785         }
0786         if (r.getReplacementSubjectVariable() != null) {
0787             buffer += " by " + getUtf8(r.getReplacementSubjectVariable());
0788         }
0789         if (r.getReference() != null) {
0790             buffer += " in " + getReference(r.getReference());
0791         }
0792         setReason(buffer);
0793     }
0794 
0795     public void visitEnter(final SubstFree rthrows ModuleDataException {
0796         String buffer = r.getName();
0797         if (r.getSubjectVariable() != null) {
0798             buffer += " " + getUtf8(r.getSubjectVariable());
0799         }
0800         if (r.getSubstituteTerm() != null) {
0801             buffer += " by " + getUtf8(r.getSubstituteTerm());
0802         }
0803         if (r.getReference() != null) {
0804             buffer += " in " + getReference(r.getReference());
0805         }
0806         setReason(buffer);
0807     }
0808 
0809     public void visitEnter(final SubstFunc rthrows ModuleDataException {
0810         String buffer = r.getName();
0811         if (r.getFunctionVariable() != null) {
0812             buffer += " " + getUtf8(r.getFunctionVariable());
0813         }
0814         if (r.getSubstituteTerm() != null) {
0815             buffer += " by " + getUtf8(r.getSubstituteTerm());
0816         }
0817         if (r.getReference() != null) {
0818             buffer += " in " + getReference(r.getReference());
0819         }
0820         setReason(buffer);
0821     }
0822 
0823     public void visitEnter(final SubstPred rthrows ModuleDataException {
0824         String buffer = r.getName();
0825         if (r.getPredicateVariable() != null) {
0826             buffer += " " + getUtf8(r.getPredicateVariable());
0827         }
0828         if (r.getSubstituteFormula() != null) {
0829             buffer += " by " + getUtf8(r.getSubstituteFormula());
0830         }
0831         if (r.getReference() != null) {
0832             buffer += " in " + getReference(r.getReference());
0833         }
0834         setReason(buffer);
0835     }
0836 
0837     public void visitEnter(final Existential rthrows ModuleDataException {
0838         String buffer = r.getName();
0839         if (r.getSubjectVariable() != null) {
0840             buffer += " with " + getUtf8(r.getSubjectVariable());
0841         }
0842         if (r.getReference() != null) {
0843             buffer += " in " + getReference(r.getReference());
0844         }
0845         setReason(buffer);
0846     }
0847 
0848     public void visitEnter(final Universal rthrows ModuleDataException {
0849         String buffer = r.getName();
0850         if (r.getSubjectVariable() != null) {
0851             buffer += " with " + getKernelQedeqBo().getElement2Utf8().getUtf8(
0852                 r.getSubjectVariable());
0853         }
0854         if (r.getReference() != null) {
0855             buffer += " in " + getReference(r.getReference());
0856         }
0857         setReason(buffer);
0858     }
0859 
0860     public void visitEnter(final InitialPredicateDefinition definition) {
0861         final QedeqNumbers numbers = getCurrentNumbers();
0862         printer.print("\u2609 ");
0863         final StringBuffer buffer = new StringBuffer();
0864         if ("de".equals(language)) {
0865             buffer.append("initiale ");
0866         else {
0867             buffer.append("initial ");
0868         }
0869         buffer.append("Definition " (numbers.getPredicateDefinitionNumber()
0870             + numbers.getFunctionDefinitionNumber()));
0871         printer.print(buffer.toString());
0872         printer.print(" ");
0873         if (title != null && title.length() 0) {
0874             printer.print(" (" + title + ")");
0875         }
0876         if (info) {
0877             printer.print("  [" + id + "]");
0878         }
0879         printer.println();
0880         printer.println();
0881         printer.print("     ");
0882         printer.println(getUtf8(definition.getPredCon()));
0883         printer.println();
0884         if (definition.getDescription() != null) {
0885             printer.append(getLatexListEntry("getDescription()", definition.getDescription()));
0886             printer.println();
0887             printer.println();
0888         }
0889     }
0890 
0891     public void visitEnter(final PredicateDefinition definition) {
0892         final QedeqNumbers numbers = getCurrentNumbers();
0893         printer.print("\u2609 ");
0894         final StringBuffer buffer = new StringBuffer();
0895         buffer.append("Definition " (numbers.getPredicateDefinitionNumber()
0896             + numbers.getFunctionDefinitionNumber()));
0897         printer.print(buffer.toString());
0898         printer.print(" ");
0899         if (title != null && title.length() 0) {
0900             printer.print(" (" + title + ")");
0901         }
0902         if (info) {
0903             printer.print("  [" + id + "]");
0904         }
0905         printer.println();
0906         printer.println();
0907         printer.print("     ");
0908         printer.println(getUtf8(definition.getFormula().getElement()));
0909         printer.println();
0910         if (definition.getDescription() != null) {
0911             printer.append(getLatexListEntry("getDescription()", definition.getDescription()));
0912             printer.println();
0913             printer.println();
0914         }
0915     }
0916 
0917     public void visitEnter(final InitialFunctionDefinition definition) {
0918         final QedeqNumbers numbers = getCurrentNumbers();
0919         printer.print("\u2609 ");
0920         final StringBuffer buffer = new StringBuffer();
0921         if ("de".equals(language)) {
0922             buffer.append("initiale ");
0923         else {
0924             buffer.append("initial ");
0925         }
0926         buffer.append("Definition " (numbers.getPredicateDefinitionNumber()
0927                 + numbers.getFunctionDefinitionNumber()));
0928         printer.print(buffer.toString());
0929         printer.print(" ");
0930         if (title != null && title.length() 0) {
0931             printer.print(" (" + title + ")");
0932         }
0933         if (info) {
0934             printer.print("  [" + id + "]");
0935         }
0936         printer.println();
0937         printer.println();
0938         printer.print("     ");
0939         printer.println(getUtf8(definition.getFunCon()));
0940         printer.println();
0941         if (definition.getDescription() != null) {
0942             printer.println(getLatexListEntry("getDescription()", definition.getDescription()));
0943             printer.println();
0944         }
0945     }
0946 
0947     public void visitEnter(final FunctionDefinition definition) {
0948         final QedeqNumbers numbers = getCurrentNumbers();
0949         printer.print("\u2609 ");
0950         final StringBuffer buffer = new StringBuffer();
0951         buffer.append("Definition " (numbers.getPredicateDefinitionNumber()
0952                 + numbers.getFunctionDefinitionNumber()));
0953         printer.print(buffer.toString());
0954         printer.print(" ");
0955         if (title != null && title.length() 0) {
0956             printer.print(" (" + title + ")");
0957         }
0958         if (info) {
0959             printer.print("  [" + id + "]");
0960         }
0961         printer.println();
0962         printer.println();
0963         printer.print("     ");
0964         printer.println(getUtf8(definition.getFormula().getElement()));
0965         printer.println();
0966         if (definition.getDescription() != null) {
0967             printer.println(getLatexListEntry("getDescription()", definition.getDescription()));
0968             printer.println();
0969         }
0970     }
0971 
0972     public void visitEnter(final Rule rule) {
0973         final QedeqNumbers numbers = getCurrentNumbers();
0974         printer.print("\u2609 ");
0975         if ("de".equals(language)) {
0976             printer.print("Regel");
0977         else {
0978             printer.print("Rule");
0979         }
0980         printer.print(" " + numbers.getRuleNumber());
0981         printer.print(" ");
0982         if (title != null && title.length() 0) {
0983             printer.print(" (" + title + ")");
0984         }
0985         if (info) {
0986             printer.print("  [" + id + "]");
0987         }
0988         printer.println();
0989         printer.println((rule.getName() != null "  Name: " + rule.getName() "")
0990             (rule.getVersion() != null "  -  Version: " + rule.getVersion() ""));
0991         printer.println();
0992         if (rule.getDescription() != null) {
0993             printer.append(getLatexListEntry("getDescription()", rule.getDescription()));
0994             printer.println();
0995             printer.println();
0996         }
0997     }
0998 
0999     public void visitEnter(final LinkList linkList) {
1000         if (linkList.size() <= 0) {
1001             return;
1002         }
1003         if ("de".equals(language)) {
1004             printer.println("Basierend auf: ");
1005         else {
1006             if (!"en".equals(language)) {
1007                 printer.println("%%% TODO unknown language: " + language);
1008             }
1009             printer.println("Based on: ");
1010         }
1011         for (int i = 0; i < linkList.size(); i++) {
1012             if (linkList.get(i!= null) {
1013                 printer.print(" (" + linkList.get(i")");
1014             }
1015         };
1016         printer.println();
1017     }
1018 
1019     public void visitEnter(final ChangedRuleList list) {
1020         if (list.size() <= 0) {
1021             return;
1022         }
1023         printer.println();
1024         if ("de".equals(language)) {
1025             printer.println("Die folgenden Regeln m\u00FCssen erweitert werden.");
1026         else {
1027             if (!"en".equals(language)) {
1028                 printer.println("%%% TODO unknown language: " + language);
1029             }
1030             printer.println("The following rules have to be extended.");
1031         }
1032         printer.println();
1033     }
1034 
1035     public void visitEnter(final ChangedRule rule) {
1036         printer.println((rule.getName() != null "  Name: " + rule.getName() "")
1037             (rule.getVersion() != null "  -  Version: " + rule.getVersion() ""));
1038         printer.println();
1039         if (rule.getDescription() != null) {
1040             printer.append(getLatexListEntry("getDescription()", rule.getDescription()));
1041             printer.println();
1042             printer.println();
1043         }
1044 
1045     }
1046 
1047     public void visitEnter(final LiteratureItemList list) {
1048         printer.println();
1049         printer.println();
1050         if ("de".equals(language)) {
1051             underlineBig("Literaturverzeichnis");
1052         else {
1053             underlineBig("Bibliography");
1054         }
1055         printImports();
1056     }
1057 
1058     /**
1059      * Print all imports if any.
1060      */
1061     private void printImports() {
1062         final ImportList imports = getKernelQedeqBo().getQedeq().getHeader().getImportList();
1063         if (imports != null && imports.size() 0) {
1064             printer.println();
1065             printer.println();
1066             if ("de".equals(language)) {
1067                 printer.println("Benutzte andere QEDEQ-Module:");
1068             else {
1069                 printer.println("Used other QEDEQ modules:");
1070             }
1071             printer.println();
1072             for (int i = 0; i < imports.size(); i++) {
1073                 final Import imp = imports.get(i);
1074                 printer.print("[" + imp.getLabel() "] ");
1075                 final Specification spec = imp.getSpecification();
1076                 printer.print(spec.getName());
1077                 if (spec.getLocationList() != null && spec.getLocationList().size() 0
1078                         && spec.getLocationList().get(0).getLocation().length() 0) {
1079                     printer.print("  ");
1080                     printer.print(getUrl(getKernelQedeqBo().getModuleAddress(), spec));
1081                 }
1082                 printer.println();
1083             }
1084             printer.println();
1085             printer.println();
1086         }
1087     }
1088 
1089     public void visitLeave(final LiteratureItemList list) {
1090         final UsedByList usedby = getKernelQedeqBo().getQedeq().getHeader().getUsedByList();
1091         if (usedby != null && usedby.size() 0) {
1092             printer.println();
1093             printer.println();
1094             if ("de".equals(language)) {
1095                 printer.println("QEDEQ-Module, welche dieses hier verwenden:");
1096             else {
1097                 printer.println("QEDEQ modules that use this one:");
1098             }
1099             for (int i = 0; i < usedby.size(); i++) {
1100                 final Specification spec = usedby.get(i);
1101                 printer.print(spec.getName());
1102                 final String url = getUrl(getKernelQedeqBo().getModuleAddress(), spec);
1103                 if (url != null && url.length() 0) {
1104                     printer.print("  ");
1105                     printer.print(url);
1106                 }
1107                 printer.println();
1108             }
1109             printer.println();
1110             printer.println();
1111         }
1112         printer.println();
1113     }
1114 
1115     public void visitEnter(final LiteratureItem item) {
1116         printer.print("[" + item.getLabel() "] ");
1117         printer.println(getLatexListEntry("getItem()", item.getItem()));
1118         printer.println();
1119     }
1120 
1121     /**
1122      * Print top level formula. If the formula has the form <code>AND(.., .., ..)</code> the
1123      * formula is broken down in several labeled lines.
1124      *
1125      @param   element     Formula to print.
1126      @param   mainLabel   Main formula label.
1127      */
1128     private void printTopFormula(final Element element, final String mainLabel) {
1129         if (!element.isList() || !element.getList().getOperator().equals("AND")) {
1130             printer.print("     ");
1131             printFormula(element);
1132             return;
1133         }
1134         final ElementList list = element.getList();
1135         for (int i = 0; i < list.size(); i++)  {
1136             String label = "";
1137             if (list.size() >= ALPHABET.length() * ALPHABET.length()) {
1138                 label = "" (i + 1);
1139             else {
1140                 if (list.size() > ALPHABET.length()) {
1141                     final int div = (i / ALPHABET.length());
1142                     label = "" + ALPHABET.charAt(div);
1143                 }
1144                 label += ALPHABET.charAt(i % ALPHABET.length());
1145             }
1146             printer.println("  (" + label + ")  " + getUtf8(list.getElement(i)));
1147         }
1148     }
1149 
1150     /**
1151      * Print formula.
1152      *
1153      @param   element Formula to print.
1154      */
1155     private void printFormula(final Element element) {
1156         printer.println(getUtf8(element));
1157     }
1158 
1159     /**
1160      * Filters correct entry out of LaTeX list. Filter criterion is for example the correct
1161      * language.
1162      *
1163      @param   method  This method was called. Used to get the correct sub context.
1164      *                  Should not be null. If it is empty the <code>subContext</code>
1165      *                  is not changed.
1166      @param   list    List of LaTeX texts.
1167      @return  Filtered text.
1168      */
1169     private String getLatexListEntry(final String method, final LatexList list) {
1170         if (list == null) {
1171             return "";
1172         }
1173         if (method.length() 0) {
1174             subContext = method;
1175         }
1176         try {
1177             for (int i = 0; i < list.size(); i++) {
1178                 if (language.equals(list.get(i).getLanguage())) {
1179                     if (method.length() 0) {
1180                         subContext = method + ".get(" + i + ")";
1181                     }
1182                     return getUtf8(list.get(i));
1183                 }
1184             }
1185             // OK, we didn't found the language, so we take the default language
1186             final String def = getKernelQedeqBo().getOriginalLanguage();
1187             for (int i = 0; i < list.size(); i++) {
1188                 if (EqualsUtility.equals(def, list.get(i).getLanguage())) {
1189                     if (method.length() 0) {
1190                         subContext = method + ".get(" + i + ")";
1191                     }
1192                     return "MISSING! OTHER: " + getUtf8(list.get(i));
1193                 }
1194             }
1195             // OK, we didn't find wanted and default language, so we take the first non empty one
1196             for (int i = 0; i < list.size(); i++) {
1197                 if (method.length() 0) {
1198                     subContext = method + ".get(" + i + ")";
1199                 }
1200                 if (null != list.get(i&& null != list.get(i).getLatex()
1201                         && list.get(i).getLatex().trim().length() 0) {
1202                     return "MISSING! OTHER: " + getUtf8(list.get(i));
1203                 }
1204             }
1205             return "MISSING!";
1206         finally {
1207             if (method.length() 0) {
1208                 subContext = "";
1209             }
1210         }
1211     }
1212 
1213     /**
1214      * Get current module context. Uses sub context information.
1215      *
1216      @param   startDelta  Skip position (relative to location start). Could be
1217      *                      <code>null</code>.
1218      @param   endDelta    Mark until this column (relative to location start).
1219      *                      be <code>null</code>
1220      @return  Current module context.
1221      */
1222     private ModuleContext getCurrentContext(final SourcePosition startDelta,
1223             final SourcePosition endDelta) {
1224         if (subContext.length() == 0) {
1225             return super.getCurrentContext();
1226         }
1227         final ModuleContext c = new ModuleContext(super.getCurrentContext().getModuleLocation(),
1228             super.getCurrentContext().getLocationWithinModule() "." + subContext,
1229             startDelta, endDelta);
1230         return c;
1231     }
1232 
1233     /**
1234      * Add warning.
1235      *
1236      @param   code        Warning code.
1237      @param   msg         Warning message.
1238      @param   startDelta  Skip position (relative to location start). Could be
1239      *                      <code>null</code>.
1240      @param   endDelta    Mark until this column (relative to location start). Could be
1241      *                      be <code>null</code>
1242      */
1243     public void addWarning(final int code, final String msg, final SourcePosition startDelta,
1244             final SourcePosition endDelta) {
1245         Trace.param(CLASS, this, "addWarning""msg", msg);
1246         if (addWarnings) {
1247             addWarning(new UnicodeException(code, msg, getCurrentContext(startDelta,
1248                 endDelta)));
1249         }
1250     }
1251 
1252     /**
1253      * Add warning.
1254      *
1255      @param   code        Warning code.
1256      @param   msg         Warning message.
1257      */
1258     public void addWarning(final int code, final String msg) {
1259         Trace.param(CLASS, this, "addWarning""msg", msg);
1260         if (addWarnings) {
1261             addWarning(new UnicodeException(code, msg, getCurrentContext()));
1262         }
1263     }
1264 
1265     /**
1266      * Get Utf8 element presentation.
1267      *
1268      @param   element     Get presentation of this element.
1269      @param   max         Maximum column.
1270      @return  UTF-8 form of element.
1271      */
1272     protected String[] getUtf8(final Element element, final int max) {
1273         return getKernelQedeqBo().getElement2Utf8().getUtf8(element, max);
1274     }
1275 
1276 
1277     /**
1278      * Get Utf8 element presentation.
1279      *
1280      @param   element    Get presentation of this element.
1281      @return  UTF-8 form of element.
1282      */
1283     protected String getUtf8(final Element element) {
1284         return getUtf8(getKernelQedeqBo().getElement2Latex().getLatex(element));
1285     }
1286 
1287     /**
1288      * Get UTF-8 String for LaTeX.
1289      *
1290      @param   latex   LaTeX we got.
1291      @return  UTF-8 result string.
1292      */
1293     private String getUtf8(final Latex latex) {
1294         if (latex == null || latex.getLatex() == null) {
1295             return "";
1296         }
1297         return getUtf8(latex.getLatex());
1298     }
1299 
1300     /**
1301      * Transform LaTeX into UTF-8 String..
1302      *
1303      @param   latex   LaTeX text.
1304      @return  String.
1305      */
1306     private String getUtf8(final String latex) {
1307         if (latex == null) {
1308             return "";
1309         }
1310         return Latex2UnicodeParser.transform(this, latex, maxColumns);
1311     }
1312 
1313     /**
1314      * Print text in one line and print another line with = to underline it.
1315      *
1316      @param   text    Line to print.
1317      */
1318     private void underlineBig(final String text) {
1319         printer.println(text);
1320         for (int i = 0; i  < text.length(); i++) {
1321             printer.print("\u2550");
1322         }
1323         printer.println();
1324     }
1325 
1326     /**
1327      * Print text in one line and print another line with = to underline it.
1328      *
1329      @param   text    Line to print.
1330      */
1331     private void underline(final String text) {
1332         printer.println(text);
1333         for (int i = 0; i  < text.length(); i++) {
1334             printer.print("\u2015");
1335         }
1336         printer.println();
1337     }
1338 
1339     public String getReferenceLink(final String reference, final SourcePosition start,
1340             final SourcePosition end) {
1341         final Reference ref = getReference(reference, getCurrentContext(start, end), addWarnings,
1342             false);
1343 
1344         if (ref.isNodeLocalReference() && ref.isSubReference()) {
1345             return "(" + ref.getSubLabel() ")";
1346         }
1347 
1348         if (ref.isNodeLocalReference() && ref.isProofLineReference()) {
1349             return "(" + ref.getProofLineLabel() ")";
1350         }
1351 
1352         if (!ref.isExternal()) {
1353             return getNodeDisplay(ref.getNodeLabel(), ref.getNode())
1354                 (ref.isSubReference() " (" + ref.getSubLabel() ")" "")
1355                 (ref.isProofLineReference() " (" + ref.getProofLineLabel() ")" "");
1356         }
1357 
1358         // do we have an external module reference without node?
1359         if (ref.isExternalModuleReference()) {
1360             return "[" + ref.getExternalQedeqLabel() "]";
1361         }
1362 
1363         return getNodeDisplay(ref.getNodeLabel(), ref.getNode())
1364             (ref.isSubReference() " (" + ref.getSubLabel() ")" "")
1365             (ref.isProofLineReference() " (" + ref.getProofLineLabel() ")" "")
1366             (ref.isExternal() " [" + ref.getExternalQedeqLabel() "]" "");
1367     }
1368 
1369     private String getNodeDisplay(final String label, final KernelNodeBo kNode) {
1370         return getNodeDisplay(label, kNode, language);
1371     }
1372 
1373 }