Змініть 2 або більше документів LibreOffice, щоб мати таку ж стилізацію / форматування


14

Скажімо, у мене каталог з приблизно 100 .rtfфайлами, які я редагую за допомогою LibreOffice Writer.

Я хочу, щоб у всіх файлах у цьому каталозі були такі самі базові директиви для стильного розширення тексту, наприклад:

* 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

Використовуйте інструменти Libreoffice замість CLI

Коли у вас є інструменти командного рядка, все виглядає як проблема командного рядка. Я вирішив написати цю відповідь за допомогою макросів LibreOffice:

  1. Використовуйте цикл командного рядка для обробки кожного документа Writer у середовищі "без голови".
  2. Запустіть макрос, щоб змінити .rtf(Rich Text Format) файл документа Writer.
  3. Макрос зберігає файл та вихід
  4. Петля назад до 1.

Створення даних тесту

Створіть два або більше файлів, що містять:

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). Веб-сторінка розробника містить інструкції щодо завантаження та встановлення вручну.

Однак це питання AU: /ubuntu//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 з'являється екран із сплеском із додатковою інформацією. Найбільш корисним є посилання на налаштування JRE 8 в системах Debian .

Третій крок встановлення JRE 8 вимагає використання Tabта Enterприйняття Ліцензійної угоди. Ваша машина буде робити паузу на кілька хвилин під час найважчої частини встановлення.

Тепер відкрийте LibreOffice та виберіть Інструменти -> Параметри -> LibreOffice -> Додатково та налаштуйте цей екран:

LO JRE8 Advanced Setup.png

Клацніть параметри для:

  • Використовуйте середовище виконання Java
  • Корпорація Oracle 1.8.0_161
  • Увімкнути макро запис (експериментальний)
  • Натисніть кнопку ОК
  • Вам буде запропоновано перезапустити, натисніть "Перезапустити зараз".

Макрос 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. Це не партія, але може допомогти надихнути інші відповіді.

Відкрийте rtf-файл із шрифтом Ubuntu, H1 на 28 пт, текст у 12pt та десь у 18 pt.

Ось приклад:

тест rtf

Наступні кроки застосують зміну, запитану у вашому запитанні "якщо розмір шрифту: 18px {make it 22px} # Весь текст із розміром шрифту 18px зараз становить 22px;"

Клацніть Редагувати → Знайти та замінити в меню або натисніть CtrlHІнші параметри Клацніть поле "Пошук", а потім "Атрибути" кнопку "Розмір шрифту", потім кнопку "Формат", виберіть 18 п. поле прокрутки праворуч

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 \ lpar {\ rtlch \ ltrch \ loch \ fs36 \ loch \ f6

fs36 змінився на fs44

єдиним іншим полем, яке змінилося, було поле revtime, яке ви можете або не хочете оновлювати:

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

Знаючи, що змінилося, дає нам модель для розробки пакетного підходу. Можливо, можливо записати макрос, який робить це після відкриття документа або розробити сценарій, який вносить зміни за бажанням.


1

Існує декілька чудових підказок щодо того, як можна про це піти в специфікації RTF.

Ось мій аналіз питання.

Виконання цього за допомогою 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 ( приклад ) у вільному доступі, якщо ви не знайомі з цими поняттями.

Також є один варіант рядка для заміни рядка у файлі. Деякі можуть працювати краще, ніж інші, залежно від випадку використання. В залежності від вмісту файлів може або не може мати сенс простий заміни кожен екземпляр fs36з fs44якої оболонки використовується також може мати відношення , як краще писати свої висловлювання. В залежності від складності та змісту документів може бути краще використовувати sed, perlабо , grepабо , можливо , навіть їх поєднання. Оскільки це стало питанням програмування, найкраще звернутися до /programming/15402770/how-to-grep-and-replace, де ви легко знайдете 1/2 десятка різних підходів, одного з що, ймовірно, цілком відповідає вашим потребам.

Наприклад, якщо ви хочете застосувати ці зміни в системі широко,

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'як надає Білтіан - це відмінний вибір.

Щоб захиститись, слід попередньо обробити файли, щоб гарантувати, що будь-які зміни, які ви можете внести, не матимуть ненавмисних наслідків. Наприклад:

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

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

Вище буде показано рядки, що містять пошуковий рядок fs36 для кожного .rtf-файлу в каталозі.

Редагувати:

Останню специфікацію можна отримати тут. Я не бачу змін, які мали б вплинути на такий підхід.


1
Здрастуйте, я дякую вам за перше опис рішення CLI. Поділіться прикладом коду щодо того, як ви будете змінювати rtfзаголовок та текст, sedщоб відповідь була централізованою sed.
JohnDoea

@JohnDoea Завжди прагнемо допомогти. Сподіваюся, і ви, і майбутні користувачі вважають це корисним.
Старійшина Гейк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.