/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.dg.latex; import java.awt.Color; import java.io.File; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.velocity.VelocityContext; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.openflexo.dg.DGGenerator; import org.openflexo.dg.rm.LatexFileResource; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.cg.CGSymbolicDirectory; import org.openflexo.foundation.cg.DGRepository; import org.openflexo.foundation.cg.generator.GeneratedCodeResult; import org.openflexo.foundation.cg.generator.GeneratedTextResource; import org.openflexo.foundation.cg.generator.IFlexoResourceGenerator; import org.openflexo.foundation.dm.DMEntity; import org.openflexo.foundation.dm.DMRepository; import org.openflexo.foundation.ie.cl.ComponentDefinition; import org.openflexo.foundation.ie.widget.IEButtonWidget; import org.openflexo.foundation.ie.widget.IEDynamicImage; import org.openflexo.foundation.ie.widget.IEHyperlinkWidget; import org.openflexo.foundation.toc.TOCEntry; import org.openflexo.foundation.utils.FlexoCSS; import org.openflexo.foundation.wkf.FlexoProcess; import org.openflexo.foundation.wkf.node.OperationNode; import org.openflexo.generator.exception.GenerationException; import org.openflexo.generator.exception.TemplateNotFoundException; import org.openflexo.toolbox.HTMLUtils; import org.openflexo.toolbox.LatexUtils; /** * @author gpolet * */ public class DGLatexGenerator<T extends FlexoModelObject> extends DGGenerator<T> implements IFlexoResourceGenerator { protected static final String UPPER_CASE_REGEXP = "[A-Z]+"; protected static final Pattern UPPER_CASE_PATTERN = Pattern.compile(UPPER_CASE_REGEXP); protected static final String LATEX_BACKSLASH = HTMLUtils.LATEX_BACKSLASH; protected static final String JAVA_BACKSLASH = "\\"; protected static final String LATEX_TAG_REGEXP = "^\\\\[^ {]+(\\{[^}]*\\}\\s*)*"; protected static final Pattern LATEX_TAG_PATTERN = Pattern.compile(LATEX_TAG_REGEXP); protected static final String CHARS_TO_ESCAPE_REGEXP = "[\\\\{}_&%#~]"; protected static final Pattern CHARS_TO_ESCAPE_PATTERN = Pattern.compile(CHARS_TO_ESCAPE_REGEXP); protected static final Logger logger = Logger.getLogger(DGLatexGenerator.class.getPackage().getName()); protected LatexFileResource<DGLatexGenerator<T>> latexResource; public static String getLatexFileExtension() { return ".tex"; } public static String nameForObject(FlexoModelObject object, DGRepository repository) { return nameForObjectNoExt(object, repository) + getLatexFileExtension(); } public static String nameForProject(DGRepository repository) { return nameForProjectNoExt(repository) + getLatexFileExtension(); } public static String nameForProcess(FlexoProcess process, DGRepository repository) { return nameForProcessNoExt(process, repository) + getLatexFileExtension(); } public static String nameForDKV(DGRepository repository) { return nameForDKVNoExt(repository) + getLatexFileExtension(); } public static String nameForOperation(OperationNode operation, DGRepository repository) { return nameForOperationNoExt(operation, repository) + getLatexFileExtension(); } public static String nameForMenu(DGRepository repository) { return nameForMenuNoExt(repository) + getLatexFileExtension(); } public static String nameForComponent(ComponentDefinition cd, DGRepository repository) { return nameForComponentNoExt(cd, repository) + getLatexFileExtension(); } public static String nameForDataModel(DGRepository repository) { return nameForDataModelNoExt(repository) + getLatexFileExtension(); } public static String nameForComponentLibrary(DGRepository repository) { return nameForComponentLibraryNoExt(repository) + getLatexFileExtension(); } public static String nameForWorkflow(DGRepository repository) { return nameForWorkflowNoExt(repository) + getLatexFileExtension(); } public static String nameForReadersGuide(DGRepository repository) { return nameForReadersGuideNoExt(repository) + getLatexFileExtension(); } public static String nameForDefinitions(DGRepository repository) { return nameForDefinitionsNoExt(repository) + getLatexFileExtension(); } public static String nameForRepository(DMRepository dmr, DGRepository repository) { return nameForRepositoryNoExt(dmr, repository) + getLatexFileExtension(); } public static String nameForEntity(DMEntity entity, DGRepository repository) { return nameForEntityNoExt(entity, repository) + getLatexFileExtension(); } protected DGLatexGenerator(ProjectDocLatexGenerator projectGenerator, T source) { super(projectGenerator, source); } public DGLatexGenerator(ProjectDocLatexGenerator projectGenerator, T source, String templateName) { super(projectGenerator, source, templateName); } public DGLatexGenerator(ProjectDocLatexGenerator projectGenerator, T source, String templateName, String identifier, String fileName, TOCEntry entry) { super(projectGenerator, source, templateName, identifier, fileName, entry); } @Override public ProjectDocLatexGenerator getProjectGenerator() { return (ProjectDocLatexGenerator) super.getProjectGenerator(); } public String getBlockTemplatePath() { try { return templateWithName("block.tex.vm").getRelativePath(); } catch (TemplateNotFoundException e) { e.printStackTrace(); return "block.tex.vm"; } } public static String convertHTML2Latex(String htmlString) { String converted = HTMLUtils.convertHTML2Latex(htmlString); if (converted == null) { return ""; } else { return converted; } } public static String prepareJavaStringForLatex(String javaString) { return LatexUtils.prepareJavaStringForLatex(javaString); } public static String splitOnUpperCase(String s) { if (s == null || s.trim().length() == 0) { return ""; } Matcher m = UPPER_CASE_PATTERN.matcher(s); StringBuffer sb = new StringBuffer(); while (m.find()) { if (sb.length() == 0 && m.start() == 0) { m.appendReplacement(sb, "$0"); } else { m.appendReplacement(sb, "\\\\-$0"); } } m.appendTail(sb); return sb.toString(); } public CGSymbolicDirectory getSymbolicDirectory(DGRepository repository) { return repository.getLatexSymbolicDirectory(); } /** * Overrides getFileExtension * * @see org.openflexo.dg.DGGenerator#getFileExtension() */ @Override public String getFileExtension() { return getLatexFileExtension(); } public String getSystemActions(IEHyperlinkWidget button) { if (button == null) { return ""; } StringBuilder sb = new StringBuilder(); if (button.getPopupComponentDefinition() != null) { sb.append("opens popup " + "\\hyperlink{" + getReference(button.getPopupComponentDefinition()) + "}{" + button.getPopupComponentDefinition().getComponentName() + "}"); } if (button.getLink() != null && button.getLink().trim().length() > 0) { if (sb.length() > 0) { sb.append("\\par "); } String lnk = LatexUtils.prepareJavaStringForLatex(button.getLink()); if (button.getFuncName() != null && button.getFuncName().trim().length() > 0) { sb.append("\\href{" + lnk + "}{" + button.getFuncName() + "}"); } else { sb.append("\\href{" + lnk + "}{" + lnk + "}"); } } return sb.toString(); } protected FlexoCSS getCss() { return getObject().getProject().getCssSheet(); } public String getImageString(IEHyperlinkWidget button) { if (button == null) { return ""; } if (button.isCustomButton()) { StringBuilder sb = new StringBuilder(); Color c = getCss().getTextColor(); sb.append(Math.round(c.getRed() * 10000d / 255) / 10000d); sb.append(','); sb.append(Math.round(c.getGreen() * 10000d / 255) / 10000d); sb.append(','); sb.append(Math.round(c.getBlue() * 10000d / 255) / 10000d); return "\\custombutton[" + sb.toString() + "]{" + button.getValue() + "}"; } else if (button instanceof IEDynamicImage) { return "\\emph{A dynamic image}"; } else if (button instanceof IEButtonWidget) { String fullName = ((IEButtonWidget) button).getImageName(); String fileName = cleanFileName(fullName.substring(0, fullName.lastIndexOf('.'))) + ".jpg"; while (fileName.startsWith("-") && fileName.length() > 2) { fileName = fileName.substring(1); } File file = new File(getRepository().getFiguresSymbolicDirectory().getDirectory().getFile().getAbsolutePath() + "/" + fileName); fileName = getRepository().getFiguresSymbolicDirectory().getName() + "/" + fileName; ((IEButtonWidget) button).getFile().createButton(file); StringBuilder sb = new StringBuilder(); sb.append("\\buttonfigure{").append(fileName).append("}"); return sb.toString(); } else { IEHyperlinkWidget link = button; return "\\bluehyperlink{" + link.getValue() + "}"; } } @Override protected VelocityContext defaultContext() { VelocityContext vc = super.defaultContext(); TOCEntry entry = getTOCEntry(); if (entry != null) { vc.put("entry", entry); } return vc; } /** * Overrides merge * * @throws Exception * @throws ParseErrorException * @throws ResourceNotFoundException * @see org.openflexo.dg.DGGenerator#merge(java.lang.String, org.apache.velocity.VelocityContext) */ @Override public String merge(String templateName, VelocityContext velocityContext) throws GenerationException { String result = super.merge(templateName, velocityContext); return result.replaceAll("\\s*?\n\\s*?\n\\s*", "\n\n"); } @Override public GeneratedCodeResult getGeneratedCode() { if (generatedCode == null && latexResource != null && latexResource.getASCIIFile() != null && latexResource.getASCIIFile().hasLastAcceptedContent()) { generatedCode = new GeneratedTextResource(getFileName(), latexResource.getASCIIFile().getLastAcceptedContent()); } return super.getGeneratedCode(); } public void setLatexResource(LatexFileResource<DGLatexGenerator<T>> latexResource) { this.latexResource = latexResource; } }