2 veya daha fazla LibreOffice belgesini, aynı stil / biçimlendirmeye sahip olacak şekilde değiştirin


14

Diyelim ki .rtfLibreOffice Writer ile düzenlediğim yaklaşık 100 dosyadan oluşan bir dizinim var.

Bu dizindeki tüm dosyaların aynı temel zengin metin stil yönergelerine sahip olmasını arzu ediyorum, örneğin:

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

Ve böylece ... Temel olarak, tüm dosyaları bir kerede değiştirmek istiyorum. Böyle bir "yığın-şekillendirme" mümkün müdür?

Belki bir şekilde CLI ile mümkündür?


3
Bence bu kolay bir iş olmayacak. Hepsi aynı şekilde yapılandırılmışsa, belki de .rtf dosyalarındaki metni komut satırından değiştirerek bazı hacky çözümlerini kullanabilirsiniz. Ancak, bu rtf dosyalarının nasıl göründüğüne ve ne kadar benzer olduklarına bağlıdır.
Sebastian Stark

Bu gece sıfırdan başlayarak yepyeni bir LibreOffice Writer makrosu için Stack Overflow'da yardım buldum. Artık olası her yazı tipi boyutunu bilmemize gerek yok.
WinEunuuchs2Unix

Son bir hendek çabasında Stack Overflow uzmanlarından, yetkisiz kullanım süresi sona ermeden önce bir cevap göndermelerini istedim: stackoverflow.com/questions/49640951/…
WinEunuuchs2Unix

On binlerce itibar puanınız var. Alçakgönüllü olarak 500-750 gibi bir şey vermeyi düşünmenizi öneririm. Sadece bir düşünün. Sadece sadece.
JohnDoea

Yanıtlar:


5

CLI yerine Libreoffice araçlarını kullanma

Tüm sahip olduğunuz komut satırı araçları olduğunda her şey bir komut satırı sorununa benziyor. Bu cevabı LibreOffice makrolarını kullanarak yazmaya karar verdim:

  1. Her Writer belgesini "başsız" bir ortamda işlemek için bir komut satırı döngüsü kullanın.
  2. .rtf(Zengin Metin Biçimi) Yazar belge dosyasını değiştirmek için makroyu çalıştırın .
  3. Makro dosyayı kaydeder ve çıkar
  4. 1'e geri dönün.

Test verileri oluşturma

Aşağıdakileri içeren iki veya daha fazla dosya oluşturun:

richtext2.png

Şunları ~/Downloads/copy-rtf.shiçeren komut dosyası oluştur :

