001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: RtfStringConverter.java 426576 2006-07-28 15:44:37Z jeremias $ */
019:
020: /*
021: * This file is part of the RTF library of the FOP project, which was originally
022: * created by Bertrand Delacretaz <bdelacretaz@codeconsult.ch> and by other
023: * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
024: * the FOP project.
025: */
026:
027: package org.apache.fop.render.rtf.rtflib.rtfdoc;
028:
029: import java.util.Map;
030: import java.util.HashMap;
031: import java.io.IOException;
032: import java.io.Writer;
033:
034: /** Converts java Strings according to RTF conventions
035: * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
036: */
037:
038: public class RtfStringConverter {
039: private static final RtfStringConverter INSTANCE = new RtfStringConverter();
040:
041: private static final Map SPECIAL_CHARS;
042: private static final Character DBLQUOTE = new Character('\"');
043: private static final Character QUOTE = new Character('\'');
044: private static final Character SPACE = new Character(' ');
045:
046: /** List of characters to escape with corresponding replacement strings */
047: static {
048: SPECIAL_CHARS = new HashMap();
049: SPECIAL_CHARS.put(new Character('\t'), "tab");
050: SPECIAL_CHARS.put(new Character('\n'), "line");
051: SPECIAL_CHARS.put(new Character('\''), "rquote");
052: SPECIAL_CHARS.put(new Character('\"'), "rdblquote");
053: SPECIAL_CHARS.put(new Character('\\'), "\\");
054: SPECIAL_CHARS.put(new Character('{'), "{");
055: SPECIAL_CHARS.put(new Character('}'), "}");
056: }
057:
058: /** singleton pattern */
059: private RtfStringConverter() {
060: }
061:
062: /**
063: * use this to get an object of this class
064: * @return the singleton instance
065: */
066: public static RtfStringConverter getInstance() {
067: return INSTANCE;
068: }
069:
070: /**
071: * Write given String to given Writer, converting characters as required by
072: * RTF spec
073: * @param w Writer
074: * @param str String to be written
075: * @throws IOException for I/O problems
076: */
077: public void writeRtfString(Writer w, String str) throws IOException {
078: if (str == null) {
079: return;
080: }
081: w.write(escape(str));
082: }
083:
084: /**
085: * Escapes a String as required by the RTF spec.
086: * @param str String to be escaped
087: * @return the escaped string
088: */
089: public String escape(String str) {
090: if (str == null) {
091: return null;
092: }
093:
094: StringBuffer sb = new StringBuffer(Math.max(16, str.length()));
095: // TODO: could be made more efficient (binary lookup, etc.)
096: for (int i = 0; i < str.length(); i++) {
097: final Character c = new Character(str.charAt(i));
098: Character d;
099: String replacement;
100: if (i != 0) {
101: d = new Character(str.charAt(i - 1));
102: } else {
103: d = new Character(str.charAt(i));
104: }
105:
106: //This section modified by Chris Scott
107: //add "smart" quote recognition
108: if (c.equals((Object) DBLQUOTE) && d.equals((Object) SPACE)) {
109: replacement = "ldblquote";
110: } else if (c.equals((Object) QUOTE)
111: && d.equals((Object) SPACE)) {
112: replacement = "lquote";
113: } else {
114: replacement = (String) SPECIAL_CHARS.get(c);
115: }
116:
117: if (replacement != null) {
118: // RTF-escaped char
119: sb.append('\\');
120: sb.append(replacement);
121: sb.append(' ');
122: } else if (c.charValue() > 127) {
123: // write unicode representation - contributed by Michel Jacobson
124: // <jacobson@idf.ext.jussieu.fr>
125: sb.append("\\u");
126: sb.append(Integer.toString((int) c.charValue()));
127: sb.append("\\\'3f");
128: } else {
129: // plain char that is understood by RTF natively
130: sb.append(c.charValue());
131: }
132: }
133: return sb.toString();
134: }
135:
136: }
|