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.REException;
34 import gnu.regexp.REMatch;
35 import gnu.regexp.REMatchEnumeration;
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;
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;
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;
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;
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");
123 configuration = MirPropertiesConfiguration.instance();
124 localImageDir = configuration.getString("Producer.Image.Path");
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"));
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"));
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"));
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"));
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"));
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"));
152 bigImageCaptionFontSize = Integer.parseInt(configuration.getString("PDF.BigImageCaption.FontSize"));
153 bigImageCaptionFontFamily = getFontByName(configuration.getString("PDF.BigImageCaption.FontFamily"));
156 catch (NumberFormatException e) {
157 throw new Failure(e.getMessage(), e);
160 // step 1: make a document
162 String pageSize = configuration.getString("PDF.Pagesize");
164 if (pageSize.equals("LETTER")) {
165 document = new Document(PageSize.LETTER);
169 document = new Document(PageSize.A4);
174 maxImageHeight = 250;
179 horizontalMargin = 20;
182 topEdge = pageHeight - verticalMargin;
183 bottomEdge = verticalMargin;
184 rightEdge = pageWidth - horizontalMargin;
185 leftEdge = horizontalMargin;
187 currentYPosition = topEdge;
190 String headerText = configuration.getString("PDF.Title.String");
193 writer = PdfWriter.getInstance(document, out);
194 cb = writer.getDirectContent();
197 addHeader(headerText);
199 catch (DocumentException de) {
200 logger.error(de.getMessage());
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"));
217 if ((! headerImage.equals("")) && headerImageHeight != 0) {
218 PdfTemplate template = cb.createTemplate(rightEdge - horizontalMargin, headerImageHeight);
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);
227 cb.addTemplate(template, leftEdge, toYPosition);
228 currentYPosition = toYPosition;
230 if (! headerText.equals("")) {
231 ColumnText ct = new ColumnText(cb);
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);
241 currentYPosition = currentYPosition - titleLineHeight;
244 catch (DocumentException de) {
245 logger.error(de.getMessage());
247 catch (MalformedURLException de) {
248 logger.error(de.getMessage());
250 catch (IOException de) {
251 logger.error(de.getMessage());
255 public void addIndexItem(EntityContent entityContent) {
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};
267 ict.addText(creatorP);
268 ict.setColumns(leftIndexCols, rightIndexCols);
269 ict.setYLine(currentYPosition);
270 ict.setAlignment(Element.ALIGN_LEFT);
272 currentYPosition = toYPosition;
274 catch (DocumentException de) {
275 logger.error(de.getMessage());
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)) {
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);
293 int status = ct.go();
294 currentYPosition = toYPosition;
297 catch (DocumentException de) {
298 logger.error(de.getMessage());
303 public void addLine() {
305 cb.moveTo(rightEdge, currentYPosition - 5);
306 cb.lineTo(leftEdge, currentYPosition - 5);
308 currentYPosition = currentYPosition - 10;
312 public void addFooter() {
314 ColumnText fct = new ColumnText(cb);
316 cb.moveTo(rightEdge, bottomEdge + footerHeight - 5);
317 cb.lineTo(leftEdge, bottomEdge + footerHeight - 5);
319 float[] leftFooterCols = {leftEdge, bottomEdge + footerHeight - 1, leftEdge, bottomEdge};
320 float[] rightFooterCols = {rightEdge, bottomEdge + footerHeight - 1, rightEdge, bottomEdge};
322 Paragraph footerP = new Paragraph(footerText, new Font(footerFontFamily, footerFontSize));
323 fct.addText(footerP);
325 fct.setColumns(leftFooterCols, rightFooterCols);
326 fct.setYLine(bottomEdge + footerHeight - 1);
327 fct.setAlignment(Element.ALIGN_JUSTIFIED);
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);
336 catch (DocumentException de) {
337 logger.error(de.getMessage());
343 public void newPage() {
349 currentYPosition = topEdge;
351 catch (DocumentException de) {
352 logger.error(de.getMessage());
356 public void addArticleSeparator() {
362 cb.moveTo(rightEdge, currentYPosition - 5);
363 cb.lineTo(leftEdge, currentYPosition - 5);
365 currentYPosition = currentYPosition - 10;
368 public void addArticleMetaInfo(ColumnText ct, String theTitle, String theCreator, String theDate) {
369 //see if we have room for the author and title
371 if (! enoughY(metaHeight)) {
375 Paragraph titleP = new Paragraph(theTitle + "\n", new Font(metaFontFamily, metaFontSize, Font.BOLD));
376 Paragraph whowhenP = new Paragraph(theCreator + " " + theDate, new Font(metaFontFamily, metaFontSize));
378 ct.addText(whowhenP);
380 ct.setYLine(currentYPosition);
381 ct.setAlignment(Element.ALIGN_LEFT);
383 float toYPosition = currentYPosition - metaHeight;
384 float[] leftHeadCols = {leftEdge, currentYPosition, leftEdge, toYPosition};
385 float[] rightHeadCols = {rightEdge, currentYPosition, rightEdge, toYPosition};
387 ct.setColumns(leftHeadCols, rightHeadCols);
390 currentYPosition = toYPosition;
392 catch (DocumentException de) {
393 logger.error(de.getMessage());
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
402 Paragraph descP = new Paragraph(theDescription, new Font(descriptionFontFamily, descriptionFontSize, Font.BOLD));
405 // every article has a description, so we can assume that:
406 int status = ColumnText.NO_MORE_COLUMN;
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);
415 logger.error("runaway description...try increasing the line height or decreasing the font size");
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);
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;
427 // let's add a little bit of text, like a couple of lines
429 while (((status & ColumnText.NO_MORE_TEXT) == 0) && x < contentLinesBeforeImages) {
430 status = addTextLine(ct, contentLineHeight, Element.ALIGN_JUSTIFIED, leftEdge, rightEdge);
434 boolean addImageOnLeft = true; //we will alternate within articles
435 while (images.hasNext()) {
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;
444 if (img_width > maxImageWidth) {
445 img_height = (new Float((new Float(img_height * (maxImageWidth / img_width))).intValue())).floatValue();
446 img_width = maxImageWidth;
449 String img_title = currentImage.getFieldValue("title");
450 String img_path = currentImage.getFieldValue("publish_path");
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
456 float templateMinimumHeight = img_height + 20;
457 float templateWidth = img_width + 10;
458 float templateHeight = templateMinimumHeight + contentLineHeight - (templateMinimumHeight % contentLineHeight);
460 PdfTemplate template = cb.createTemplate(templateWidth, templateHeight);
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);
474 catch (DocumentException de) {
475 logger.error(de.getMessage());
480 float toYPosition = currentYPosition - templateHeight;
483 Image theImage = Image.getInstance(localImageDir + img_path);
484 theImage.scaleAbsolute(img_width, img_height);
485 theImage.setAbsolutePosition(5, 13);
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);
495 catch (BadElementException de) {
496 logger.error(de.getMessage());
498 catch (DocumentException de) {
499 logger.error(de.getMessage());
501 catch (MalformedURLException de) {
502 logger.error(de.getMessage());
504 catch (IOException de) {
505 logger.error(de.getMessage());
509 float leftImageTextEdge = leftEdge;
510 float rightImageTextEdge = rightEdge;
513 if (addImageOnLeft) {
514 cb.addTemplate(template, leftEdge, toYPosition);
515 leftImageTextEdge = leftEdge + templateWidth + 5;
516 addImageOnLeft = false;
518 cb.addTemplate(template, rightEdge - templateWidth, toYPosition);
519 rightImageTextEdge = rightEdge - templateWidth - 5;
520 addImageOnLeft = true;
523 logger.debug("adding template at " + leftEdge + "," + toYPosition);
525 //and fill some text while we are at it
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);
534 currentYPosition = toYPosition;
536 catch (DocumentException de) {
537 logger.error(de.getMessage());
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())) {
551 float toYPosition = currentYPosition - templateHeight;
553 Image theImage = Image.getInstance(localImageDir + img_path);
554 theImage.setAbsolutePosition(0, 13);
555 theImage.scaleAbsolute(img_width, img_height);
556 template.addImage(theImage);
558 catch (BadElementException de) {
559 logger.error(de.getMessage());
561 catch (DocumentException de) {
562 logger.error(de.getMessage());
564 catch (MalformedURLException de) {
565 logger.error(de.getMessage());
567 catch (IOException de) {
568 logger.error(de.getMessage());
571 cb.addTemplate(template, leftEdge, toYPosition);
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};
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);
585 currentYPosition = toYPosition;
587 catch (DocumentException de) {
588 logger.error(de.getMessage());
593 //add the rest of the text which might be left
595 while ((status & ColumnText.NO_MORE_TEXT) == 0 && brake > 0) {
596 status = addTextLine(ct, contentLineHeight, Element.ALIGN_JUSTIFIED, leftEdge, rightEdge);
600 logger.error("runaway content....try decreasing font size or increasing line height");
603 private void addArticleSource(ColumnText ct, String theSource) {
604 Paragraph sourceP = new Paragraph(theSource, new Font(sourceFontFamily, sourceFontSize, Font.BOLD));
606 addTextLine(ct, sourceLineHeight, Element.ALIGN_RIGHT, leftEdge, rightEdge);
610 private boolean enoughY(int heightOfBlockToAdd) {
611 if ((currentYPosition - heightOfBlockToAdd - footerHeight) < bottomEdge)
617 public void add(EntityContent entityContent) {
618 logger.error("adding a content Entity");
628 * --image without text
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);
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"));
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";
653 String theContent = "";
654 String theDescription = "";
656 if (isHTML.equals("1")) {
660 RE nobackslashr = new RE("\r");
661 theContent = nobackslashr.substituteAll(theContentRaw, "");
662 theDescription = nobackslashr.substituteAll(theDescriptionRaw, "");
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");
668 RE ListItemTag = new RE("<li[^>]*>", RE.REG_ICASE);
669 theContent = ListItemTag.substituteAll(theContent, "\n * ");
670 theDescription = ListItemTag.substituteAll(theDescription, "\n * ");
672 RE ListTag = new RE("<(u|o)l[^>]*>", RE.REG_ICASE);
673 theContent = ListTag.substituteAll(theContent, "\n");
674 theDescription = ListTag.substituteAll(theDescription, "\n");
676 RE DivTag = new RE("</?div[^>]*>", RE.REG_ICASE);
677 theContent = DivTag.substituteAll(theContent, "\n");
678 theDescription = DivTag.substituteAll(theDescription, "\n");
680 RE PTag = new RE("<(p|P)([:space:]+[^>]*)?>");
681 theContent = PTag.substituteAll(theContent, "\n ");
682 theDescription = PTag.substituteAll(theDescription, "\n ");
684 RE PTagClose = new RE("</(p|P)([:space:]+[^>]*)?>");
685 theContent = PTagClose.substituteAll(theContent, "\n");
686 theDescription = PTagClose.substituteAll(theDescription, "\n");
688 RE BRTag = new RE("<(br|BR)([:space:]+[^>]*)?>");
689 theContent = BRTag.substituteAll(theContent, "\n");
690 theDescription = BRTag.substituteAll(theDescription, "\n");
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());
703 theContent = theContentCopy;
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());
715 theDescription = theDescriptionCopy;
718 RE noTags = new RE("<[^>]*>");
719 theContent = noTags.substituteAll(theContent, " ");
720 theDescription = noTags.substituteAll(theDescription, " ");
722 theContent = HTMLRoutines.resolveHTMLEntites(theContent);
723 theDescription = HTMLRoutines.resolveHTMLEntites(theDescription);
725 RE re1 = new RE("\r?\n\r?\n");
726 String theDescription1 = re1.substituteAll(theDescription, "BREAKHERE");
728 RE re2 = new RE("\r?\n");
729 String theDescription2 = re2.substituteAll(theDescription1, " ");
731 RE re3 = new RE("BREAKHERE");
732 theDescription = re3.substituteAll(theDescription2, "\n ");
736 catch (REException ree) {
737 logger.error(ree.getMessage());
741 RE re1 = new RE("\r?\n\r?\n");
742 String theContent1 = re1.substituteAll(theContentRaw, "BREAKHERE");
743 String theDescription1 = re1.substituteAll(theDescriptionRaw, "BREAKHERE");
745 RE re2 = new RE("\r?\n");
746 String theContent2 = re2.substituteAll(theContent1, " ");
747 String theDescription2 = re2.substituteAll(theDescription1, " ");
749 RE re3 = new RE("BREAKHERE");
750 theContent = " " + re3.substituteAll(theContent2, "\n ");
751 theDescription = re3.substituteAll(theDescription2, "\n ");
754 catch (REException ree) {
755 logger.error(ree.getMessage());
759 addArticleSeparator();
761 ColumnText ct = new ColumnText(cb);
763 addArticleMetaInfo(ct, theTitle, theCreator, theDate);
764 addArticleDescription(ct, theDescription);
765 addArticleContent(ct, theContent, images);
766 addArticleSource(ct, theSource);
769 public int getFontByName(String fontName) {
771 if ("helvetica".equalsIgnoreCase(fontName)) {
772 theFont = Font.HELVETICA;
774 else if ("courier".equalsIgnoreCase(fontName)) {
775 theFont = Font.COURIER;
777 else if ("times".equalsIgnoreCase(fontName)) {
778 theFont = Font.TIMES_ROMAN;
781 logger.error("using helvetica because I can't get font for name: " + fontName);
782 theFont = Font.HELVETICA;