Views:
787
Votes: 4
✅ Solution
Tags:
libreoffice
style
Link:
🔍 See Original Answer on Ask Ubuntu ⧉ 🔗
URL:
https://askubuntu.com/q/1021152
Title:
Change 2 or more LibreOffice documents to have the exact same styling/formatting
ID:
/2018/04/01/Change-2-or-more-LibreOffice-documents-to-have-the-exact-same-styling_formatting
Created:
April 1, 2018
Edited: January 9, 2022
Upload:
September 15, 2024
Layout: post
TOC:
true
Navigation: true
Copy to clipboard: false
Use LibreOffice Tools Instead of Command Line
When all you have are command line tools everything looks like a command line problem. I’ve decided to write this answer using LibreOffice macros:
- Use a command line loop to process every Writer document in a “headless” environment.
- Run macro to change
.rtf
(Rich Text Format) Writer document file. - Macro saves file and exit
- Loop back to 1.
Table of Contents
- Use LibreOffice Tools Instead of Command Line
- Create Test Data
- Run Macro in Headless Environment
- Install Java Runtime Environment
- LibreOffice Writer Macro
Create Test Data
Create two or more files containing:
Create script ~/Downloads/copy-rtf.sh
containing:
cp ~/Documents/*.rtf ~/Downloads
Mark as executable using
chmod a+x ~/Downloads/copy-rtf.sh
- During development and testing, the macros modifying
*.rtf
files will run against~/Downloads
directory. - Before each test type
cd ~/Downloads
and run./copy-rtf.sh
- After output is perfect, they are copied back into live directory.
The Downloads
directory is used because:
- everyone has a
~/Downloads
- it gets added to regularly and manually emptied periodically
- it is more permanent than
/tmp/
directory which may not persist across reboots.
Run Macro in Headless Environment
Using this Stack Exchange answer, run Libreoffice Writer from the command line and pass it a global macro name to execute:
soffice -headless -invisible "vnd.sun.star.script:Standard.Module1.MySubroutine? language=Basic&location=application"
If the above method doesn’t work, another method can be tried:
soffice "macro:///Standard.SaveCSV.Main" $1
Install Java Runtime Environment
To run macros you need Java Runtime Environment (JRE) installed. The developer’s web page has instructions for downloading and installing manually.
However this AU Q&A: https://askubuntu.com/a/728153/307523 suggests it is as simple as:
sudo apt-add-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer oracle-java8-set-default
I tried the AU Q&A method and after the first step of adding the PPA a splash screen appears with additional information. The most helpful is a link to setting up JRE 8 on Debian systems.
The third step of installing JRE 8 requires you to use Tab and Enter to accept the License Agreement. Your machine will pause for a few minutes during the heaviest part of the installation routine.
Now open LibreOffice and select Tools -> Options -> LibreOffice -> Advanced and setup this screen:
Click the options for:
- Use a Java runtime environment
- Oracle Corporation 1.8.0_161
- Enable macro recording (experimental)
- Click OK
- You will be asked to restart, click “Restart Now”.
LibreOffice Writer Macro
The macro will read through the entire document and:
- change font name to Ubuntu.
- If heading 1 set font size to 28
- else if font size is 18 set to 22
- else set font size to 12
The macro will save document and exit LibreOffice Writer.
Turn Off Dialog
Do a file save and this dialog comes up:
Turn this message off as show in the screen. The macro may not run properly if this option is on.
Macro Contents
I spent a few days attempting to record a macro using “Tools” -> “Macros” -> “Record Macro” -> “Basic”. At first it seemed promising but the recorded macro had inconsistent behavior and had to be abandoned for a hand written basic macro. A found help in Stack Overflow for an expert there to help me with the basic basic coding. Here is the result:
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