Ubah 2 atau lebih dokumen LibreOffice untuk memiliki gaya / format yang sama persis

14

Katakanlah saya memiliki direktori dengan sekitar 100 .rtffile yang saya edit dengan LibreOffice Writer.

Saya berharap bahwa semua file dalam direktori itu akan memiliki arahan penataan gaya teks kaya persis sama, misalnya:

* 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;

Dan sebagainya ... Jadi, pada dasarnya saya ingin mengubah semua file sekaligus. Mungkinkah "penataan massal" seperti itu?

Mungkin itu mungkin dengan CLI entah bagaimana?

JohnDoea
sumber
3
Ini bukan tugas yang mudah saya pikir. Jika semuanya terstruktur dengan cara yang sama, Anda mungkin dapat menggunakan beberapa solusi hacky dengan mengganti teks dalam file .rtf dari baris perintah. Namun, ini sangat tergantung pada bagaimana file rtf terlihat dan seberapa mirip mereka.
Sebastian Stark
Saya telah menemukan bantuan dalam Stack Overflow untuk makro LibreOffice Writer baru mulai dari awal malam ini. Kami tidak lagi perlu mengetahui setiap kemungkinan ukuran font yang ada.
WinEunuuchs2Unix
Dalam upaya terakhir saya telah meminta ahli Stack Overflow untuk mengirim jawaban di sini sebelum masa tenggang berakhir: stackoverflow.com/questions/49640951/…
WinEunuuchs2Unix
Kalian memiliki puluhan ribu poin reputasi. Dengan rendah hati saya sarankan Anda mempertimbangkan untuk memberikan sesuatu seperti 500-750. Hanya sebuah pertimbangan. Hanya saja.
JohnDoea

Jawaban:

5

Gunakan alat Libreoffice bukan CLI

Ketika semua yang Anda miliki adalah alat baris perintah semuanya tampak seperti masalah baris perintah. Saya telah memutuskan untuk menulis jawaban ini menggunakan makro LibreOffice:

  1. Gunakan loop baris perintah untuk memproses setiap dokumen Writer dalam lingkungan "tanpa kepala".
  2. Jalankan makro untuk mengubah .rtf(Rich Text Format) file dokumen Writer.
  3. Makro menyimpan file dan keluar
  4. Kembali ke 1.

Buat data uji

Buat dua atau lebih file yang mengandung:

richtext2.png

Buat skrip yang ~/Downloads/copy-rtf.shberisi:

