LibreOffice Writerで編集する約100個の.rtf
ファイルがあるディレクトリがあるとします。
そのディレクトリ内のすべてのファイルに、まったく同じ基本的なリッチテキストスタイリングディレクティブが含まれることを望みます。たとえば、
* font-family: Ubuntu # All text in all files is now Ubuntu;
* font-size: 12px # All text in all files is now 12px big;
h1: 28px # All h1's are now 28px big;
if font-size: 18px {make it 22px} # All text with font-size 18px is now 22px;
など...それで、基本的に、すべてのファイルを一度に変更したいです。そのような「一括スタイリング」は可能ですか?
たぶんCLIで可能ですか?
持っているのがコマンドラインツールだけであれば、すべてがコマンドラインの問題のように見えます。 LibreOfficeマクロを使用してこの答えを書くことにしました。
.rtf
(リッチテキスト形式)ライタードキュメントファイルを変更します。以下を含む2つ以上のファイルを作成します。
以下を含むスクリプト~/Downloads/copy-rtf.sh
を作成します。
cp ~/Documents/*.rtf ~/Downloads
を使用して実行可能としてマークする
chmod a+x ~/Downloads/copy-rtf.sh
*.rtf
ファイルを変更するマクロは~/Downloads
ディレクトリに対して実行されます。cd ~/Downloads
を入力し、./copy-rtf.sh
を実行します次の理由で、ダウンロードディレクトリが使用されます。
~/Downloads
を持っています/tmp/
ディレクトリよりも永続的であり、再起動しても保持されない場合があります。これを使用して Stack Exchange answer コマンドラインからLibreoffice Writerを呼び出し、実行するグローバルマクロ名を渡します。
soffice -headless -invisible "vnd.Sun.star.script:Standard.Module1.MySubroutine? language=Basic&location=application"
上記の答えはうまくいかないかもしれません 別の方法 を試すことができます:
soffice "macro:///Standard.SaveCSV.Main" $1
マクロを実行するには、Java Runtime Environment(JRE)がインストールされている必要があります。開発者のWebページには、手動でダウンロードおよびインストールするための instructions があります。
ただし、このAU Q&A: https://askubuntu.com/a/728153/30752 は、次のようにシンプルであることを示唆しています。
Sudo apt-add-repository ppa:webupd8team/Java
Sudo apt-get update
Sudo apt-get install Oracle-Java8-installer Oracle-Java8-set-default
AU Q&Aメソッドを試しましたが、PPAを追加する最初のステップの後、追加情報を含むスプラッシュ画面が表示されます。最も役立つのは DebianシステムでJRE 8をセットアップする へのリンクです。
JRE 8をインストールする3番目の手順では、使用する必要があります Tab そして Enter ライセンス契約に同意します。インストールルーチンの最も重い部分の間、マシンは数分間停止します。
LibreOfficeを開き、Tools->Options->LibreOffice->Advancedこの画面のセットアップ:
次のオプションをクリックします。
マクロはドキュメント全体を読み通し、次のことを行います。
マクロはドキュメントを保存し、Libreoffice Writerを終了します。
ファイルを保存すると、このダイアログが表示されます:
画面に表示されるこのメッセージをオフにします。このオプションがオンの場合、マクロは正しく実行されない場合があります。
「ツール」->「マクロ」->「マクロの記録」->「基本」を使用してマクロを記録しようと数日費やしました。最初は有望に思えましたが、記録されたマクロは一貫性のない動作をし、手書きの基本マクロのために放棄されなければなりませんでした。 Stack Overflowの専門家が、基本的な 基本的なコーディング を手伝ってくれるヘルプを見つけました。結果は次のとおりです。
Sub ChangeAllFonts
rem - Change all font names to Ubuntu.
rem - If heading 1 set font size to 28
rem - else if font size is 18 set to 22
rem - else set font size to 12
rem - The macro will save document and exit LibreOffice Writer.
Dim oDoc As Object
Dim oParEnum As Object, oPar As Object, oSecEnum As Object, oSec As Object
Dim oFamilies As Object, oParaStyles As Object, oStyle As Object
oDoc = ThisComponent
oParEnum = oDoc.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.Sun.star.text.Paragraph") Then
oSecEnum = oPar.createEnumeration()
Do While oSecEnum.hasMoreElements()
oSec = oSecEnum.nextElement()
If oSec.TextPortionType = "Text" Then
If oSec.ParaStyleName = "Heading 1" Then
rem ignore for now
ElseIf oSec.CharHeight = 18 Then
oSec.CharHeight = 22.0
Else
oSec.CharHeight = 12.0
End If
End If
Loop
End If
Loop
oFamilies = oDoc.getStyleFamilies()
oParaStyles = oFamilies.getByName("ParagraphStyles")
oStyle = oParaStyles.getByName("Heading 1")
oStyle.setPropertyValue("CharHeight", 28.0)
FileSave
StarDesktop.terminate()
End Sub
rem Above subroutine is missing call to UbuntuFontName ()
rem also it is calling oStyle.setPropertyValue("CharHeight", 28.0)
rem which may cause problems. Will test. Also StarDesktop.terminate ()
rem is known to cause problems and will likely be reworked with a
rem a dialog box telling operator the program is finished and maybe
rem to press <Alt>+<F4>.
rem ========= Original code below for possible recycling ===========
Sub AllFonts
rem - change all font names to Ubuntu.
rem - If heading 1 set font size to 28
rem - else if font size is 18 set to 22
rem - else set font size to 12
rem The macro will save document and exit Libreoffice Writer.
Dim CharHeight As Long, oSel as Object, oTC as Object
Dim CharStyleName As String
Dim oParEnum as Object, oPar as Object, oSecEnum as Object, oSec as Object
Dim oVC as Object, oText As Object
Dim oParSection 'Current Section
oText = ThisComponent.Text
oSel = ThisComponent.CurrentSelection.getByIndex(0) 'get the current selection
oTC = oText.createTextCursorByRange(oSel) ' and span it with a cursor
rem Scan the cursor range for chunks of given text size.
rem (Doesn't work - affects the whole document)
oParEnum = oTC.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.Sun.star.text.Paragraph") Then
oSecEnum = oPar.createEnumeration()
oParSection = oSecEnum.nextElement()
Do While oSecEnum.hasMoreElements()
oSec = oSecEnum.nextElement()
If oSec.TextPortionType = "Text" Then
CharStyleName = oParSection.CharStyleName
CharHeight = oSec.CharHeight
if CharStyleName = "Heading 1" Then
oSec.CharHeight = 28
elseif CharHeight = 18 Then
oSec.CharHeight = 22
else
oSec.CharHeight = 12
End If
End If
Loop
End If
Loop
FileSave
stardesktop.terminate()
End Sub
Sub UbuntuFontName
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.Sun.star.frame.DispatchHelper")
rem ----------- Select all text ------------------------------------------
dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())
rem ----------- Change all fonts to Ubuntu -------------------------------
dim args5(4) as new com.Sun.star.beans.PropertyValue
args5(0).Name = "CharFontName.StyleName"
args5(0).Value = ""
args5(1).Name = "CharFontName.Pitch"
args5(1).Value = 2
args5(2).Name = "CharFontName.CharSet"
args5(2).Value = -1
args5(3).Name = "CharFontName.Family"
args5(3).Value = 0
args5(4).Name = "CharFontName.FamilyName"
args5(4).Value = "Ubuntu"
dispatcher.executeDispatch(document, ".uno:CharFontName", "", 0, args5())
end sub
sub FileSave
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.Sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Save", "", 0, Array())
end sub
Libre Officeを使用した1回限りのアプローチを次に示します。バッチではありませんが、他の答えを引き出すのに役立つ場合があります。
Ubuntuフォント、28ポイントのH1、12ポイントのテキストと18ポイントのテキストを含むrtfファイルを開きます。
以下に例を示します。
次の手順は、「if font-size:18px {make it 22px}#font-size 18pxのすべてのテキストが22pxになった」という質問で要求された変更を適用します。
メニューの[編集]→[検索と置換]をクリックするか、ヒット CtrlH その他のオプション[検索ボックス]、[属性]ボタン、[フォントサイズ]チェックボックス、[フォーマット]ボタンをクリックして、右端のスクロールボックスから18 ptを選択します。
すべて置換をクリック
変更された該当する行は次のとおりです。
\ par\pard\plain\s0\ql\widctlpar\hyphpar0\ltrpar\cf1\kerning1\dbch\af7\langfe1081\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\ql\widctlpar\hyphpar0\ltrpar {\ rtlch\ltrch\loch\fs36\loch\f6
fs36はfs44に変更されました
変更された他のフィールドは、更新する場合としない場合があるrevtimeフィールドのみでした。
{\ revtim\yr2018\mo3\dy31\hr22\min19}
変更点を知ることで、バッチアプローチを開発するためのモデルが得られます。文書を開いたときにこれを行うマクロを記録したり、必要に応じて変更を加えるスクリプトを開発したりすることが可能です。
RTF仕様 でこれをどのように進めるかについて、いくつかの大きな手がかりがあります。
ここに私の問題の分析があります。
この種のバッチ変換を処理できるGUIベースのアプリケーションを見たことがないので、CLIを使用してこれを実現するのが最も簡単な方法のように思えます。ヘッダーを簡単に変更できるようです:
ヘッダーの構文は次のとおりです。
<header>
\rtf <charset> \deff? <fonttbl> <filetbl>? <colortbl>? <stylesheet>? <listtables>? <revtbl>?
Each of the various header tables should appear, if they exist, in the above order. Document properties can occur before and between the header tables. A property must be defined before being referenced. Specifically:
* The style sheet must occur before any style usage.
* The font table must precede any reference to a font.
* The \deff keyword must precede any text without an explicit reference to a font, because it specifies the font to use in such cases.
個人的に、この情報を確認すると、フォントの選択から style。 に至るまで、ヘッダーでサポートされているように見えることはすべてあるように見えます。
このプロセスを支援するために利用できるツールがあり、以下に概要を説明します私はあなたが持っている文書スタイルの例もあなたが望む文書スタイルもありませんそして、より一般的な答えは、あなたの正確な状況をターゲットにしたものよりも、コミュニティにとってより役立つでしょう。
grep
は、変換する既存のファイルと既存の<fonttbl>
のターゲットスタイルのサンプルを解析するのに役立ちます。<stylesheet>
選択。実際に何を持っているかを確認したら、sed
を使用して既存のヘッダーコンテンツを目的のヘッダーコンテンツに置き換える簡単なスクリプトを作成できるはずです。これらの概念に慣れていない場合は、bashスクリプトでファイルを反復処理する方法の例( example )とsedを利用する方法( example )の多数の例があります。
ファイル内の文字列を置き換える1行のオプションもあります。ユースケースに応じて、他のものよりもうまく機能するものもあります。ファイルの内容に応じて、fs36
のすべてのインスタンスをfs44
に単純に置き換えるのが理にかなっているかもしれません。文書の複雑さと内容に応じて、sed
、Perl
、またはgrep
、あるいはそれらの組み合わせを使用した方がよい場合があります。これがプログラミングの質問になっているので、あなたを参照するのが最善です https://stackoverflow.com/questions/15402770/how-to-grep-and-replace 簡単に1/2ダースの異なるアプローチ。そのうちの1つは、ニーズに完全に適合する可能性があります。
たとえば、これらの変更をシステム全体に適用する場合、
find /path/to/files -type f -exec sed -i 's/oldstring/newstring/g' {} \;
提供 rezizter おそらく最適です。
単一のディレクトリへの変更を含める場合は、
_ billtian が提供するgrep -rl matchstring somedir/ | xargs sed -i 's/fs36/fs44/g'
asは優れた選択肢です。
安全のために、ファイルを前処理して、行った変更が意図しない結果にならないようにする必要があります。例えば:
<!-- language: lang-bash -->
#!/bin/bash
for f in *.rtf
do
echo $f
grep fs36
done
上記は、ディレクトリ内の各.rtfファイルの検索文字列fs36を含む行を表示します。
編集:
最新の仕様を入手できます こちら このアプローチに影響を与えるような変更は見当たりません。