2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with any library licensed under the Apache Software License,
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23 * (or with modified versions of the above that use the same license as the above),
24 * and distribute linked combinations including the two. You must obey the
25 * GNU General Public License in all respects for all of the code used other than
26 * the above mentioned libraries. If you modify this file, you may extend this
27 * exception to your version of the file, but you are not obligated to do so.
28 * If you do not wish to do so, delete this exception statement from your version.
30 package mircoders.pdf;
33 import gnu.regexp.REMatch;
34 import gnu.regexp.REMatchEnumeration;
35 import gnu.regexp.REException;
37 import java.io.ByteArrayOutputStream;
38 import java.io.IOException;
39 import java.net.MalformedURLException;
41 import com.lowagie.text.BadElementException;
42 import com.lowagie.text.Document;
43 import com.lowagie.text.DocumentException;
44 import com.lowagie.text.Element;
45 import com.lowagie.text.Font;
46 import com.lowagie.text.Image;
47 import com.lowagie.text.PageSize;
48 import com.lowagie.text.Paragraph;
49 import com.lowagie.text.Phrase;
50 import com.lowagie.text.pdf.BaseFont;
51 import com.lowagie.text.pdf.ColumnText;
52 import com.lowagie.text.pdf.PdfContentByte;
53 import com.lowagie.text.pdf.PdfTemplate;
54 import com.lowagie.text.pdf.PdfWriter;
58 import mir.config.MirPropertiesConfiguration;
59 import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
60 import mir.entity.EntityList;
61 import mir.log.LoggerWrapper;
62 import mircoders.entity.EntityContent;
63 import mircoders.entity.EntityImages;
64 import mircoders.storage.DatabaseContentToMedia;
69 public class PDFGenerator{
71 public Document document;
72 public PdfWriter writer;
73 public PdfContentByte cb;
74 public String localImageDir;
75 public float currentYPosition;
76 public int currentPage;
77 public float pageWidth;
78 public float pageHeight;
79 public float verticalMargin;
80 public float horizontalMargin;
82 public float bottomEdge;
83 public float rightEdge;
84 public float leftEdge;
86 public int maxImageHeight;
87 public int maxImageWidth;
88 protected LoggerWrapper logger;
90 public int indexFontSize;
91 public int indexLineHeight;
92 public int indexFontFamily;
94 public float footerHeight;
95 public String footerText;
96 public int footerFontSize;
97 public int footerFontFamily;
99 public int metaHeight;
100 public int metaFontSize;
101 public int metaFontFamily;
103 public int descriptionLineHeight;
104 public int descriptionFontSize;
105 public int descriptionFontFamily;
107 public int contentLineHeight;
108 public int contentFontSize;
109 public int contentFontFamily;
111 public int sourceLineHeight;
112 public int sourceFontSize;
113 public int sourceFontFamily;
115 public int bigImageCaptionFontSize;
116 public int bigImageCaptionFontFamily;
118 protected MirPropertiesConfiguration configuration;
121 public PDFGenerator(ByteArrayOutputStream out){
122 logger = new LoggerWrapper("PDFGenerator");
124 configuration = MirPropertiesConfiguration.instance();
126 catch (PropertiesConfigExc e) {
127 throw new RuntimeException("Can't get configuration: " + e.getMessage());
129 localImageDir=configuration.getString("Producer.Image.Path");
132 indexFontSize = Integer.parseInt(configuration.getString("PDF.Index.FontSize"));
133 indexLineHeight = Integer.parseInt(configuration.getString("PDF.Index.LineHeight"));
134 indexFontFamily = getFontByName(configuration.getString("PDF.Index.FontFamily"));
136 footerText = configuration.getString("PDF.Footer.String");
137 footerFontSize = Integer.parseInt(configuration.getString("PDF.Footer.FontSize"));
138 footerFontFamily = getFontByName(configuration.getString("PDF.Footer.FontFamily"));
139 footerHeight = Integer.parseInt(configuration.getString("PDF.Footer.Height"));;
141 metaFontSize = Integer.parseInt(configuration.getString("PDF.Meta.FontSize"));
142 metaFontFamily = getFontByName(configuration.getString("PDF.Meta.FontFamily"));
143 metaHeight = Integer.parseInt(configuration.getString("PDF.Meta.Height"));;
145 descriptionFontSize = Integer.parseInt(configuration.getString("PDF.Description.FontSize"));
146 descriptionLineHeight = Integer.parseInt(configuration.getString("PDF.Description.LineHeight"));
147 descriptionFontFamily = getFontByName(configuration.getString("PDF.Description.FontFamily"));
149 contentFontSize = Integer.parseInt(configuration.getString("PDF.Content.FontSize"));
150 contentLineHeight = Integer.parseInt(configuration.getString("PDF.Content.LineHeight"));
151 contentFontFamily = getFontByName(configuration.getString("PDF.Content.FontFamily"));
153 sourceFontSize = Integer.parseInt(configuration.getString("PDF.Source.FontSize"));
154 sourceLineHeight = Integer.parseInt(configuration.getString("PDF.Source.LineHeight"));
155 sourceFontFamily = getFontByName(configuration.getString("PDF.Source.FontFamily"));
157 bigImageCaptionFontSize = Integer.parseInt(configuration.getString("PDF.BigImageCaption.FontSize"));
158 bigImageCaptionFontFamily = getFontByName(configuration.getString("PDF.BigImageCaption.FontFamily"));
161 catch (NumberFormatException e){
165 // step 1: make a document
167 String pageSize = configuration.getString("PDF.Pagesize");
169 if (pageSize.equals("LETTER")){
170 document = new Document(PageSize.LETTER);
175 document = new Document(PageSize.A4);
180 maxImageHeight = 250;
185 horizontalMargin = 20;
189 topEdge=pageHeight-verticalMargin;
190 bottomEdge=verticalMargin;
191 rightEdge=pageWidth-horizontalMargin;
192 leftEdge=horizontalMargin;
194 currentYPosition=topEdge;
197 String headerText = configuration.getString("PDF.Title.String");
200 writer = PdfWriter.getInstance(document, out);
201 cb = writer.getDirectContent();
204 addHeader(headerText);
206 catch(DocumentException de) {
207 logger.error(de.getMessage());
216 public void addHeader(String headerText){
217 int titleFontSize=Integer.parseInt(configuration.getString("PDF.Title.FontSize"));
218 int titleLineHeight=Integer.parseInt(configuration.getString("PDF.Title.LineHeight"));
219 String titleFontFamily=configuration.getString("PDF.Title.FontFamily");
220 String headerImage=configuration.getString("PDF.Header.Image");
221 int headerImageHeight = Integer.parseInt(configuration.getString("PDF.Header.ImageHeight"));
224 if ((! headerImage.equals("")) && headerImageHeight != 0){
225 PdfTemplate template = cb.createTemplate(rightEdge-horizontalMargin,headerImageHeight);
227 float toYPosition=currentYPosition - headerImageHeight;
228 Image theImage = Image.getInstance(headerImage);
229 theImage.setAbsolutePosition(0,0);
230 // theImage.scaleAbsolute(img_width,img_height);
231 template.addImage(theImage);
234 cb.addTemplate(template,leftEdge,toYPosition);
235 currentYPosition = toYPosition;
237 if (! headerText.equals("")){
238 ColumnText ct = new ColumnText(cb);
240 ct.addText(new Phrase(headerText, new Font(getFontByName(titleFontFamily), titleFontSize,Font.BOLD)));
241 float[] rightCol = {rightEdge,currentYPosition,rightEdge,currentYPosition-titleLineHeight};
242 float[] leftCol = {leftEdge,currentYPosition,leftEdge,currentYPosition-titleLineHeight};
243 ct.setColumns(leftCol,rightCol);
244 ct.setYLine(currentYPosition);
245 ct.setAlignment(Element.ALIGN_CENTER);
248 currentYPosition = currentYPosition - titleLineHeight;
251 catch(DocumentException de) {
252 logger.error(de.getMessage());
254 catch(MalformedURLException de) {
255 logger.error(de.getMessage());
257 catch(IOException de) {
258 logger.error(de.getMessage());
261 public void addIndexItem(EntityContent entityContent){
264 ColumnText ict = new ColumnText(cb);
265 String theTitle = entityContent.getValue("title");
266 String theCreator = entityContent.getValue("creator");
267 Phrase titleP=new Phrase(" - " + theTitle,new Font(indexFontFamily,indexFontSize,Font.BOLD));
268 Phrase creatorP=new Phrase( " :: " + theCreator,new Font(indexFontFamily,indexFontSize));
269 float toYPosition = currentYPosition - indexLineHeight;
270 float[] leftIndexCols = {leftEdge,currentYPosition,leftEdge,toYPosition};
271 float[] rightIndexCols = {rightEdge,currentYPosition,rightEdge,toYPosition};
273 ict.addText(creatorP);
274 ict.setColumns(leftIndexCols,rightIndexCols);
275 ict.setYLine(currentYPosition);
276 ict.setAlignment(Element.ALIGN_LEFT);
278 currentYPosition = toYPosition;
280 catch(DocumentException de) {
281 logger.error(de.getMessage());
288 private int addTextLine(ColumnText ct,int lineHeight,int alignment,float left, float right){
289 logger.debug("adding a line of text");
290 if (! enoughY(lineHeight)){
293 float toYPosition = currentYPosition - lineHeight;
294 float[] leftContentCols = {left,currentYPosition,left,toYPosition};
295 float[] rightContentCols = {right,currentYPosition,right,toYPosition};
296 ct.setColumns(leftContentCols,rightContentCols);
297 ct.setYLine(currentYPosition);
298 ct.setAlignment(alignment);
301 currentYPosition = toYPosition;
304 catch(DocumentException de) {
305 logger.error(de.getMessage());
310 public void addLine(){
312 cb.moveTo(rightEdge, currentYPosition-5);
313 cb.lineTo(leftEdge, currentYPosition-5);
315 currentYPosition = currentYPosition - 10;
319 public void addFooter(){
321 ColumnText fct = new ColumnText(cb);
323 cb.moveTo(rightEdge, bottomEdge+footerHeight-5);
324 cb.lineTo(leftEdge, bottomEdge+footerHeight-5);
326 float[] leftFooterCols = {leftEdge,bottomEdge+footerHeight-1,leftEdge,bottomEdge};
327 float[] rightFooterCols = {rightEdge,bottomEdge+footerHeight-1,rightEdge,bottomEdge};
329 Paragraph footerP=new Paragraph(footerText,new Font(footerFontFamily,footerFontSize));
330 fct.addText(footerP);
332 fct.setColumns(leftFooterCols,rightFooterCols);
333 fct.setYLine(bottomEdge+footerHeight-1);
334 fct.setAlignment(Element.ALIGN_JUSTIFIED);
337 Paragraph numberP=new Paragraph((new Integer(currentPage)).toString(),new Font(footerFontFamily,footerFontSize,Font.BOLD));
338 fct.addText(numberP);
339 fct.setAlignment(Element.ALIGN_RIGHT);
343 catch (DocumentException de){
344 logger.error(de.getMessage());
350 public void newPage(){
356 currentYPosition=topEdge;
358 catch(DocumentException de) {
359 logger.error(de.getMessage());
363 public void addArticleSeparator(){
369 cb.moveTo(rightEdge, currentYPosition-5);
370 cb.lineTo(leftEdge, currentYPosition-5);
372 currentYPosition = currentYPosition - 10;
375 public void addArticleMetaInfo(ColumnText ct,String theTitle,String theCreator,String theDate){
376 //see if we have room for the author and title
378 if (! enoughY(metaHeight)){
382 Paragraph titleP=new Paragraph(theTitle+"\n",new Font(metaFontFamily,metaFontSize,Font.BOLD));
383 Paragraph whowhenP=new Paragraph(theCreator + " " + theDate ,new Font(metaFontFamily,metaFontSize));
385 ct.addText(whowhenP);
387 ct.setYLine(currentYPosition);
388 ct.setAlignment(Element.ALIGN_LEFT);
390 float toYPosition = currentYPosition - metaHeight;
391 float[] leftHeadCols = {leftEdge,currentYPosition,leftEdge,toYPosition};
392 float[] rightHeadCols = {rightEdge,currentYPosition,rightEdge,toYPosition};
394 ct.setColumns(leftHeadCols,rightHeadCols);
397 currentYPosition = toYPosition;
399 catch(DocumentException de) {
400 logger.error(de.getMessage());
405 public void addArticleDescription(ColumnText ct,String theDescription){
406 // Now we add the description, one line at a time, the ct should be empty at this point
409 Paragraph descP=new Paragraph(theDescription,new Font(descriptionFontFamily,descriptionFontSize,Font.BOLD));
412 // every article has a description, so we can assume that:
413 int status = ColumnText.NO_MORE_COLUMN;
416 while ((status & ColumnText.NO_MORE_TEXT) == 0 && brake >0){
417 //there is still text left in the description.
418 status = addTextLine(ct,descriptionLineHeight,Element.ALIGN_JUSTIFIED,leftEdge,rightEdge);
422 logger.error("runaway description...try increasing the line height or decreasing the font size");
425 public void addArticleContent(ColumnText ct,String theContent,EntityList images){
426 //let's go ahead and add in all the body text
427 Paragraph contentP=new Paragraph(theContent,new Font(contentFontFamily,contentFontSize));
428 ct.addText(contentP);
430 int contentLinesBeforeImages=3;
431 //and assume we have at least one line of text in the content
432 int status = ColumnText.NO_MORE_COLUMN;
434 // let's add a little bit of text, like a couple of lines
436 while (((status & ColumnText.NO_MORE_TEXT) == 0) && x<contentLinesBeforeImages){
437 status=addTextLine(ct,contentLineHeight,Element.ALIGN_JUSTIFIED,leftEdge,rightEdge);
441 boolean addImageOnLeft = true; //we will alternate within articles
442 while (images.hasNext()){
444 EntityImages currentImage=(EntityImages) images.next();
445 float img_width=(new Float(currentImage.getValue("img_width"))).floatValue();
446 float img_height=(new Float(currentImage.getValue("img_height"))).floatValue();
447 if (img_height>maxImageHeight){
448 img_width=(new Float((new Float(img_width*(maxImageHeight/img_height))).intValue())).floatValue();
449 img_height=maxImageHeight;
451 if (img_width>maxImageWidth){
452 img_height=(new Float((new Float(img_height*(maxImageWidth/img_width))).intValue())).floatValue();
453 img_width=maxImageWidth;
456 String img_title=currentImage.getValue("title");
457 String img_path=currentImage.getValue("publish_path");
459 if ((status & ColumnText.NO_MORE_TEXT) == 0){
460 // there is still text, so add an image which will have text wrapped around it, then add the text which
461 // will be on the left or the right of the image
463 float templateMinimumHeight = img_height+20;
464 float templateWidth = img_width+10;
465 float templateHeight = templateMinimumHeight+contentLineHeight-(templateMinimumHeight % contentLineHeight);
467 PdfTemplate template = cb.createTemplate(templateWidth,templateHeight);
470 //here we need a page check
471 if (! enoughY((new Float(templateHeight)).intValue())){
472 //ok, well just fill text to the bottom then
473 float toYPosition = bottomEdge+footerHeight;
474 float[] leftBottomCols = {leftEdge,currentYPosition,leftEdge,toYPosition};
475 float[] rightBottomCols = {rightEdge,currentYPosition,rightEdge,toYPosition};
476 ct.setColumns(leftBottomCols,rightBottomCols);
477 ct.setYLine(currentYPosition);
478 ct.setAlignment(Element.ALIGN_JUSTIFIED);
482 catch(DocumentException de) {
483 logger.error(de.getMessage());
488 float toYPosition=currentYPosition - templateHeight;
491 Image theImage = Image.getInstance(localImageDir+img_path);
492 theImage.scaleAbsolute(img_width,img_height);
493 theImage.setAbsolutePosition(5,13);
495 template.addImage(theImage);
496 template.beginText();
497 BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
498 template.setFontAndSize(bf, 8);
499 template.setTextMatrix(5, 3);
500 template.showText(img_title);
503 catch(BadElementException de) {
504 logger.error(de.getMessage());
506 catch(DocumentException de) {
507 logger.error(de.getMessage());
509 catch (MalformedURLException de){
510 logger.error(de.getMessage());
512 catch (IOException de){
513 logger.error(de.getMessage());
517 float leftImageTextEdge=leftEdge;
518 float rightImageTextEdge=rightEdge;
522 cb.addTemplate(template,leftEdge,toYPosition);
523 leftImageTextEdge=leftEdge+templateWidth+5;
524 addImageOnLeft = false;
527 cb.addTemplate(template,rightEdge-templateWidth,toYPosition);
528 rightImageTextEdge = rightEdge-templateWidth-5;
529 addImageOnLeft = true;
532 logger.debug("adding template at " + leftEdge + "," + toYPosition);
534 //and fill some text while we are at it
536 float[] leftBottomCols = {leftImageTextEdge,currentYPosition,leftImageTextEdge,toYPosition};
537 float[] rightBottomCols = {rightImageTextEdge,currentYPosition,rightImageTextEdge,toYPosition};
538 ct.setColumns(leftBottomCols,rightBottomCols);
539 ct.setYLine(currentYPosition);
540 ct.setAlignment(Element.ALIGN_JUSTIFIED);
543 currentYPosition=toYPosition;
545 catch(DocumentException de) {
546 logger.error(de.getMessage());
552 //add an image on the left with a big caption to the right
553 currentYPosition = currentYPosition - 10;
554 float templateMinimumHeight = img_height;
555 float templateWidth = img_width;
556 float templateHeight = templateMinimumHeight+contentLineHeight-(templateMinimumHeight % contentLineHeight);
557 PdfTemplate template = cb.createTemplate(templateWidth,templateHeight);
558 if (! enoughY((new Float(templateHeight)).intValue())){
561 float toYPosition=currentYPosition - templateHeight;
563 Image theImage = Image.getInstance(localImageDir+img_path);
564 theImage.setAbsolutePosition(0,13);
565 theImage.scaleAbsolute(img_width,img_height);
566 template.addImage(theImage);
568 catch(BadElementException de) {
569 logger.error(de.getMessage());
571 catch(DocumentException de) {
572 logger.error(de.getMessage());
574 catch(MalformedURLException de) {
575 logger.error(de.getMessage());
577 catch(IOException de) {
578 logger.error(de.getMessage());
581 cb.addTemplate(template,leftEdge,toYPosition);
584 ColumnText cct = new ColumnText(cb);
585 float[] leftCaptionCols = {leftEdge+templateWidth+5,currentYPosition-5,leftEdge+templateWidth+5,toYPosition};
586 float[] rightCaptionCols = {rightEdge,currentYPosition-5,rightEdge,toYPosition};
588 Paragraph captionP=new Paragraph(img_title,new Font(bigImageCaptionFontFamily,bigImageCaptionFontSize,Font.BOLD));
589 cct.addText(captionP);
590 cct.setColumns(leftCaptionCols,rightCaptionCols);
591 cct.setYLine(currentYPosition-5);
592 cct.setAlignment(Element.ALIGN_LEFT);
595 currentYPosition=toYPosition;
597 catch(DocumentException de) {
598 logger.error(de.getMessage());
603 //add the rest of the text which might be left
605 while ((status & ColumnText.NO_MORE_TEXT) == 0 && brake > 0){
606 status=addTextLine(ct,contentLineHeight,Element.ALIGN_JUSTIFIED,leftEdge,rightEdge);
610 logger.error("runaway content....try decreasing font size or increasing line height");
613 private void addArticleSource(ColumnText ct,String theSource){
614 Paragraph sourceP = new Paragraph(theSource,new Font(sourceFontFamily,sourceFontSize,Font.BOLD));
616 addTextLine(ct,sourceLineHeight,Element.ALIGN_RIGHT,leftEdge,rightEdge);
620 private boolean enoughY(int heightOfBlockToAdd){
621 if ((currentYPosition - heightOfBlockToAdd - footerHeight) < bottomEdge )
628 public void add(EntityContent entityContent){
629 logger.error("adding a content Entity");
639 * --image without text
643 EntityList images=DatabaseContentToMedia.getInstance().getImages(entityContent);
644 String isHTML = entityContent.getValue("is_html");
645 String theTitle = entityContent.getValue("title");
646 String theCreator = entityContent.getValue("creator");
647 String theDate = DateTimeFunctions.advancedDateFormat(
648 configuration.getString("RDF.Meta.DateFormat"),
649 StringUtil.convertMirInternalDateToDate(entityContent.getValue("webdb_create")),
650 configuration.getString("Mir.DefaultTimezone"));
653 String theDescriptionRaw = entityContent.getValue("description");
654 String theContentRaw = entityContent.getValue("content_data");
655 String theSource = configuration.getString("Producer.ProductionHost") + "/" + configuration.getString("StandardLanguage") + entityContent.getValue("publish_path") + entityContent.getValue("id") + ".shtml";
659 String theContent = "";
660 String theDescription = "";
662 if (isHTML.equals("1")){
667 RE nobackslashr = new RE("\r");
668 theContent= nobackslashr.substituteAll(theContentRaw,"");
670 RE HxTag = new RE("</?h[1-6][^>]*>",RE.REG_ICASE);
671 theContent = HxTag.substituteAll(theContent,"\n\n");
673 RE ListItemTag = new RE("<li[^>]*>",RE.REG_ICASE);
674 theContent = ListItemTag.substituteAll(theContent,"\n * ");
676 RE ListTag = new RE("<(u|o)l[^>]*>",RE.REG_ICASE);
677 theContent = ListTag.substituteAll(theContent,"\n");
679 RE DivTag = new RE("</?div[^>]*>",RE.REG_ICASE);
680 theContent= DivTag.substituteAll(theContent,"\n");
682 RE PTag = new RE("<(p|P)([:space:]+[^>]*)?>");
683 theContent= PTag.substituteAll(theContent,"\n ");
685 RE PTagClose = new RE("</(p|P)([:space:]+[^>]*)?>");
686 theContent= PTagClose.substituteAll(theContent,"\n");
688 RE BRTag = new RE("<(br|BR)([:space:]+[^>]*)?>");
689 theContent= BRTag.substituteAll(theContent,"\n");
691 RE ATagAll = new RE("<a[^>]*href=(?:\"|\')([^#\"\'][^\'\"]+)(?:\"|\')[^>]*>(.*?)</a>",RE.REG_ICASE);
692 REMatchEnumeration atags= ATagAll.getMatchEnumeration(theContent);
693 String theContentCopy=theContent;
694 while (atags.hasMoreMatches()){
695 REMatch atag = atags.nextMatch();
696 String atagString=atag.toString();
697 String atagStringHref=atag.toString(1);
698 String atagStringText=atag.toString(2);
699 int begin=theContentCopy.indexOf(atagString);
700 theContentCopy=theContentCopy.substring(0,begin) + atagStringText + " ["+ atagStringHref + "] " + theContentCopy.substring(begin+atagString.length());
702 theContent=theContentCopy;
704 RE noTags = new RE("<[^>]*>");
705 theContent= noTags.substituteAll(theContent," ");
707 theContent=mir.util.Translate.decode(theContent);
709 RE re1 = new RE("\r?\n\r?\n");
710 String theDescription1 = re1.substituteAll(theDescriptionRaw,"BREAKHERE");
712 RE re2 = new RE("\r?\n");
713 String theDescription2 = re2.substituteAll(theDescription1," ");
715 RE re3 = new RE("BREAKHERE");
716 theDescription = re3.substituteAll(theDescription2,"\n ");
720 catch(REException ree){
721 logger.error(ree.getMessage());
726 RE re1 = new RE("\r?\n\r?\n");
727 String theContent1 = re1.substituteAll(theContentRaw,"BREAKHERE");
728 String theDescription1 = re1.substituteAll(theDescriptionRaw,"BREAKHERE");
730 RE re2 = new RE("\r?\n");
731 String theContent2 = re2.substituteAll(theContent1," ");
732 String theDescription2 = re2.substituteAll(theDescription1," ");
734 RE re3 = new RE("BREAKHERE");
735 theContent = " " + re3.substituteAll(theContent2,"\n ");
736 theDescription = re3.substituteAll(theDescription2,"\n ");
739 catch(REException ree){
740 logger.error(ree.getMessage());
744 addArticleSeparator();
746 ColumnText ct = new ColumnText(cb);
748 addArticleMetaInfo(ct,theTitle,theCreator,theDate);
749 addArticleDescription(ct,theDescription);
750 addArticleContent(ct,theContent,images);
751 addArticleSource(ct,theSource);
755 public int getFontByName(String fontName) {
757 if (fontName.equalsIgnoreCase("helvetica")){
758 theFont = Font.HELVETICA;
761 if (fontName.equalsIgnoreCase("courier")) {
762 theFont = Font.COURIER;
765 if (fontName.equalsIgnoreCase("times")) {
766 theFont = Font.TIMES_ROMAN;
769 logger.error("using helvetica because I can't get font for name: "+fontName);
770 theFont = Font.HELVETICA;