3

我需要font style check为我选择的文本区域做。

我曾经applescript将突出显示/选定的文本区域复制到剪贴板并在 java 中检索剪贴板值。我曾经string捕获选定/突出显示的值。

有什么办法可以style check使用Stringin java.

代码检索剪贴板值:

    String result = "";
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

    //odd: the Object param of getContents is not currently used
    Transferable contents = clipboard.getContents(null);
    boolean hasTransferableText = (contents != null) &&
      contents.isDataFlavorSupported(DataFlavor.stringFlavor);
    if ( hasTransferableText ) {
      try {
        result = (String)contents.getTransferData(DataFlavor.stringFlavor);
      }
      catch (UnsupportedFlavorException ex){
      }
      catch (IOException ex) {
      }
    }
    return result;
  }

字体信息:

{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 Verdana;\f1\fnil\fcharset0 Tahoma;}
{\colortbl;\red255\green255\blue255;}
\deftab720
\pard\pardeftab720\sa280

\f0\i\fs34 \cf0 testing
\f1\i0  hello\'a0
\b Module 
\b0 \ul world}
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 Verdana;\f1\fnil\fcharset0 Tahoma;}
{\colortbl;\red255\green255\blue255;}
\deftab720
\pard\pardeftab720\sa280

\f0\i\fs34 \cf0 testing
\f1\i0  hello\'a0
\b Module 
\b0 \ul world}

请指教。非常感谢任何建议/参考。

4

2 回答 2

1

您获得的值是富文本格式的语义代码。完整的基于 Java 的 rtf 解析器的代码在这里发布会很长,但作为参考,Swing 中有一个RTFEditorKit 0,Apache 的Tika项目有一个 RTFParser。

RTF 使用控制词 - 它们具有类似于其他标记语言的开始和结束标签,例如:

示例: \someAsciiTag1 ... \someAsciiTag1

对于您的问题:

字体样式就在字体表或\fnttbl组中 - 组由大括号{}封装。

字体样式在索引类结构上排序,其中\f* index *作为控制代码。

下一个代码是\f* font-family *等等。

虽然全局字体样式在 \fnttbl 中的文件顶部设置,但可以在纯文本部分(如 html)中进行某些样式修改,例如:\fs20表示 font-size = 20 的任何单位在结构上进一步继承,如css。

虽然我可以在这里发布 Java 代码来向您展示如何访问特定标签,并且如果您只需要访问一些全局元素,我会这样做,但我不知道您的整个项目的范围,如果这是您的目标您文本中的所有样式我真的非常强烈建议您使用上面可用的解析器之一,因为 RTF 是一种非常复杂的格式。

如果您对此表示怀疑,这里有一个指向 Microsoft 规范的链接,它大约有 270 页,我所知道的最轻量级的实现非常接近规范完整,是超过 9000 行代码,这就是您可能不这样做的原因想自己做。

http://www.microsoft.com/en-us/download/details.aspx?id=10725

编辑:

我意识到我在上一个答案中没有完全回答你的第二个问题

\b 或 \b1 = 粗体(真或 1)\b0 = 粗体(假或 0)

\i 或 \i1 = 斜体(真或 1)\i0 = 斜体(假或 0)

仅供参考,但是,这些不是设置样式的唯一方法,rtf 允许其他不太常见的编程方式来设置这些值。ascii 和 unicode rtf 代码之间也存在差异,因此再次使用解析器。

我仍然包含字体标签结构,所以如果你想要全局信息,你可以得到它。

<fonttbl>   '{' \fonttbl (<fontinfo> | ('{' <fontinfo> '}'))+ '}'
<fontinfo>  <themefont>? \fN <fontfamily> \fcharsetN? \fprq? <panose>? <nontaggedname>?
    <fontemb>? \cpgN? <fontname> <fontaltname>? ';' 
<themefont> \flomajor | \fhimajor | \fdbmajor | \fbimajor | \flominor | \fhiminor |
    \fdbminor | \fbiminor
<fontfamily>    \fnil | \froman | \fswiss | \fmodern | \fscript | \fdecor | \ftech | 
    \fbidi
<panose>    '{\*' \panose <data> '}'
<nontaggedname> '{\*' \fname #PCDATA ';}'
<fontname>  #PCDATA
<fontaltname>   '{\*' \falt #PCDATA '}'
<fontemb>   '{\*' \fontemb <fonttype> <fontfname>? <data>? '}'
<fonttype>  \ftnil | \fttruetype
<fontfname> '{\*' \fontfile \cpgN? #PCDATA '}'

那是字体数据标签的列表和字体数据的一般结构。希望有帮助。

编辑:跟进

好吧,从外观上看,您有一大块 Mac rtfd(额外的标签)

cocoartf1038\cocoasubrtf360 - 告诉你它是mac编码的

第一部分给出了编码 第二部分给出了两种主要的字体样式 Verdana 在 f0 和 Tahoma 在 f1 第三行告诉你它是白色 rgb(255,255,255) 和所有。第四个和第五个定义选项卡和分页。第六个(非空白)说 f0\i\fs34 = Verdana, Italic, size 34 \cf0 是黑色前景色第七个是 Tahoma 斜体,粗体是围绕模块,而世界是下划线等等然后重复。

有一个基于 Java 的 rtf 解析器,它最近添加了对一些 mac 自定义标签的支持,您可以在 GitHub 上找到它,连接模块并解析您可能需要的任何文件应该相当简单。

于 2013-08-24T08:43:46.473 回答
-1

仅当剪贴板中的文本为富格式文本 (RTF) 时,您的数据中才包含格式数据。在这种情况下,当您检查并且剪贴板的内容包含 RTF 文本时,您可以检查其字体和其他格式信息。您可以使用此示例代码作为起点。

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;

public class ClipboardTest {

    public static void main(String[] args) {
        System.out.println(getClipboardData());
    }

    public static String getClipboardData() {
        String result = "";
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

        // odd: the Object param of getContents is not currently used
        Transferable contents = clipboard.getContents(null);
        DataFlavor dfRTF = new DataFlavor("text/rtf", "Rich Formatted Text");
        DataFlavor dfTxt = DataFlavor.stringFlavor;

        boolean hasTransferableRTFText = (contents != null)
                && contents.isDataFlavorSupported(dfRTF);

        boolean hasTransferableTxtText = (contents != null)
                && contents.isDataFlavorSupported(dfTxt);

        if (hasTransferableRTFText) {
            try {
                result = streamToString((InputStream)contents
                        .getTransferData(dfRTF));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else if (hasTransferableTxtText) {
            try {
                result = (String)contents
                        .getTransferData(dfTxt);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    private static String streamToString(InputStream transferData) {
        return slurp(transferData, 1024);
    }

    public static String slurp(final InputStream is, final int bufferSize)
    {
      final char[] buffer = new char[bufferSize];
      final StringBuilder out = new StringBuilder();
      try {
        final Reader in = new InputStreamReader(is, "UTF-8");
        try {
          for (;;) {
            int rsz = in.read(buffer, 0, buffer.length);
            if (rsz < 0)
              break;
            out.append(buffer, 0, rsz);
          }
        }
        finally {
          in.close();
        }
      }
      catch (UnsupportedEncodingException ex) {
        /* ... */
      }
      catch (IOException ex) {
          /* ... */
      }
      return out.toString();
    }

}
于 2013-08-22T21:39:44.733 回答