cp ~/Documents/*.rtf ~/Downloads

Tandai sebagai dapat dieksekusi menggunakan

chmod a+x ~/Downloads/copy-rtf.sh
  • Selama pengembangan dan pengujian, makro memodifikasi *.rtffile akan berjalan melawan ~/Downloadsdirektori.
  • Sebelum setiap jenis tes cd ~/Downloadsdan jalankan./copy-rtf.sh
  • Setelah output sempurna, mereka disalin kembali ke direktori langsung.

Direktori Unduhan digunakan karena:

  • setiap orang memiliki ~/Downloads
  • itu akan ditambahkan secara teratur dan dikosongkan secara manual secara berkala
  • ini lebih permanen daripada /tmp/direktori yang mungkin tidak bertahan selama reboot.

Jalankan makro di lingkungan tanpa kepala

Menggunakan jawaban Stack Exchange ini, minta Libreoffice Writer dari baris perintah dan berikan nama makro global untuk dieksekusi:

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

Jawaban di atas mungkin tidak berfungsi sehingga metode lain dapat dicoba:

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

Instal Java Runtime Environment

Untuk menjalankan makro Anda perlu menginstal Java Runtime Environment (JRE). Halaman web pengembang memiliki instruksi untuk mengunduh dan menginstal secara manual.

Namun, T&J AU ini: /ubuntu//a/728153/307523 menyarankannya sesederhana:

sudo apt-add-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer oracle-java8-set-default

Saya mencoba metode Tanya Jawab AU dan setelah langkah pertama menambahkan PPA, layar splash muncul dengan informasi tambahan. Yang paling membantu adalah tautan untuk mengatur JRE 8 pada sistem Debian .

Langkah ketiga menginstal JRE 8 mengharuskan Anda untuk menggunakan Tabdan Entermenerima Perjanjian Lisensi. Mesin Anda akan berhenti selama beberapa menit selama bagian terberat dari rutin instalasi.

Sekarang buka LibreOffice dan pilih Alat -> Opsi -> LibreOffice -> Advanced dan setup layar ini:

LO JRE8 Advanced Setup.png

Klik opsi untuk:

  • Gunakan lingkungan Java runtime
  • Oracle Corporation 1.8.0_161
  • Aktifkan perekaman makro (percobaan)
  • Klik OK
  • Anda akan diminta untuk me-restart, klik "Restart Now".

LibreOffice Writer Macro

Makro akan membaca seluruh dokumen dan:

  • ubah nama font menjadi Ubuntu.
  • Jika pos 1 atur ukuran font menjadi 28
  • lain jika ukuran font 18 diatur ke 22
  • lain atur ukuran font menjadi 12

Makro akan menyimpan dokumen dan keluar dari Libreoffice Writer.

Matikan Dialog

Lakukan penyimpanan file dan dialog ini muncul:

Penulis LO mematikan dialog RTF.png

Matikan pesan ini seperti yang ditampilkan di layar. Makro mungkin tidak berjalan dengan benar jika opsi ini aktif.

Konten makro

Saya menghabiskan beberapa hari mencoba merekam makro menggunakan "Alat" -> "Makro" -> "Rekam Makro" -> "Dasar". Pada awalnya itu tampak menjanjikan tetapi makro yang direkam memiliki perilaku yang tidak konsisten dan harus ditinggalkan untuk makro dasar tulisan tangan. Ditemukan bantuan di Stack Overflow untuk ahli di sana untuk membantu saya dengan pengkodean dasar dasar . Inilah hasilnya:

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
WinEunuuchs2Unix
sumber
2

Berikut ini pendekatan sekali pakai menggunakan Libre Office. Ini bukan batch, tetapi dapat membantu menginspirasi jawaban lain.

Buka file rtf yang memiliki font Ubuntu, H1 pada 28 pt, beberapa teks pada 12pt dan beberapa pada 18 pt.

Ini sebuah contoh:

uji rtf

Langkah-langkah berikut akan menerapkan perubahan yang diminta dalam pertanyaan Anda "jika ukuran font: 18px {make it 22px} # Semua teks dengan ukuran font 18px sekarang 22px;"

Klik Edit → Cari & Ganti pada menu atau tekan CtrlHOpsi lain. Klik kotak Cari Untuk kemudian tombol atribut Ukuran font kotak centang lalu Format tombol pilih 18 pt dari kotak gulir di sebelah kanan. Klik Ganti dengan kotak lalu Format tombol dan pilih 22 pt dari kotak gulir di paling kanan

FindNreplace

Klik Ganti Semua

baris yang berlaku yang berubah adalah:

\ par \ pard \ plain \ s0 \ ql \ widctlpar \ hyphpar0 \ ltrpar \ cf1 \ kerning1 \ dbch \ af7 \ langfe1081 \ dbch \ af7 \ afs24 \ alang1081 \ loch \ f3 \ fs24 \ lang1033 \ ql \ widctlpar \ lhpar \ {\ rtlch \ ltrch \ loch \ fs36 \ loch \ f6

fs36 berubah menjadi fs44

satu-satunya bidang lain yang berubah adalah bidang revtime yang Anda mungkin atau mungkin tidak ingin memperbarui:

{\ revtim \ yr2018 \ mo3 \ dy31 \ hr22 \ min19}

Mengetahui apa yang berubah memberi kita model untuk mengembangkan pendekatan batch. Mungkin saja untuk Merekam Makro yang melakukan ini saat membuka dokumen atau mengembangkan skrip yang membuat perubahan seperti yang diinginkan.

Penatua Geek
sumber
1

Ada beberapa petunjuk hebat tentang bagaimana seseorang dapat melakukan ini dalam spesifikasi RTF.

Inilah analisis saya tentang masalah ini.

Menyelesaikan ini menggunakan CLI saat Anda menduga akan menjadi pendekatan yang paling sederhana karena saya belum melihat aplikasi berbasis GUI yang dapat menangani konversi batch semacam ini. Tampaknya Anda dapat dengan mudah memodifikasi tajuk:

Header memiliki sintaks berikut:

<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.

Secara pribadi, setelah meninjau informasi ini, saya menyadari bahwa semua yang Anda coba lakukan sepertinya didukung di header, dari pemilihan font hingga gaya.

Ada alat yang tersedia untuk membantu Anda dengan proses ini yang akan saya uraikan di bawah karena saya tidak memiliki contoh gaya dokumen yang Anda miliki atau gaya dokumen yang Anda inginkan dan jawaban yang lebih umum kemungkinan akan lebih berguna untuk komunitas daripada satu ditargetkan untuk situasi Anda yang sebenarnya.

grepakan berguna untuk mem-parsing file yang ada untuk dikonversi dan sampel gaya target untuk yang sudah ada <fonttbl>dan
<stylesheet>pilihan. Setelah menentukan apa yang sebenarnya Anda miliki, Anda harus dapat menulis skrip sederhana dengan memanfaatkan seduntuk mengganti konten header yang ada dengan konten header yang diinginkan. Ada banyak contoh tentang bagaimana melakukan iterasi melalui file dalam skrip bash ( contoh ) dan cara memanfaatkan sed ( contoh ) yang tersedia secara bebas jika Anda tidak terbiasa dengan konsep-konsep ini.

Ada juga satu opsi baris untuk mengganti string dalam file. Beberapa mungkin bekerja lebih baik daripada yang lain tergantung pada kasus penggunaan Anda. Bergantung pada konten file Anda, mungkin atau mungkin tidak masuk akal untuk mengganti setiap instance fs36dengan fs44shell mana yang Anda gunakan mungkin juga berhubungan dengan cara terbaik untuk menulis ekspresi Anda. Bergantung pada kerumitan dan isi dokumen Anda, Anda mungkin lebih baik menggunakan sed, perlatau grepatau bahkan kombinasi dari mereka. Karena ini telah menjadi pertanyaan pemrograman, sebaiknya merujuk Anda ke /programming/15402770/how-to-grep-and-replace mana Anda akan dengan mudah menemukan 1/2 lusin pendekatan yang berbeda, salah satunya yang mungkin sesuai dengan kebutuhan Anda dengan sempurna.

Misalnya, jika Anda ingin menerapkan perubahan sistem ini secara luas,

find /path/to/files -type f -exec sed -i 's/oldstring/newstring/g' {} \;seperti yang disediakan oleh rezizter Kemungkinan adalah yang terbaik.

Jika Anda ingin memuat perubahan Anda ke satu direktori,

grep -rl matchstring somedir/ | xargs sed -i 's/fs36/fs44/g'seperti yang disediakan oleh billtian adalah pilihan yang sangat baik.

Agar aman, Anda harus memproses ulang file untuk memastikan bahwa setiap perubahan yang Anda buat tidak akan memiliki konsekuensi yang tidak diinginkan. Contohnya:

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

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

Di atas akan menampilkan baris yang berisi string pencarian fs36 untuk setiap file .rtf di direktori.

Edit:

Spesifikasi terbaru dapat diperoleh di sini. Saya tidak melihat perubahan apa pun yang berdampak pada pendekatan ini.

Penatua Geek
sumber
1
Halo, saya ucapkan terima kasih karena telah menjelaskan solusi CLI terlebih dahulu. Silakan bagikan contoh kode untuk bagaimana Anda akan mengubah rtfdengan tajuk dan teks sedsehingga jawaban akan terpusat pada sed.
JohnDoea
@JohnDoea Selalu ingin membantu. Saya harap Anda dan pengguna di masa depan akan merasakan manfaatnya.
Penatua Geek