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