Home > Back-end >  Set font family and size of equations in flextable
Set font family and size of equations in flextable

Time:04-10

I'm looking for an option to set the the font family and size of equations in a flextable.

In general the font family and size of the table, rows and columns could be set via the sugar functions flextable::font and flextable::fontsize. However, both have no effect on the font family and size of equations neither in the HTML output nor when exporting to docx.

Running the reprex below gives the correct font family and size for the text column but not for the formula column.

library(flextable)

# Note: Running the reprex requires the `equatags` package. 
# Also equatags::mathjax_install() must be executed
# to install necessary dependencies. See ?flextable::as_equation.

eqs <- c(
  "(ax^2   bx   c = 0)",
  "a \\ne 0",
  "x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}"
)
text = LETTERS[1:3]
df <- data.frame(text = text, formula = eqs)
df
#>   text                                 formula
#> 1    A                     (ax^2   bx   c = 0)
#> 2    B                                a \\ne 0
#> 3    C x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}

ft <- flextable(df)
ft <- compose(
  x = ft, j = "formula",
  value = as_paragraph(as_equation(formula, width = 2))
)
ft <- width(ft, j = 2, width = 2)
ft <- fontsize(ft, size = 20, part = "all")

fn <- tempfile(fileext = ".docx")
save_as_docx(ft, path = fn)
if (FALSE) fs::file_show(fn) # Set to TRUE to show file

CodePudding user response:

To control the row heights, you need to specify hrule(ft, i = 1:3, rule = 'atleast') as well as the height in inches via height_all

ft <- flextable(df)
ft <- compose(
  x = ft, j = "formula",
  value = as_paragraph(as_equation(formula, width = 3, height = 2))
)
ft <- width(ft, j = 1:2, width = 2)
ft <- hrule(ft, i = 1:3, rule = 'atleast')
ft <- height_all(ft, height = 1)
ft <- fontsize(ft, size = 20, part = "all")

Unfortunately, that doesn't change the size of the equations:

enter image description here

The mathjax formulas that make up your second column (including the text characters) are rendered as SVG paths, and both their size and font family are fixed.

If you dig into the flextable code you will see that when you do

  1. print(ft) it calls
  2. flextable:::print.flextable which calls
  3. htmltools_value(ft) , which calls
  4. flextable:::html_str(ft), which calls
  5. flextable:::html_gen(ft), which generates the actual html.

The formula strings are passed directly inside html_gen to equatags::transform_mathjax, which doesn't take any size or font family parameters, and just spits out default mathjax svg. The svg images are incorporated into the table cells at a fixed size.

In order to change the size of the svgs, you would need to get involved in svg hacking, which in the case of simple scaling isn't too difficult:

html_format <- as.character(htmltools_value(ft))
html_format <- gsub('<svg ',
                    '<svg transform=\"scale(2)\" ',
                    html_format, fixed = TRUE)

The html_format object is just the html string of the flextable and can be rendered like this:

dir <- tempfile()
dir.create(dir)
htmlFile <- file.path(dir, "index.html")
writeLines(html_format, con = htmlFile)
rstudioapi::viewer(htmlFile)

Resulting in

enter image description here

None of this is ideal, or course, but it just a limitation of how flextable renders formulas though equatags.

Unfortunately, Mathjax does not allow for arbitrary fonts to be used, so that would be even harder to achieve.

  • Related