2つ以上のLibreOfficeドキュメントを変更して、まったく同じスタイル/フォーマットを使用する


14

.rtfLibreOffice Writerで編集する約100個のファイルがあるディレクトリがあるとします。

そのディレクトリ内のすべてのファイルに、まったく同じ基本的なリッチテキストスタイリングディレクティブが含まれることを望みます。次に例を示します。

* 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で可能ですか?


3
これは簡単な作業ではないと思います。それらがすべて同じ方法で構成されている場合は、コマンドラインから.rtfファイル内のテキストを置き換える、何らかのハッキングソリューションを使用できます。ただし、これはrtfファイルがどのように見えるか、およびそれらがどの程度似ているかに大きく依存します。
セバスチャン・スターク

Stack Overflowで、今夜ゼロから始めるまったく新しいLibreOffice Writerマクロのヘルプを見つけました。既存のすべてのフォントサイズを知る必要はなくなりました。
WinEunuuchs2Unix

土壇場の努力で、私は猶予期間が終了する前に、ここで答えを投稿するスタックオーバーフローの専門家を求めてきました:stackoverflow.com/questions/49640951/...
WinEunuuchs2Unix

あなた達は何万もの評判ポイントを持っています。500-750のようなものを与えることを検討することを謙虚に提案します。ただの考察。ただただ。
-JohnDoea

回答:


5

CLIの代わりにLibreofficeツールを使用する

持っているのがコマンドラインツールだけであれば、すべてがコマンドラインの問題のように見えます。LibreOfficeマクロを使用してこの答えを書くことにしました。

  1. コマンドラインループを使用して、すべてのWriterドキュメントを「ヘッドレス」環境で処理します。
  2. 変更するマクロを実行 .rtf(リッチテキスト形式)Writerドキュメントファイルます。
  3. マクロはファイルを保存して終了します
  4. 1にループバックします。

テストデータを作成する

以下を含む2つ以上のファイルを作成します。

richtext2.png

以下~/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の回答を使用して、コマンドラインからLibreoffice Writerを呼び出し、実行するグ​​ローバルマクロ名を渡します。

soffice -headless -invisible "vnd.sun.star.script:Standard.Module1.MySubroutine? language=Basic&location=application"

上記の答えが機能しない場合があるため、別の方法を試すことができます。

soffice "macro:///Standard.SaveCSV.Main" $1

Javaランタイム環境をインストールする

マクロを実行するには、Java Runtime Environment(JRE)がインストールされている必要があります。開発者のWebページに手順があります、手動でダウンロードしてインストールするためのがあります。

ただし、このAU Q&A:https : //askubuntu.com/a/728153/307523は、次のようにシンプルであることを示唆しています

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番目の手順では、ライセンス契約を使用TabEnterて同意する必要があります。インストールルーチンの最も重い部分の間、マシンは数分間停止します。

LibreOfficeを開き、[ ツール] -> [ オプション] -> [ LibreOffice] -> [ 詳細設定]を選択して、この画面をセットアップします。

LO JRE8 Advanced Setup.png

次のオプションをクリックします。

  • Javaランタイム環境を使用する
  • Oracle Corporation 1.8.0_161
  • マクロ記録を有効にする(実験的)
  • OKをクリック
  • 再起動するように求められたら、[今すぐ再起動]をクリックします。

LibreOffice Writerマクロ

マクロは文書全体を読み通し、次のことを行います。

  • フォント名をUbuntuに変更します。
  • 見出し1の場合、フォントサイズを28に設定します
  • それ以外の場合、フォントサイズが18で22に設定されている場合
  • それ以外の場合は、フォントサイズを12に設定します

マクロはドキュメントを保存し、Libreoffice Writerを終了します。

ダイアログをオフにする

ファイルを保存すると、このダイアログが表示されます:

LO WriterはRTF dialog.pngをオフにします

画面に表示されるこのメッセージをオフにします。このオプションがオンの場合、マクロは正しく実行されない場合があります。

マクロの内容

