You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RtfStringConverter.java 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.render.rtf.rtflib.rtfdoc;
  19. /*
  20. * This file is part of the RTF library of the FOP project, which was originally
  21. * created by Bertrand Delacretaz <bdelacretaz@codeconsult.ch> and by other
  22. * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
  23. * the FOP project.
  24. */
  25. import java.io.IOException;
  26. import java.io.Writer;
  27. import java.util.HashMap;
  28. import java.util.Map;
  29. /**
  30. * <p>Converts java Strings according to RTF conventions.</p>
  31. *
  32. * <p>This work was authored by Bertrand Delacretaz (bdelacretaz@codeconsult.ch).</p>
  33. */
  34. public final class RtfStringConverter {
  35. private static final RtfStringConverter INSTANCE = new RtfStringConverter();
  36. private static final Map SPECIAL_CHARS;
  37. private static final Character DBLQUOTE = '\"';
  38. private static final Character QUOTE = '\'';
  39. private static final Character SPACE = ' ';
  40. /** List of characters to escape with corresponding replacement strings */
  41. static {
  42. SPECIAL_CHARS = new HashMap();
  43. SPECIAL_CHARS.put('\t', "tab");
  44. SPECIAL_CHARS.put('\n', "line");
  45. SPECIAL_CHARS.put('\'', "rquote");
  46. SPECIAL_CHARS.put('\"', "rdblquote");
  47. SPECIAL_CHARS.put('\\', "\\");
  48. SPECIAL_CHARS.put('{', "{");
  49. SPECIAL_CHARS.put('}', "}");
  50. }
  51. /** singleton pattern */
  52. private RtfStringConverter() {
  53. }
  54. /**
  55. * use this to get an object of this class
  56. * @return the singleton instance
  57. */
  58. public static RtfStringConverter getInstance() {
  59. return INSTANCE;
  60. }
  61. /**
  62. * Write given String to given Writer, converting characters as required by
  63. * RTF spec
  64. * @param w Writer
  65. * @param str String to be written
  66. * @throws IOException for I/O problems
  67. */
  68. public void writeRtfString(Writer w, String str) throws IOException {
  69. if (str == null) {
  70. return;
  71. }
  72. w.write(escape(str));
  73. }
  74. /**
  75. * Escapes a String as required by the RTF spec.
  76. * @param str String to be escaped
  77. * @return the escaped string
  78. */
  79. public String escape(String str) {
  80. if (str == null) {
  81. return null;
  82. }
  83. StringBuffer sb = new StringBuffer(Math.max(16, str.length()));
  84. // TODO: could be made more efficient (binary lookup, etc.)
  85. for (int i = 0; i < str.length(); i++) {
  86. final Character c = str.charAt(i);
  87. Character d;
  88. String replacement;
  89. if (i != 0) {
  90. d = str.charAt(i - 1);
  91. } else {
  92. d = SPACE;
  93. }
  94. //This section modified by Chris Scott
  95. //add "smart" quote recognition
  96. if (c.equals((Object)DBLQUOTE) && d.equals((Object)SPACE)) {
  97. replacement = "ldblquote";
  98. } else if (c.equals((Object)QUOTE) && d.equals((Object)SPACE)) {
  99. replacement = "lquote";
  100. } else {
  101. replacement = (String)SPECIAL_CHARS.get(c);
  102. }
  103. if (replacement != null) {
  104. // RTF-escaped char
  105. sb.append('\\');
  106. sb.append(replacement);
  107. sb.append(' ');
  108. } else if (c.charValue() > 127) {
  109. // write unicode representation - contributed by Michel Jacobson
  110. // <jacobson@idf.ext.jussieu.fr>
  111. sb.append("\\u");
  112. sb.append(Integer.toString((int)c.charValue()));
  113. sb.append("\\\'3f");
  114. } else {
  115. // plain char that is understood by RTF natively
  116. sb.append(c.charValue());
  117. }
  118. }
  119. return sb.toString();
  120. }
  121. }