1a158685dda58e0a4f2ca584dcdc5549a6482ea9
[mir.git] / source / mircoders / pdf / PDFGenerator.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
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.
10  *
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.
15  *
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
19  *
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.
29  */
30 package mircoders.pdf;
31
32 import gnu.regexp.RE;
33 import gnu.regexp.REException;
34 import gnu.regexp.REMatch;
35 import gnu.regexp.REMatchEnumeration;
36
37 import java.io.ByteArrayOutputStream;
38 import java.io.IOException;
39 import java.net.MalformedURLException;
40 import java.util.ArrayList;
41 import java.util.Iterator;
42 import java.util.List;
43
44 import mir.config.MirPropertiesConfiguration;
45 import mir.entity.EntityBrowser;
46 import mir.log.LoggerWrapper;
47 import mir.misc.StringUtil;
48 import mir.util.DateTimeRoutines;
49 import mir.util.HTMLRoutines;
50 import mircoders.entity.EntityContent;
51 import mircoders.entity.EntityImages;
52 import mircoders.storage.DatabaseImages;
53
54 import com.lowagie.text.BadElementException;
55 import com.lowagie.text.Document;
56 import com.lowagie.text.DocumentException;
57 import com.lowagie.text.Element;
58 import com.lowagie.text.Font;
59 import com.lowagie.text.Image;
60 import com.lowagie.text.PageSize;
61 import com.lowagie.text.Paragraph;
62 import com.lowagie.text.Phrase;
63 import com.lowagie.text.pdf.BaseFont;
64 import com.lowagie.text.pdf.ColumnText;
65 import com.lowagie.text.pdf.PdfContentByte;
66 import com.lowagie.text.pdf.PdfTemplate;
67 import com.lowagie.text.pdf.PdfWriter;
68 import multex.Failure;
69
70 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;
81   public float topEdge;
82   public float bottomEdge;
83   public float rightEdge;
84   public float leftEdge;
85
86   public int maxImageHeight;
87   public int maxImageWidth;
88   protected LoggerWrapper logger;
89
90   public int indexFontSize;
91   public int indexLineHeight;
92   public int indexFontFamily;
93
94   public float footerHeight;
95   public String footerText;
96   public int footerFontSize;
97   public int footerFontFamily;
98
99   public int metaHeight;
100   public int metaFontSize;
101   public int metaFontFamily;
102
103   public int descriptionLineHeight;
104   public int descriptionFontSize;
105   public int descriptionFontFamily;
106
107   public int contentLineHeight;
108   public int contentFontSize;
109   public int contentFontFamily;
110
111   public int sourceLineHeight;
112   public int sourceFontSize;
113   public int sourceFontFamily;
114
115   public int bigImageCaptionFontSize;
116   public int bigImageCaptionFontFamily;
117
118   protected MirPropertiesConfiguration configuration;
119
120
121   public PDFGenerator(ByteArrayOutputStream out) {
122     logger = new LoggerWrapper("PDFGenerator");
123     configuration = MirPropertiesConfiguration.instance();
124     localImageDir = configuration.getString("Producer.Image.Path");
125
126     try {
127       indexFontSize = Integer.parseInt(configuration.getString("PDF.Index.FontSize"));
128       indexLineHeight = Integer.parseInt(configuration.getString("PDF.Index.LineHeight"));
129       indexFontFamily = getFontByName(configuration.getString("PDF.Index.FontFamily"));
130
131       footerText = configuration.getString("PDF.Footer.String");
132       footerFontSize = Integer.parseInt(configuration.getString("PDF.Footer.FontSize"));
133       footerFontFamily = getFontByName(configuration.getString("PDF.Footer.FontFamily"));
134       footerHeight = Integer.parseInt(configuration.getString("PDF.Footer.Height"));
135
136       metaFontSize = Integer.parseInt(configuration.getString("PDF.Meta.FontSize"));
137       metaFontFamily = getFontByName(configuration.getString("PDF.Meta.FontFamily"));
138       metaHeight = Integer.parseInt(configuration.getString("PDF.Meta.Height"));
139
140       descriptionFontSize = Integer.parseInt(configuration.getString("PDF.Description.FontSize"));
141       descriptionLineHeight = Integer.parseInt(configuration.getString("PDF.Description.LineHeight"));
142       descriptionFontFamily = getFontByName(configuration.getString("PDF.Description.FontFamily"));
143
144       contentFontSize = Integer.parseInt(configuration.getString("PDF.Content.FontSize"));
145       contentLineHeight = Integer.parseInt(configuration.getString("PDF.Content.LineHeight"));
146       contentFontFamily = getFontByName(configuration.getString("PDF.Content.FontFamily"));
147
148       sourceFontSize = Integer.parseInt(configuration.getString("PDF.Source.FontSize"));
149       sourceLineHeight = Integer.parseInt(configuration.getString("PDF.Source.LineHeight"));
150       sourceFontFamily = getFontByName(configuration.getString("PDF.Source.FontFamily"));
151
152       bigImageCaptionFontSize = Integer.parseInt(configuration.getString("PDF.BigImageCaption.FontSize"));
153       bigImageCaptionFontFamily = getFontByName(configuration.getString("PDF.BigImageCaption.FontFamily"));
154
155     }
156     catch (NumberFormatException e) {
157       throw new Failure(e.getMessage(), e);
158     }
159
160     // step 1: make a document
161
162     String pageSize = configuration.getString("PDF.Pagesize");
163
164     if (pageSize.equals("LETTER")) {
165       document = new Document(PageSize.LETTER);
166       pageWidth = 612;
167       pageHeight = 792;
168     } else {
169       document = new Document(PageSize.A4);
170       pageWidth = 595;
171       pageHeight = 842;
172     }
173
174     maxImageHeight = 250;
175     maxImageWidth = 250;
176
177
178     verticalMargin = 20;
179     horizontalMargin = 20;
180
181
182     topEdge = pageHeight - verticalMargin;
183     bottomEdge = verticalMargin;
184     rightEdge = pageWidth - horizontalMargin;
185     leftEdge = horizontalMargin;
186
187     currentYPosition = topEdge;
188     currentPage = 1;
189
190     String headerText = configuration.getString("PDF.Title.String");
191
192     try {
193       writer = PdfWriter.getInstance(document, out);
194       cb = writer.getDirectContent();
195
196       document.open();
197       addHeader(headerText);
198     }
199     catch (DocumentException de) {
200       logger.error(de.getMessage());
201     }
202   }
203
204   public void stop() {
205     addFooter();
206     document.close();
207   }
208
209   public void addHeader(String headerText) {
210     int titleFontSize = Integer.parseInt(configuration.getString("PDF.Title.FontSize"));
211     int titleLineHeight = Integer.parseInt(configuration.getString("PDF.Title.LineHeight"));
212     String titleFontFamily = configuration.getString("PDF.Title.FontFamily");
213     String headerImage = configuration.getString("PDF.Header.Image");
214     int headerImageHeight = Integer.parseInt(configuration.getString("PDF.Header.ImageHeight"));
215
216     try {
217       if ((! headerImage.equals("")) && headerImageHeight != 0) {
218         PdfTemplate template = cb.createTemplate(rightEdge - horizontalMargin, headerImageHeight);
219
220         float toYPosition = currentYPosition - headerImageHeight;
221         Image theImage = Image.getInstance(headerImage);
222         theImage.setAbsolutePosition(0, 0);
223         //      theImage.scaleAbsolute(img_width,img_height);
224         template.addImage(theImage);
225
226
227         cb.addTemplate(template, leftEdge, toYPosition);
228         currentYPosition = toYPosition;
229       }
230       if (! headerText.equals("")) {
231         ColumnText ct = new ColumnText(cb);
232         //add a basic header
233         ct.addText(new Phrase(headerText, new Font(getFontByName(titleFontFamily), titleFontSize, Font.BOLD)));
234         float[] rightCol = {rightEdge, currentYPosition, rightEdge, currentYPosition - titleLineHeight};
235         float[] leftCol = {leftEdge, currentYPosition, leftEdge, currentYPosition - titleLineHeight};
236         ct.setColumns(leftCol, rightCol);
237         ct.setYLine(currentYPosition);
238         ct.setAlignment(Element.ALIGN_CENTER);
239         ct.go();
240
241         currentYPosition = currentYPosition - titleLineHeight;
242       }
243     }
244     catch (DocumentException de) {
245       logger.error(de.getMessage());
246     }
247     catch (MalformedURLException de) {
248       logger.error(de.getMessage());
249     }
250     catch (IOException de) {
251       logger.error(de.getMessage());
252     }
253   }
254
255   public void addIndexItem(EntityContent entityContent) {
256     try {
257
258       ColumnText ict = new ColumnText(cb);
259       String theTitle = entityContent.getFieldValue("title");
260       String theCreator = entityContent.getFieldValue("creator");
261       Phrase titleP = new Phrase(" - " + theTitle, new Font(indexFontFamily, indexFontSize, Font.BOLD));
262       Phrase creatorP = new Phrase(" :: " + theCreator, new Font(indexFontFamily, indexFontSize));
263       float toYPosition = currentYPosition - indexLineHeight;
264       float[] leftIndexCols = {leftEdge, currentYPosition, leftEdge, toYPosition};
265       float[] rightIndexCols = {rightEdge, currentYPosition, rightEdge, toYPosition};
266       ict.addText(titleP);
267       ict.addText(creatorP);
268       ict.setColumns(leftIndexCols, rightIndexCols);
269       ict.setYLine(currentYPosition);
270       ict.setAlignment(Element.ALIGN_LEFT);
271       ict.go();
272       currentYPosition = toYPosition;
273     }
274     catch (DocumentException de) {
275       logger.error(de.getMessage());
276     }
277
278
279   }
280
281   private int addTextLine(ColumnText ct, int lineHeight, int alignment, float left, float right) {
282     logger.debug("adding a line of text");
283     if (! enoughY(lineHeight)) {
284       newPage();
285     }
286     float toYPosition = currentYPosition - lineHeight;
287     float[] leftContentCols = {left, currentYPosition, left, toYPosition};
288     float[] rightContentCols = {right, currentYPosition, right, toYPosition};
289     ct.setColumns(leftContentCols, rightContentCols);
290     ct.setYLine(currentYPosition);
291     ct.setAlignment(alignment);
292     try {
293       int status = ct.go();
294       currentYPosition = toYPosition;
295       return status;
296     }
297     catch (DocumentException de) {
298       logger.error(de.getMessage());
299     }
300     return 0;
301   }
302
303   public void addLine() {
304     cb.setLineWidth(1f);
305     cb.moveTo(rightEdge, currentYPosition - 5);
306     cb.lineTo(leftEdge, currentYPosition - 5);
307     cb.stroke();
308     currentYPosition = currentYPosition - 10;
309
310   }
311
312   public void addFooter() {
313     try {
314       ColumnText fct = new ColumnText(cb);
315       cb.setLineWidth(1f);
316       cb.moveTo(rightEdge, bottomEdge + footerHeight - 5);
317       cb.lineTo(leftEdge, bottomEdge + footerHeight - 5);
318       cb.stroke();
319       float[] leftFooterCols = {leftEdge, bottomEdge + footerHeight - 1, leftEdge, bottomEdge};
320       float[] rightFooterCols = {rightEdge, bottomEdge + footerHeight - 1, rightEdge, bottomEdge};
321
322       Paragraph footerP = new Paragraph(footerText, new Font(footerFontFamily, footerFontSize));
323       fct.addText(footerP);
324
325       fct.setColumns(leftFooterCols, rightFooterCols);
326       fct.setYLine(bottomEdge + footerHeight - 1);
327       fct.setAlignment(Element.ALIGN_JUSTIFIED);
328       fct.go();
329
330       Paragraph numberP = new Paragraph((new Integer(currentPage)).toString(), new Font(footerFontFamily, footerFontSize, Font.BOLD));
331       fct.addText(numberP);
332       fct.setAlignment(Element.ALIGN_RIGHT);
333       fct.go();
334
335     }
336     catch (DocumentException de) {
337       logger.error(de.getMessage());
338     }
339
340
341   }
342
343   public void newPage() {
344     try {
345       //add a footer
346       addFooter();
347       document.newPage();
348       currentPage++;
349       currentYPosition = topEdge;
350     }
351     catch (DocumentException de) {
352       logger.error(de.getMessage());
353     }
354   }
355
356   public void addArticleSeparator() {
357     // make a line
358     if (! enoughY(10)) {
359       newPage();
360     }
361     cb.setLineWidth(1f);
362     cb.moveTo(rightEdge, currentYPosition - 5);
363     cb.lineTo(leftEdge, currentYPosition - 5);
364     cb.stroke();
365     currentYPosition = currentYPosition - 10;
366   }
367
368   public void addArticleMetaInfo(ColumnText ct, String theTitle, String theCreator, String theDate) {
369     //see if we have room for the author and title
370
371     if (! enoughY(metaHeight)) {
372       newPage();
373     }
374
375     Paragraph titleP = new Paragraph(theTitle + "\n", new Font(metaFontFamily, metaFontSize, Font.BOLD));
376     Paragraph whowhenP = new Paragraph(theCreator + "  " + theDate, new Font(metaFontFamily, metaFontSize));
377     ct.addText(titleP);
378     ct.addText(whowhenP);
379
380     ct.setYLine(currentYPosition);
381     ct.setAlignment(Element.ALIGN_LEFT);
382
383     float toYPosition = currentYPosition - metaHeight;
384     float[] leftHeadCols = {leftEdge, currentYPosition, leftEdge, toYPosition};
385     float[] rightHeadCols = {rightEdge, currentYPosition, rightEdge, toYPosition};
386
387     ct.setColumns(leftHeadCols, rightHeadCols);
388     try {
389       ct.go();
390       currentYPosition = toYPosition;
391     }
392     catch (DocumentException de) {
393       logger.error(de.getMessage());
394     }
395
396   }
397
398   public void addArticleDescription(ColumnText ct, String theDescription) {
399     // Now we add the description, one line at a time, the ct should be empty at this point
400
401
402     Paragraph descP = new Paragraph(theDescription, new Font(descriptionFontFamily, descriptionFontSize, Font.BOLD));
403     ct.addText(descP);
404
405     // every article has a description, so we can assume that:
406     int status = ColumnText.NO_MORE_COLUMN;
407
408     int brake = 1000;
409     while ((status & ColumnText.NO_MORE_TEXT) == 0 && brake > 0) {
410       //there is still text left in the description.
411       status = addTextLine(ct, descriptionLineHeight, Element.ALIGN_JUSTIFIED, leftEdge, rightEdge);
412       brake--;
413     }
414     if (brake == 0)
415       logger.error("runaway description...try increasing the line height or decreasing the font size");
416   }
417
418   public void addArticleContent(ColumnText ct, String theContent, Iterator images) {
419     //let's go ahead and add in all the body text
420     Paragraph contentP = new Paragraph(theContent, new Font(contentFontFamily, contentFontSize));
421     ct.addText(contentP);
422
423     int contentLinesBeforeImages = 3;
424     //and assume we have at least one line of text in the content
425     int status = ColumnText.NO_MORE_COLUMN;
426
427     // let's add a little bit of text, like a couple of lines
428     int x = 0;
429     while (((status & ColumnText.NO_MORE_TEXT) == 0) && x < contentLinesBeforeImages) {
430       status = addTextLine(ct, contentLineHeight, Element.ALIGN_JUSTIFIED, leftEdge, rightEdge);
431       x++;
432     }
433
434     boolean addImageOnLeft = true; //we will alternate within articles
435     while (images.hasNext()) {
436
437       EntityImages currentImage = (EntityImages) images.next();
438       float img_width = (new Float(currentImage.getFieldValue("img_width"))).floatValue();
439       float img_height = (new Float(currentImage.getFieldValue("img_height"))).floatValue();
440       if (img_height > maxImageHeight) {
441         img_width = (new Float((new Float(img_width * (maxImageHeight / img_height))).intValue())).floatValue();
442         img_height = maxImageHeight;
443       }
444       if (img_width > maxImageWidth) {
445         img_height = (new Float((new Float(img_height * (maxImageWidth / img_width))).intValue())).floatValue();
446         img_width = maxImageWidth;
447       }
448
449       String img_title = currentImage.getFieldValue("title");
450       String img_path = currentImage.getFieldValue("publish_path");
451
452       if ((status & ColumnText.NO_MORE_TEXT) == 0) {
453         // there is still text, so add an image which will have text wrapped around it, then add the text which
454         // will be on the left or the right of the image
455
456         float templateMinimumHeight = img_height + 20;
457         float templateWidth = img_width + 10;
458         float templateHeight = templateMinimumHeight + contentLineHeight - (templateMinimumHeight % contentLineHeight);
459
460         PdfTemplate template = cb.createTemplate(templateWidth, templateHeight);
461
462         //here we need a page check
463         if (! enoughY((new Float(templateHeight)).intValue())) {
464           //ok, well just fill text to the bottom then
465           float toYPosition = bottomEdge + footerHeight;
466           float[] leftBottomCols = {leftEdge, currentYPosition, leftEdge, toYPosition};
467           float[] rightBottomCols = {rightEdge, currentYPosition, rightEdge, toYPosition};
468           ct.setColumns(leftBottomCols, rightBottomCols);
469           ct.setYLine(currentYPosition);
470           ct.setAlignment(Element.ALIGN_JUSTIFIED);
471           try {
472             status = ct.go();
473           }
474           catch (DocumentException de) {
475             logger.error(de.getMessage());
476           }
477           newPage();
478         }
479
480         float toYPosition = currentYPosition - templateHeight;
481
482         try {
483           Image theImage = Image.getInstance(localImageDir + img_path);
484           theImage.scaleAbsolute(img_width, img_height);
485           theImage.setAbsolutePosition(5, 13);
486
487           template.addImage(theImage);
488           template.beginText();
489           BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
490           template.setFontAndSize(bf, 8);
491           template.setTextMatrix(5, 3);
492           template.showText(img_title);
493           template.endText();
494         }
495         catch (BadElementException de) {
496           logger.error(de.getMessage());
497         }
498         catch (DocumentException de) {
499           logger.error(de.getMessage());
500         }
501         catch (MalformedURLException de) {
502           logger.error(de.getMessage());
503         }
504         catch (IOException de) {
505           logger.error(de.getMessage());
506         }
507
508
509         float leftImageTextEdge = leftEdge;
510         float rightImageTextEdge = rightEdge;
511
512
513         if (addImageOnLeft) {
514           cb.addTemplate(template, leftEdge, toYPosition);
515           leftImageTextEdge = leftEdge + templateWidth + 5;
516           addImageOnLeft = false;
517         } else {
518           cb.addTemplate(template, rightEdge - templateWidth, toYPosition);
519           rightImageTextEdge = rightEdge - templateWidth - 5;
520           addImageOnLeft = true;
521         }
522
523         logger.debug("adding template at " + leftEdge + "," + toYPosition);
524
525         //and fill some text while we are at it
526
527         float[] leftBottomCols = {leftImageTextEdge, currentYPosition, leftImageTextEdge, toYPosition};
528         float[] rightBottomCols = {rightImageTextEdge, currentYPosition, rightImageTextEdge, toYPosition};
529         ct.setColumns(leftBottomCols, rightBottomCols);
530         ct.setYLine(currentYPosition);
531         ct.setAlignment(Element.ALIGN_JUSTIFIED);
532         try {
533           status = ct.go();
534           currentYPosition = toYPosition;
535         }
536         catch (DocumentException de) {
537           logger.error(de.getMessage());
538         }
539
540
541       } else {
542         //add an image on the left with a big caption to the right
543         currentYPosition = currentYPosition - 10;
544         float templateMinimumHeight = img_height;
545         float templateWidth = img_width;
546         float templateHeight = templateMinimumHeight + contentLineHeight - (templateMinimumHeight % contentLineHeight);
547         PdfTemplate template = cb.createTemplate(templateWidth, templateHeight);
548         if (! enoughY((new Float(templateHeight)).intValue())) {
549           newPage();
550         }
551         float toYPosition = currentYPosition - templateHeight;
552         try {
553           Image theImage = Image.getInstance(localImageDir + img_path);
554           theImage.setAbsolutePosition(0, 13);
555           theImage.scaleAbsolute(img_width, img_height);
556           template.addImage(theImage);
557         }
558         catch (BadElementException de) {
559           logger.error(de.getMessage());
560         }
561         catch (DocumentException de) {
562           logger.error(de.getMessage());
563         }
564         catch (MalformedURLException de) {
565           logger.error(de.getMessage());
566         }
567         catch (IOException de) {
568           logger.error(de.getMessage());
569         }
570
571         cb.addTemplate(template, leftEdge, toYPosition);
572
573         // add a big caption
574         ColumnText cct = new ColumnText(cb);
575         float[] leftCaptionCols = {leftEdge + templateWidth + 5, currentYPosition - 5, leftEdge + templateWidth + 5, toYPosition};
576         float[] rightCaptionCols = {rightEdge, currentYPosition - 5, rightEdge, toYPosition};
577
578         Paragraph captionP = new Paragraph(img_title, new Font(bigImageCaptionFontFamily, bigImageCaptionFontSize, Font.BOLD));
579         cct.addText(captionP);
580         cct.setColumns(leftCaptionCols, rightCaptionCols);
581         cct.setYLine(currentYPosition - 5);
582         cct.setAlignment(Element.ALIGN_LEFT);
583         try {
584           cct.go();
585           currentYPosition = toYPosition;
586         }
587         catch (DocumentException de) {
588           logger.error(de.getMessage());
589         }
590       }
591     }
592
593     //add the rest of the text which might be left
594     int brake = 10000;
595     while ((status & ColumnText.NO_MORE_TEXT) == 0 && brake > 0) {
596       status = addTextLine(ct, contentLineHeight, Element.ALIGN_JUSTIFIED, leftEdge, rightEdge);
597       brake --;
598     }
599     if (brake == 0)
600       logger.error("runaway content....try decreasing font size or increasing line height");
601   }
602
603   private void addArticleSource(ColumnText ct, String theSource) {
604     Paragraph sourceP = new Paragraph(theSource, new Font(sourceFontFamily, sourceFontSize, Font.BOLD));
605     ct.addText(sourceP);
606     addTextLine(ct, sourceLineHeight, Element.ALIGN_RIGHT, leftEdge, rightEdge);
607   }
608
609
610   private boolean enoughY(int heightOfBlockToAdd) {
611     if ((currentYPosition - heightOfBlockToAdd - footerHeight) < bottomEdge)
612       return false;
613     return true;
614   }
615
616
617   public void add(EntityContent entityContent) {
618     logger.error("adding a content Entity");
619
620     /*
621      * initialize
622      * separate
623      * meta info
624      * description
625      * content
626      * --image with text
627      * --normal text
628      * --image without text
629      * source
630     */
631
632     List extraTables = new ArrayList();
633     extraTables.add("content_x_media cxm");
634     Iterator images = new EntityBrowser(
635         DatabaseImages.getInstance(), "i", extraTables,
636         "cxm.content_id=" + entityContent.getId() + "and cxm.media_id=i.id",
637         "i.id desc", 30, -1, 0);
638
639     String isHTML = entityContent.getFieldValue("is_html");
640     String theTitle = entityContent.getFieldValue("title");
641     String theCreator = entityContent.getFieldValue("creator");
642     String theDate = DateTimeRoutines.advancedDateFormat(
643         configuration.getString("RDF.Meta.DateFormat"),
644         StringUtil.convertMirInternalDateToDate(entityContent.getFieldValue("webdb_create")),
645         configuration.getString("Mir.DefaultTimezone"));
646
647
648     String theDescriptionRaw = entityContent.getFieldValue("description");
649     String theContentRaw = entityContent.getFieldValue("content_data");
650     String theSource = configuration.getString("Producer.PublicationHost") + "/" + configuration.getString("StandardLanguage") + entityContent.getFieldValue("publish_path") + entityContent.getFieldValue("id") + ".shtml";
651
652
653     String theContent = "";
654     String theDescription = "";
655
656     if (isHTML.equals("1")) {
657
658
659       try {
660         RE nobackslashr = new RE("\r");
661         theContent = nobackslashr.substituteAll(theContentRaw, "");
662         theDescription = nobackslashr.substituteAll(theDescriptionRaw, "");
663
664         RE HxTag = new RE("</?h[1-6][^>]*>", RE.REG_ICASE);
665         theContent = HxTag.substituteAll(theContent, "\n\n");
666         theDescription = HxTag.substituteAll(theDescription, "\n\n");
667
668         RE ListItemTag = new RE("<li[^>]*>", RE.REG_ICASE);
669         theContent = ListItemTag.substituteAll(theContent, "\n * ");
670         theDescription = ListItemTag.substituteAll(theDescription, "\n * ");
671
672         RE ListTag = new RE("<(u|o)l[^>]*>", RE.REG_ICASE);
673         theContent = ListTag.substituteAll(theContent, "\n");
674         theDescription = ListTag.substituteAll(theDescription, "\n");
675
676         RE DivTag = new RE("</?div[^>]*>", RE.REG_ICASE);
677         theContent = DivTag.substituteAll(theContent, "\n");
678         theDescription = DivTag.substituteAll(theDescription, "\n");
679
680         RE PTag = new RE("<(p|P)([:space:]+[^>]*)?>");
681         theContent = PTag.substituteAll(theContent, "\n    ");
682         theDescription = PTag.substituteAll(theDescription, "\n    ");
683
684         RE PTagClose = new RE("</(p|P)([:space:]+[^>]*)?>");
685         theContent = PTagClose.substituteAll(theContent, "\n");
686         theDescription = PTagClose.substituteAll(theDescription, "\n");
687
688         RE BRTag = new RE("<(br|BR)([:space:]+[^>]*)?>");
689         theContent = BRTag.substituteAll(theContent, "\n");
690         theDescription = BRTag.substituteAll(theDescription, "\n");
691
692         RE ATagAll = new RE("<a[^>]*href=(?:\"|\')([^#\"\'][^\'\"]+)(?:\"|\')[^>]*>(.*?)</a>", RE.REG_ICASE);
693         REMatchEnumeration atags = ATagAll.getMatchEnumeration(theContent);
694         String theContentCopy = theContent;
695         while (atags.hasMoreMatches()) {
696           REMatch atag = atags.nextMatch();
697           String atagString = atag.toString();
698           String atagStringHref = atag.toString(1);
699           String atagStringText = atag.toString(2);
700           int begin = theContentCopy.indexOf(atagString);
701           theContentCopy = theContentCopy.substring(0, begin) + atagStringText + " [" + atagStringHref + "] " + theContentCopy.substring(begin + atagString.length());
702         }
703         theContent = theContentCopy;
704
705         REMatchEnumeration atags2 = ATagAll.getMatchEnumeration(theDescription);
706         String theDescriptionCopy = theDescription;
707         while (atags2.hasMoreMatches()) {
708           REMatch atag = atags2.nextMatch();
709           String atagString = atag.toString();
710           String atagStringHref = atag.toString(1);
711           String atagStringText = atag.toString(2);
712           int begin = theDescriptionCopy.indexOf(atagString);
713           theDescriptionCopy = theDescriptionCopy.substring(0, begin) + atagStringText + " [" + atagStringHref + "] " + theDescriptionCopy.substring(begin + atagString.length());
714         }
715         theDescription = theDescriptionCopy;
716
717
718         RE noTags = new RE("<[^>]*>");
719         theContent = noTags.substituteAll(theContent, " ");
720         theDescription = noTags.substituteAll(theDescription, " ");
721
722         theContent = HTMLRoutines.resolveHTMLEntites(theContent);
723         theDescription = HTMLRoutines.resolveHTMLEntites(theDescription);
724
725         RE re1 = new RE("\r?\n\r?\n");
726         String theDescription1 = re1.substituteAll(theDescription, "BREAKHERE");
727
728         RE re2 = new RE("\r?\n");
729         String theDescription2 = re2.substituteAll(theDescription1, " ");
730
731         RE re3 = new RE("BREAKHERE");
732         theDescription = re3.substituteAll(theDescription2, "\n    ");
733
734
735       }
736       catch (REException ree) {
737         logger.error(ree.getMessage());
738       }
739     } else {
740       try {
741         RE re1 = new RE("\r?\n\r?\n");
742         String theContent1 = re1.substituteAll(theContentRaw, "BREAKHERE");
743         String theDescription1 = re1.substituteAll(theDescriptionRaw, "BREAKHERE");
744
745         RE re2 = new RE("\r?\n");
746         String theContent2 = re2.substituteAll(theContent1, " ");
747         String theDescription2 = re2.substituteAll(theDescription1, " ");
748
749         RE re3 = new RE("BREAKHERE");
750         theContent = "    " + re3.substituteAll(theContent2, "\n    ");
751         theDescription = re3.substituteAll(theDescription2, "\n    ");
752
753       }
754       catch (REException ree) {
755         logger.error(ree.getMessage());
756       }
757     }
758
759     addArticleSeparator();
760
761     ColumnText ct = new ColumnText(cb);
762
763     addArticleMetaInfo(ct, theTitle, theCreator, theDate);
764     addArticleDescription(ct, theDescription);
765     addArticleContent(ct, theContent, images);
766     addArticleSource(ct, theSource);
767   }
768
769   public int getFontByName(String fontName) {
770     int theFont = 0;
771     if ("helvetica".equalsIgnoreCase(fontName)) {
772       theFont = Font.HELVETICA;
773     }
774     else if ("courier".equalsIgnoreCase(fontName)) {
775       theFont = Font.COURIER;
776     }
777     else if ("times".equalsIgnoreCase(fontName)) {
778       theFont = Font.TIMES_ROMAN;
779     }
780     else {
781       logger.error("using helvetica because I can't get font for name: " + fontName);
782       theFont = Font.HELVETICA;
783     }
784
785     return theFont;
786   }
787 }