「ツール」->「マクロ」->「マクロの記録」->「基本」を使用してマクロを記録しようと数日費やしました。最初は有望に見えましたが、記録されたマクロは一貫性のない動作をし、手書きの基本マクロのために放棄されなければなりませんでした。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

2

Libre Officeを使用した1回限りのアプローチです。バッチではありませんが、他の答えを引き出すのに役立つ場合があります。

Ubuntuフォント、28ポイントのH1、12ポイントのテキストと18ポイントのテキストを含むrtfファイルを開きます。

以下に例を示します。

テストRTF

次の手順は、「if font-size:18px {make 22px}#font-size 18pxのテキストはすべて22pxになりました」という質問で要求された変更を適用します。

メニューの[編集]→[検索と置換]をCtrlHクリックするか、[その他のオプション]をクリックします。一番右のスクロールボックス

FindNreplace

すべて置換をクリック

変更された該当する行は次のとおりです。

\ 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}

変更点を知ることで、バッチアプローチを開発するためのモデルが得られます。文書を開いたときにこれを行うマクロを記録したり、必要に応じて変更を加えるスクリプトを開発したりすることが可能です。


1

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.

個人的に、この情報を確認すると、フォントの選択からスタイルまで、あなたがしようとしていることはすべてヘッダーでサポートされているように見えます。

このプロセスを支援するツールはありますが、以下に概要を説明します。これは、使用しているドキュメントスタイルや必要なドキュメントスタイルの例がないためです。より一般的な回答は、コミュニティよりも役に立つでしょうあなたの正確な状況をターゲットにしたもの。

grep変換される既存のファイルと、既存<fonttbl>および
<stylesheet>選択のターゲットスタイルのサンプルを解析するのに役立ちます。実際に何を持っているかを判断したらsed、既存のヘッダーコンテンツを目的のヘッダーコンテンツに置き換えるために使用する簡単なスクリプトを作成できるはずです。これらの概念に慣れていない場合は、bashスクリプト内のファイルを反復処理する方法の例()およびsedを利用する方法()の無料の例が多数あります。

ファイル内の文字列を置き換える1行のオプションもあります。ユースケースに応じて、他のものよりもうまく機能するものもあります。あなたのファイルの内容に依存して、または単純に感覚がのすべてのインスタンス置き換える加えることはできませんことfs36fs44、あなたもあなたの式を書くことが最善の方法でベアリングを有していてもよく使っているシェルのどちらを。複雑さと、ドキュメントの内容によっては、あなたが使用したほうが良いかもしれsedperlまたはgrepおそらくそれらの組み合わせであってもまたは。これがプログラミングの質問になったので、https://stackoverflow.com/questions/15402770/how-to-grep-and-replaceを参照するのが最善です。ニーズに完全に適合する可能性があります。

たとえば、これらの変更をシステム全体に適用する場合、

find /path/to/files -type f -exec sed -i 's/oldstring/newstring/g' {} \;rezizterによって提供されるように、おそらく最高です。

単一のディレクトリへの変更を含める場合は、

grep -rl matchstring somedir/ | xargs sed -i 's/fs36/fs44/g'billtianが提供するのは素晴らしい選択です。

安全のために、ファイルを前処理して、行った変更が意図しない結果にならないようにする必要があります。例えば:

<!-- language: lang-bash -->

    #!/bin/bash
    for f in *.rtf 
        do
        echo $f
        grep fs36
        done

上記は、ディレクトリ内の各.rtfファイルの検索文字列fs36を含む行を表示します。

編集:

ここから最新の仕様を入手できます。このアプローチに影響を与えるような変更は見当たりません。


1
こんにちは、最初にCLIソリューションについて説明していただきありがとうございます。をrtf見出しとテキストで変更する方法のコード例を共有してください。sedそうすれば、答えは集中化されsedます。
ジョンドエア

@JohnDoea常に助けに熱心です。あなたと将来のユーザーの両方がそれが役に立つことを願っています。
オタク長老
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.