文書ドキュメントの構造
文書ドキュメントには、次の 4 種類の情報が記録されています。
- テキスト本体
- 文字、段落、ページを対象とした書式設定用テンプレート
- テーブル、画像、図形描画オブジェクトなど、テキスト以外の要素
- 文書ドキュメント全体の設定
本節では特に、テキストおよびその書式設定オプションについて説明します。
段落と段落部位
文書ドキュメントは、段落の集合であるとも言えます。しかしこのような段落は、個別的な名前やインデックスが付けられているわけでもないため、直接アクセスする方法はありません。その代わり段落へのアクセスは、「API について」で説明されている Enumeration オブジェクトを用いた順次アクセスが行えます。段落を編集する場合は、このような機能を利用します。
ただし Enumeration オブジェクトで取得される対象には、段落だけでなくテーブルも含まれるので、注意が必要です (Apache OpenOffice Writer では、テーブルを特殊な段落として処理)。このため、取得したオブジェクトへアクセスする際には、そのオブジェクトが段落を示す com.sun.star.text.Paragraph サービスをサポートしているのか、テーブルを示す com.sun.star.text.TextTable サービスをサポートしているのかを確認する必要があります。
次のサンプルコードでは、ループを使って文書ドキュメントの内容に順次アクセスして、各インスタンスごとに該当オブジェクトが段落であるかテーブルであるかを、メッセージ表示します。
Dim Doc As Object
Dim Enum As Object
Dim TextElement As Object
' Create document object
Doc = StarDesktop.CurrentComponent
' Create enumeration object
Enum = Doc.Text.createEnumeration
' loop over all text elements
While Enum.hasMoreElements
TextElement = Enum.nextElement
If TextElement.supportsService("com.sun.star.text.TextTable") Then
MsgBox "The current block contains a table."
End If
If TextElement.supportsService("com.sun.star.text.Paragraph") Then
MsgBox "The current block contains a paragraph."
End If
Wend
このサンプルコードでは、Doc というドキュメントオブジェクトを作成して、現在の Apache OpenOffice ドキュメントを参照しています。次にこの Doc オブジェクトを使って Enumeration オブジェクトを作成して、テキストの各部 (段落およびテーブル) に順次アクセスして、TextElement というオブジェクトに現在の要素を取得します。そして supportsService メソッドを使って、TextElement の内容が段落かテーブルかを判定しています。
段落
段落の内容にアクセスするには、com.sun.star.text.Paragraph サービスを使用します。そして段落中のテキストの取得および変更には、String 属性を使用します。
Dim Doc As Object
Dim Enum As Object
Dim TextElement As Object
Doc = StarDesktop.CurrentComponent
Enum = Doc.Text.createEnumeration
While Enum.hasMoreElements
TextElement = Enum.nextElement
If TextElement.supportsService("com.sun.star.text.Paragraph") Then
TextElement.String = Replace(TextElement.String, "you", "U")
TextElement.String = Replace(TextElement.String, "too", "2")
TextElement.String = Replace(TextElement.String, "for", "4")
End If
Wend
このサンプルコードでは、現在の文書ドキュメントを開いて、その内容に Enumeration オブジェクトを用いて順次アクセスしています。そして各段落の TextElement.String 属性を使用して、単語 you、too と for をそれぞれ文字 U、2 と 4 に置き換えていますなお、ここで使っている Replace という関数は、Apache OpenOffice Basic に用意されているものではありません。これは、「検索と置換」で説明されている実行例です。
VBA の Characters, Sentences および Words リストに直接該当する機能は、Apache OpenOffice Basic には用意されていません。ただし、TextCursor の機能を利用することで、文字、段落、ワード単位での操作を行えます。
段落部位
上記のサンプルコードを実行すると、テキストの置換は成功しても、書式設定が崩れるような場合があります。
このような現象は、個々の段落が独立したサブオブジェクトから構成されていることに原因があります。これら各サブオブジェクトは、独自の書式設定情報を保持しています。たとえば、中央部の 1 つの単語だけに太字の書式設定が行われた段落がある場合、Apache OpenOffice はこの段落を、太字テキストよりも前の部分、太字テキストの部分、太字テキストよりも後の通常テキストの部分という、3 つの段落部位として扱います。
この段落のテキストを String 属性を使って変更する場合、Apache OpenOffice は該当する段落部位をいったん削除してから新規に段落部位を挿入するという方法で処理を進めます。この際に、変更前の書式設定は失われてしまいます。
このような現象を回避するには、段落全体ではなく該当する段落部位にアクセスするようにします。このような処理を行うため、各段落には Enumeration オブジェクトが用意されています。次のサンプルコードは、先のサンプルコードと同様の置換処理を実行しますが、ここではループを二重にすることで、文書ドキュメント内のすべての段落および、各段落を構成するすべての段落部位にアクセスするようにしています。
Dim Doc As Object
Dim Enum1 As Object
Dim Enum2 As Object
Dim TextElement As Object
Dim TextPortion As Object
Doc = StarDesktop.CurrentComponent
Enum1 = Doc.Text.createEnumeration
' loop over all paragraphs
While Enum1.hasMoreElements
TextElement = Enum1.nextElement
If TextElement.supportsService("com.sun.star.text.Paragraph") Then
Enum2 = TextElement.createEnumeration
' loop over all sub-paragraphs
While Enum2.hasMoreElements
TextPortion = Enum2.nextElement
MsgBox "'" & TextPortion.String & "'"
TextPortion.String = Replace(TextPortion.String, "you", "U")
TextPortion.String = Replace(TextPortion.String, "too", "2")
TextPortion.String = Replace(TextPortion.String, "for", "4")
Wend
End If
Wend
このサンプルコードでは、二重ループを使って文書ドキュメントの内容に順次アクセスしています。外周部のループは、段落単位のアクセスを担当しています。そして内周部のループは、各段落を構成する段落部位のアクセスを担当しています。次のサンプルコードでは、文字列の String 属性を使用して、各段落部位の内容を変更します。段落については、先のサンプルコードの場合と同じです。ただしこのサンプルコードでは、個々の段落部位ごとに変更するようにしているので、テキストの置換を行なっても書式設定情報は保持されます。
書式設定
テキストの書式設定を行う方法は、複数あります。一番簡単な方法は、書式設定用属性をテキストに直接指定することです。このような方式は、ダイレクトフォーマッティングと呼ばれます。通常このようなダイレクトフォーマッティングが使われるのは、マウス操作による逐次的な書式設定が行えるような、比較的小さめのドキュメントです。より具体的に言えば、ユーザーがマウスを直接操作してテキスト内の特定の単語を太字にしたり、1 行だけを中央揃えにする場合が、これに該当します。
書式設定は、ダイレクトフォーマッティング以外にも、テンプレートを使って行うことができます。このような方式を、インダイレクトフォーマッティングと呼びます。インダイレクトフォーマッティングは、あらかじめ定義しておいたテンプレートを、該当テキストに適用することで実施します。このようなテキストの書式設定を後から変更する場合は、テンプレートを変更するだけで済みます。Apache OpenOfficeはテンプレートへの変更を、該当するすべてのテキストに対して一括適用します。
文字属性
ここでは、個々の文字に対する書式設定属性を、文字属性と総称します。このようなものには、太字やフォントなどの書体指定が該当します。文字属性を使えるオブジェクトは、com.sun.star.style.CharacterProperties サービスをサポートしているものに限られます。Apache OpenOffice には、これに該当する各種のサービスが存在します。たとえば先に説明した、段落に対する com.sun.star.text.Paragraph サービスや、段落部位に対する com.sun.star.text.TextPortion サービスなども、その中に含まれます。
com.sun.star.style.CharacterProperties サービスは、何らかのインターフェースを提供するものではなく、文字属性の指定と取得を行う各種の属性を提供します。すべての文字属性のリストについては、Apache OpenOffice の『API reference』を参照してください。以下に主要な属性を示します。
- CharFontName (String)
- 選択したフォントの種類の名前。
- CharColor (Long)
- テキストの色。
- CharHeight (Float)
- ポイント単位で指定した文字の高さ。
- CharUnderline (Constant group)
- 下線の種類 (com.sun.star.awt.FontUnderline に定められた定数)。
- CharWeight (Constant group)
- フォントの太さ (com.sun.star.awt.FontWeight に定められた定数)。
- CharBackColor (Long)
- 背景色。
- CharKeepTogether (Boolean)
- 自動行ブレークを抑制する指定。
- CharStyleName (String)
- 文字テンプレートの名前。
段落属性
個々の文字に対してではなく、段落全体に対して施される書式設定の情報は、段落属性と総称されます。このような情報としては、用紙と段落の間の余白や行間の大きさなどが該当します。段落属性は、com.sun.star.style.ParagraphProperties サービスを通じて使用します。
段落属性は、各種のオブジェクトで利用できます。com.sun.star.text.Paragraph サービスをサポートするすべてのオブジェクトは、com.sun.star.style.ParagraphProperties の段落属性もサポートしています。
すべての段落属性のリストについては、『Apache OpenOfficeAPI reference』を参照してください。以下に主要な段落属性を示します。
- ParaAdjust (enum)
- 垂直の文字の方向 (com.sun.star.style.ParagraphAdjust に定められた定数)。
- ParaLineSpacing (struct)
- 行間 (com.sun.star.style.LineSpacing に定められた構造体)。
- ParaBackColor (Long)
- 背景色。
- ParaLeftMargin (Long)
- 100 分の 1 ミリ単位で指定した左マージン。
- ParaRightMargin (Long)
- 100 分の 1 ミリ単位で指定した右マージン。
- ParaTopMargin (Long)
- 100 分の 1 ミリ単位で指定した上マージン。
- ParaBottomMargin (Long)
- 100 分の 1 ミリ単位で指定した下マージン。
- ParaTabStops (Array of struct)
- タブの種類と位置 (Typs 構造 com.sun.star.style.TabStop を持つ配列)。
- ParaStyleName (String)
- 段落テンプレートの名前。
例: HTML の簡易エクスポート
次のサンプルコードは、書式設定情報の操作例です。ここでは、文書ドキュメントを順次読み取り、HTML 形式ファイルへの簡易的な変換を行なっています。基本的な変換処理としては、個々の段落の先頭に HTML タグの <P> を付加します。同様に、太字指定のされた段落部位には HTML タグの <B> を付けるよう処理しています。
Dim FileNo As Integer, Filename As String, CurLine As String
Dim Doc As Object
Dim Enum1 As Object, Enum2 As Object
Dim TextElement As Object, TextPortion As Object
Filename = "c:\text.html"
FileNo = Freefile
Open Filename For Output As #FileNo
Print #FileNo, "<HTML><BODY>"
Doc = StarDesktop.CurrentComponent
Enum1 = Doc.Text.createEnumeration
' loop over all paragraphs
While Enum1.hasMoreElements
TextElement = Enum1.nextElement
If TextElement.supportsService("com.sun.star.text.Paragraph") Then
Enum2 = TextElement.createEnumeration
CurLine = "<P>"
' loop over all paragraph portions
While Enum2.hasMoreElements
TextPortion = Enum2.nextElement
If TextPortion.CharWeight = com.sun.star.awt.FontWeight.BOLD THEN
CurLine = CurLine & "<B>" & TextPortion.String & "</B>"
Else
CurLine = CurLine & TextPortion.String
End If
Wend
' output the line
CurLine = CurLine & "</P>"
Print #FileNo, CurLine
End If
Wend
' write HTML footer
Print #FileNo, "</BODY></HTML>"
Close #FileNo
このサンプルコードの基本構造は、先に説明した段落部位へアクセスするサンプルコードと同じものです。今回追加されたものは、HTML ファイルの書き出し処理および、テキストが太字であるかをチェックして該当する段落部位を HTML タグで囲むよう処理するコードです。
文字と段落属性のデフォルト値
ダイレクトフォーマッティングは、常にインダイレクトフォーマッティングに優先します。これはつまりテンプレートによる書式設定よりも、テキストへの直接操作による書式設定の方が優先されるということになります。
ドキュメントの特定セクションが、ダイレクトフォーマッティングされたのか、インダイレクトフォーマッティングされたのかは、簡単には確認できません。Apache OpenOffice のオブジェクトバーには、本文テキストに設定されたフォント、太さ、サイズなどの属性が表示されます。しかし、このような書式設定がテンプレートによるものか、直接設定したものかについては表示されません。
特定の属性については、Apache OpenOffice Basic の getPropertyState メソッドを使うことで、どのように書式設定されているかを確認することができます。この場合に渡すパラメータには属性名を指定し、戻り値としては書式設定の出所を示す定数が返されます。このような定数としては、com.sun.star.beans.PropertyState に定義された次の値が使われます。
- com.sun.star.beans.PropertyState.DIRECT_VALUE
- テキストへの直接操作により設定された属性 (ダイレクトフォーマッティング)
- com.sun.star.beans.PropertyState.DEFAULT_VALUE
- テンプレートにより設定された属性 (インダイレクトフォーマッティング)
- com.sun.star.beans.PropertyState.AMBIGUOUS_VALUE
- 属性が不明確。このような状況が発生するのは、たとえばプレーンテキストと太字テキストの部分が混在する段落で、太字テキストの部分を調べようとした場合などです。
次のサンプルコードでは、書式設定用属性が Apache OpenOffice 内でどのように編集されているかを調べます。ここでは、個々の段落部位にダイレクトフォーマッティングにより太字にされたものがあるかをチェックします。そして該当する段落部位があると、setPropertyToDefault メソッドを用いてダイレクトフォーマッティングによる書式指定を解除して、MyBold という文字テンプレートを適用させています。
Dim Doc As Object
Dim Enum1 As Object
Dim Enum2 As Object
Dim TextElement As Object
Dim TextPortion As Object
Doc = StarDesktop.CurrentComponent
Enum1 = Doc.Text.createEnumeration
' loop over all paragraphs
While Enum1.hasMoreElements
TextElement = Enum1.nextElement
If TextElement.supportsService("com.sun.star.text.Paragraph") Then
Enum2 = TextElement.createEnumeration
' loop over all paragraph portions
While Enum2.hasMoreElements
TextPortion = Enum2.nextElement
If TextPortion.CharWeight = _
com.sun.star.awt.FontWeight.BOLD AND _
TextPortion.getPropertyState("CharWeight") = _
com.sun.star.beans.PropertyState.DIRECT_VALUE Then
TextPortion.setPropertyToDefault("CharWeight")
TextPortion.CharStyleName = "MyBold"
End If
Wend
End If
Wend
Content on this page is licensed under the Public Documentation License (PDL). |