cp ~/Documents/*.rtf ~/Downloads

Kullanarak yürütülebilir olarak işaretle

chmod a+x ~/Downloads/copy-rtf.sh
  • Geliştirme ve test sırasında, *.rtfdosyaları değiştiren makrolar ~/Downloadsdizinde çalıştırılır .
  • Her test türü cd ~/Downloadsve çalışmasından önce./copy-rtf.sh
  • Çıktı mükemmel olduktan sonra, canlı dizine geri kopyalanırlar.

İndirilenler dizini kullanılır, çünkü:

  • herkesin bir ~/Downloads
  • düzenli ve manuel olarak boşaltılır.
  • /tmp/yeniden başlatmalarda kalıcı olmayabilecek dizinden daha kalıcıdır .

Makroyu başsız bir ortamda çalıştırın

Bu Yığın Değişimi yanıtını kullanarak Libreoffice Writer'ı komut satırından çağırır ve yürütmek için genel bir makro adı iletir:

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

Yukarıdaki yanıt çalışmayabilir, bu nedenle başka bir yöntem denenebilir:

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

Java Runtime Environment yazılımını yükleme

Makroları çalıştırmak için Java Runtime Environment (JRE) yazılımının yüklü olması gerekir. Geliştiricinin web sayfasında manuel olarak indirme ve yükleme talimatları vardır .

Ancak bu AU Soru-Cevap: /ubuntu//a/728153/307523 bunun kadar basit olduğunu göstermektedir:

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 yöntemini denedim ve PPA eklemenin ilk adımından sonra ek bilgiler içeren bir açılış ekranı belirdi. En yararlı olanı , Debian sistemlerinde JRE 8 kurulumu için bir bağlantıdır .

JRE 8 kurulumunun üçüncü adımı , Lisans Sözleşmesini kullanmanızı Tabve Enterkabul etmenizi gerektirir . Kurulum rutininin en ağır kısmı sırasında makineniz birkaç dakika duraklayacaktır.

Şimdi LibreOffice'i açın ve Araçlar -> Seçenekler -> LibreOffice -> Gelişmiş'i seçin ve bu ekranı ayarlayın:

LO JRE8 Gelişmiş Kurulum.png

Aşağıdakiler için seçenekleri tıklayın:

  • Java çalışma zamanı ortamı kullanma
  • Oracle Corporation 1.8.0_161
  • Makro kaydını etkinleştir (deneysel)
  • Tamam'ı tıklayın
  • Yeniden başlatmanız istenir, "Şimdi Yeniden Başlat" ı tıklayın.

LibreOffice Yazar Makrosu

Makro tüm belgeyi okuyacak ve:

  • yazı tipi adını Ubuntu olarak değiştirin.
  • 1 başlığı yazı tipi boyutunu 28 olarak ayarlarsa
  • yazı tipi boyutu 18 olarak ayarlanmışsa
  • başka yazı tipi boyutunu 12 olarak ayarlayın

Makro belgeyi kaydedecek ve Libreoffice Writer'dan çıkacaktır.

İletişim Kutusunu Kapat

Bir dosya kaydedin ve bu iletişim kutusu açılır:

LO Writer RTF iletişim kutusunu kapat

Bu mesajı ekranda gösterildiği gibi kapatın. Bu seçenek açıksa makro düzgün çalışmayabilir.

Makro içeriği

Birkaç gün "Araçlar" -> "Makrolar" -> "Makro Kaydet" -> "Temel" kullanarak bir makro kaydetmeye çalışarak geçirdim. İlk başta ümit verici görünüyordu, ancak kaydedilen makro tutarsız bir davranışa sahipti ve elle yazılmış bir temel makro için terkedilmek zorunda kaldı. Temel temel kodlama konusunda bana yardımcı olacak bir uzman için Stack Overflow'da bulunan bir yardım . İşte sonuç:

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

İşte Libre Office kullanarak bir defaya mahsus yaklaşım. Bu toplu değil, ancak diğer cevaplara ilham vermenize yardımcı olabilir.

Ubuntu yazı tipi, H1'i 28 punto, bazıları 12pt ve bazıları 18 pt olan bir rtf dosyası açın.

İşte bir örnek:

test rtf

Aşağıdaki adımlar, "yazı tipi boyutu varsa: 18px {make 22px} # Yazı tipi boyutu 18px olan tüm metinler artık 22 piksel;"

Menüde Düzenle → Bul ve Değiştir'i tıklatın veya CtrlHDiğer seçenekler'i tıklatın. Ara'yı tıklatın, ardından öznitelikler düğmesini Yazı tipi boyutu onay kutusu ve Biçim düğmesi en sağdaki kaydırma kutusundan 18 pt'yi seçin Kutuyla değiştir'i ve ardından Biçim düğmesini seçin ve en sağdaki kaydırma kutusu

FindNreplace

Tümünü Değiştir'i tıklayın

değişen satır:

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

fs36 fs44 olarak değiştirildi

değiştirilen diğer tek alan güncellemek isteyebileceğiniz veya istemeyeceğiniz zaman aralığı alanıdır:

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

Neyin değiştiğini bilmek bize toplu yaklaşım geliştirmek için bir model sağlar. Bir belgeyi açtıktan sonra bunu yapan bir Makro Kaydetmek veya değişiklikleri istediğiniz gibi yapan bir komut dosyası geliştirmek mümkündür.


1

RTF spesifikasyonunda bunun nasıl olabileceğine dair bazı harika ipuçları var .

İşte benim sorunumun analizi.

Tahmin ettiğiniz gibi CLI kullanarak bunu başarmak en basit yaklaşım gibi görünebilir, çünkü bu tür toplu dönüştürme işlemek için herhangi bir GUI tabanlı uygulamalar görmedim. Başlığı basitçe değiştirebileceğiniz anlaşılıyor:

Üstbilgide şu sözdizimi bulunur:

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

Şahsen, bu bilgileri inceledikten sonra, yapmaya çalıştığınız her şeyin yazı tipi seçiminden stile kadar başlıkta desteklendiği gibi görünüyor .

Sahip olduğunuz belge stiline veya istediğiniz belge stiline bir örneğim olmadığından, aşağıda genel olarak anlatacağım bu işlemde size yardımcı olacak araçlar vardır ve daha genel bir yanıt muhtemelen topluluk için daha yararlı olacaktır tam durumunuzu hedefleyen biri.

grepdönüştürülecek mevcut dosyaları ve var olan <fonttbl>ve
<stylesheet>seçimler için hedef stilin bir örneğini ayrıştırmak için yararlı olacaktır . Gerçekten neye sahip olduğunuzu belirledikten sonra sed, mevcut başlık içeriğini istenen başlık içeriğiyle değiştirmek için basit bir komut dosyası yazabilmelisiniz . Bir bash betiğindeki ( örnek ) dosyalar arasında nasıl yineleme yapılacağı ve bu kavramlara aşina değilseniz sed ( örnek ) 'in nasıl serbestçe kullanılabileceğine dair çok sayıda örnek vardır .

Dosyadaki bir dizeyi değiştirmek için bir satır seçeneği de vardır. Kullanım durumunuza bağlı olarak bazıları diğerlerinden daha iyi çalışabilir. Dosyalarınızın içeriğine bağlı olarak bu veya basit için duyu her geçtiği yerde değiştirmek yapmak olmayabilir fs36ile fs44siz de ifadeleri yazmaya nasıl en iyi üzerinde etkisi olabilecek kullandığınız kabuk Hangi. Karmaşıklık ve belgelerin içeriğine bağlı olarak kullanmakta daha iyi olabilir sed, perlya da grepbelki onlardan bile bir arada ya. Bu bir programlama sorusu haline geldiğinden , sizi kolayca 1/2 düzine farklı yaklaşım bulabileceğiniz /programming/15402770/how-to-grep-and-replace adresine yönlendirmek en iyisidir . Bu da ihtiyaçlarınıza mükemmel şekilde cevap verecektir.

Örneğin, bu değişiklikleri sistem genelinde uygulamak istiyorsanız,

find /path/to/files -type f -exec sed -i 's/oldstring/newstring/g' {} \;rezizter tarafından sağlanan muhtemelen en iyisidir.

Değişikliklerinizi tek bir dizine eklemek istiyorsanız,

grep -rl matchstring somedir/ | xargs sed -i 's/fs36/fs44/g'billtian tarafından sağlanan gibi mükemmel bir seçimdir.

Güvenli tarafta olmak için, yapabileceğiniz değişikliklerin istenmeyen sonuçlara yol açmayacağından emin olmak için dosyaları önceden işlemelisiniz. Örneğin:

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

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

Yukarıdaki, dizindeki her .rtf dosyası için fs36 arama dizesini içeren satırları görüntüler.

Düzenle:

En son spesifikasyon burada bulunabilir. Bu yaklaşımı etkileyecek hiçbir değişiklik görmüyorum.


1
Merhaba, öncelikle bir CLI çözümünü tanımladığınız için teşekkür ederim. Lütfen a'yı bir rtfbaşlık ve metinle nasıl değiştireceğinize ilişkin bir kod örneği paylaşın , sedböylece yanıt b merkezileştirilir sed.
JohnDoea

@JohnDoea Her zaman yardım etmeye istekli. Umarım hem siz hem de gelecekteki kullanıcılar bunu faydalı bulur.
Elder Geek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.