Tools>Macros>Organize>Basic…
Button “Organize…”
The code under “My Macros” is organized in libraries and modules. There is a library named “Standard”. Add a module to “Standard” and paste the code to that module.
Close the Basic editor.
Open the document in question.
Call Tools>Macros>Runn…,navigate to your macro and run it.
Thank you, I will try this. Just to confirm, this is gonna make all the characters (indexes, variables, text, etc.) bold, isn’t it?
I reworked and renamed my little snippet. There are 8 different types of text which can be bold.
I did run the code, but it doesn’t seem to do anything. On Basic editor though, running it returns:
“BASIC runtime error.
Property or method not found: getDrawPages”
Are you sure that this is the code I should run through LibreOffice Impress and it would modify all the formulas?
I saved the above code under "My Macros > library "DrawPage" > module "MathProps"
, however, the location does not really matter as long as you can find the routine changeFormulas_Bold_18pt
.
Just in case, anybody asks, the following Basic module seems to work with Writer, Calc, Impress, Draw and Math:
REM ***** BASIC *****
Sub changeFormulas_Bold_18pt()
doc = ThisComponent
sNames = Array("BaseFontHeight", "FontMathIsBold", "FontFixedIsBold", "FontFunctionsIsBold", "FontNumbersIsBold", "FontSansIsBold", "FontSerifIsBold", "FontTextIsBold", "FontVariablesIsBold")
values = Array(18, True, True, True, True, True, True, True, True)
changeFormulaProperties doc, sNames, values
End Sub
Sub changeFormulas_Regular_12pt()
doc = ThisComponent
sNames = Array("BaseFontHeight", "FontMathIsBold", "FontFixedIsBold", "FontFunctionsIsBold", "FontNumbersIsBold", "FontSansIsBold", "FontSerifIsBold", "FontTextIsBold", "FontVariablesIsBold")
values = Array(12, False, False, False, False, False, False, False, False)
changeFormulaProperties doc, sNames, values
End Sub
Sub changeFormulaProperties(doc, sNames, values)
if doc.supportsService("com.sun.star.formula.FormulaProperties") Then
doc.setPropertyValues(sNames, values)
elseif HasUnoInterfaces(doc, "com.sun.star.drawing.XDrawPageSupplier") Then
obj = doc.getDrawPage()
loopDrawPage obj, sNames, values
elseif HasUnoInterfaces(doc, "com.sun.star.drawing.XDrawPagesSupplier") Then
REM Draw, Impress, Calc
obj = doc.getDrawPages()
loopDrawPages obj, sNames, values
endif
End Sub
Sub loopDrawPages(oDrawPages, sNames, values)
for nDP = 0 to oDrawPages.getCount()-1
oDP = oDrawPages.getByIndex(nDP)
loopDrawPage oDP, sNames, values
next nDP
End Sub
Sub loopDrawPage(oDP, sNames, values)
for nShape = 0 to oDP.getCount()-1
oShape = oDP.getByIndex(nShape)
REM recurse grouped controls:
if oShape.supportsService("com.sun.star.drawing.GroupShape") then loopDrawPage oShape, sNames, values
on error resume next
setShapeModelProperties oShape, sNames, values
next nShape
End Sub
Sub setShapeModelProperties(oShape, sNames, values)
oModel = oShape.Model
sImplementationName = oModel.ImplementationName
if sImplementationName = "com.sun.star.comp.Math.FormulaDocument" then
oModel.setPropertyValues(sNames, values)
endif
End Sub
All you need to prepare is your own routine with a list of property names in array sNames and a corresponding array of property values. In the above code, changeFormulas_Bold_18pt
defines 9 properties, the first one is the font size (short integer 18) and 8 boolean values describing the boldness (True) of different formula contents.
The routine changeFormulas_Regular_12pt
resets the same properties to regular fonts of size 12.
ThisComponent refers to the currently active document.
The following list shows 63 properties that may be useful in this context:
(Name) (Type)
Alignment short
BaseFontHeight short
BaseLine short
BottomMargin short
CustomFontNameFixed string
CustomFontNameSans string
CustomFontNameSerif string
FontFixedIsBold boolean
FontFixedIsItalic boolean
FontFunctionsIsBold boolean
FontFunctionsIsItalic boolean
FontMathIsBold boolean
FontMathIsItalic boolean
FontNameFunctions string
FontNameMath string
FontNameNumbers string
FontNameText string
FontNameVariables string
FontNumbersIsBold boolean
FontNumbersIsItalic boolean
FontSansIsBold boolean
FontSansIsItalic boolean
FontSerifIsBold boolean
FontSerifIsItalic boolean
FontTextIsBold boolean
FontTextIsItalic boolean
FontVariablesIsBold boolean
FontVariablesIsItalic boolean
Formula string
GreekCharStyle short
Identifier string
IsRightToLeft boolean
IsScaleAllBrackets boolean
IsTextMode boolean
LeftMargin short
RelativeBracketDistance short
RelativeBracketExcessSize short
RelativeFontHeightFunctions short
RelativeFontHeightIndices short
RelativeFontHeightLimits short
RelativeFontHeightOperators short
RelativeFontHeightText short
RelativeFractionBarExcessLength short
RelativeFractionBarLineWeight short
RelativeFractionDenominatorDepth short
RelativeFractionNumeratorHeight short
RelativeIndexSubscript short
RelativeIndexSuperscript short
RelativeLineSpacing short
RelativeLowerLimitDistance short
RelativeMatrixColumnSpacing short
RelativeMatrixLineSpacing short
RelativeOperatorExcessSize short
RelativeOperatorSpacing short
RelativeRootSpacing short
RelativeScaleBracketExcessSize short
RelativeSpacing short
RelativeSymbolMinimumHeight short
RelativeSymbolPrimaryHeight short
RelativeUpperLimitDistance short
RightMargin short
SyntaxVersion short
TopMargin short
The LibreOffice developers strongly advise against using ImplementationName
.
Maybe so:
Sub changeFormulaProperties(doc, sNames, values)
if doc.supportsService("com.sun.star.formula.FormulaProperties") Then
doc.setPropertyValues(sNames, values)
elseif HasUnoInterfaces(doc, "com.sun.star.drawing.XDrawPageSupplier") Then
obj = doc.getDrawPage()
loopDrawPage obj, sNames, values
elseif HasUnoInterfaces(doc, "com.sun.star.drawing.XDrawPagesSupplier") Then
REM Draw, Impress, Calc
obj = doc.getDrawPages()
loopDrawPages obj, sNames, values
endif
End Sub
Do they?
Sure. I replaced the subroutine.
They do.
So, I copied this code to the basic editor as well and then closed it. Upon running a new macro
First, fourth, fifth and sixth ones one give me this error:
A Scripting Framework error occurred while running the Basic script Standard.Module1.[script name here]
Message: wrong number of parameters! at C:/cygwin64/home/buildslave/source/libo-core/scripting/source/basprov/basscript.cxx:199
Second and third ones run but do nothing.
I really don’t know what to do at this point…
In case anyone wants to see the code (that I copied back from the basic editor):
REM ***** BASIC *****
Sub changeFormulas_Bold_18pt()
doc = ThisComponent
sNames = Array("BaseFontHeight", "FontMathIsBold", "FontFixedIsBold", "FontFunctionsIsBold", "FontNumbersIsBold", "FontSansIsBold", "FontSerifIsBold", "FontTextIsBold", "FontVariablesIsBold")
values = Array(18, True, True, True, True, True, True, True, True)
changeFormulaProperties doc, sNames, values
End Sub
Sub changeFormulas_Regular_12pt()
doc = ThisComponent
sNames = Array("BaseFontHeight", "FontMathIsBold", "FontFixedIsBold", "FontFunctionsIsBold", "FontNumbersIsBold", "FontSansIsBold", "FontSerifIsBold", "FontTextIsBold", "FontVariablesIsBold")
values = Array(12, False, False, False, False, False, False, False, False)
changeFormulaProperties doc, sNames, values
End Sub
Sub changeFormulaProperties(doc, sNames, values)
if doc.supportsService("com.sun.star.formula.FormulaProperties") Then
doc.setPropertyValues(sNames, values)
elseif HasUnoInterfaces(doc, "com.sun.star.drawing.XDrawPageSupplier") Then
obj = doc.getDrawPage()
loopDrawPage obj, sNames, values
elseif HasUnoInterfaces(doc, "com.sun.star.drawing.XDrawPagesSupplier") Then
REM Draw, Impress, Calc
obj = doc.getDrawPages()
loopDrawPages obj, sNames, values
endif
End Sub
Sub loopDrawPages(oDrawPages, sNames, values)
for nDP = 0 to oDrawPages.getCount()-1
oDP = oDrawPages.getByIndex(nDP)
loopDrawPage oDP, sNames, values
next nDP
End Sub
Sub loopDrawPage(oDP, sNames, values)
for nShape = 0 to oDP.getCount()-1
oShape = oDP.getByIndex(nShape)
on error resume next
setShapeModelProperties oShape, sNames, values
next nShape
End Sub
Sub setShapeModelProperties(oShape, sNames, values)
oModel = oShape.Model
sImplementationName = oModel.ImplementationName
if sImplementationName = "com.sun.star.comp.Math.FormulaDocument" then
oModel.setPropertyValues(sNames, values)
endif
End Sub
The callable macros are changeFormulas_Bold_18pt
and changeFormulas_Regular_12pt
. The names describe what they do.
Each of the two call changeFormulaProperties
with parameters describing what should be applied to all the formulas in the given document.
changeFormulaProperties
applies the property values directly in case of a Open Formula Document.
It calls loopDrawPage
in case of a single DrawPage (Writer) passing the DrawPage in question.
It calls loopDrawPages
passing the collection of DrawPages in case of some other document having many DrawPages.
loopDrawPages
calls loopDrawPage
one time per DrawPage passing a single DrawPage with each call.
Finally, loopDrawPage
calls setShapeModelProperties
which actually applies the property values after verifying that a shape actually contains a formula object. With any other kind of shape, the properties would not apply.
Usually a good idea, but at this stage it may be useful to upload a (reduced / shortened) copy of your .odp
(Just to make sure your formulas are no embedded pictures…)
Update, I realized that the reason the code didn’t work was because the formulas were “grouped” with some other objects. Ungrouping and running it seems to have fixed the problem. Huge thanks for that script.
On a slightly unrelated note, I opened a new impress file created a random formula (a simple one, non decimal fraction, with exponents) and copied it 50-100 times. Afterwards I ran the script, for some reason all but one was converted using the script.
And why does a formula with a font size of 18 does not match the same formula size when created with a text box? It need a font size of 10 to match a math formula of 18.
Thank you very much for clarifying what the problem with my code is. I did not consider grouping.
P.S. The fix was easier than I thought. Now the code walks through arbitrary levels of groupings.
One more question on this detail: Is it future safe to use supportsService(“com.sun.star.MyService”) instead of testing for interfaces? I use to think in services rather than interfaces.
Likewise, do you also have any idea as to why there is a discrepancy in font sizes? I set font size to 18, but 18 for text created with the “text box” feature is much larger. What am I missing again?
Right-click the formula object, choose “Original size”.
Thank you, I don’t recall ever using that feature though.
Is this available for 24.2?