hughjonesd / huxtable

An R package to create styled tables in multiple output formats, with a friendly, modern interface.
http://hughjonesd.github.io/huxtable
Other
321 stars 28 forks source link

Use fontspec for cross-platform font names #105

Closed markbneal closed 5 years ago

markbneal commented 5 years ago

Describe what is missing huxtable has some sweet options for font formatting that works great into html. However, these don't carry over as well to pdf. Changing mainfont in pdf (through rmarkdown option) carries over to the huxtable only if no options are selected.

Describe your proposed solution Ideally we carry the same fonts over to the pdf. This might require specification of those fonts with fontspec http://mirror.aut.ac.nz/CTAN/macros/latex/contrib/fontspec/fontspec.pdf and/or handy hints from here https://tex.stackexchange.com/a/461262. kable/kableExtra has an environment that allows a specific font to be used for the table, though only one font per table as far as I can tell, see https://stackoverflow.com/questions/55280203/rmarkdown-different-font-types-in-table-using-kable-or-huxtable-output-to-pdf

Target audience Everyone who wants a different font for table(s) than the main font, or control over fonts within the table.

Additional context Here's an example comparing kable and huxtable taking font from mainfont, except where it was specified by options in huxtable. image

tabletest.zip

hughjonesd commented 5 years ago

Seems there are two issues here:

  1. Font names differ between TeX and HTML.
  2. huxtable ignores "mainfont".

I think I'd rather fix 1... than 2. I'd welcome a pull request if you can show how to use fontspec to enable "standard" font names.

markbneal commented 5 years ago

I'm getting well out of my depth now, until very recently I thought latex was a material for making gloves! Back to the topic: Is it that font names vary or that they get referred to with different syntax? If the latter, would a work around be something like the helper function I altered to make consistent references to hex colours across pdf and html output? https://stackoverflow.com/a/55270844/4927395 Maybe I should stackoverflow a question on that.

hughjonesd commented 5 years ago

A helper function relies on knowing a list of font names in TeX and their translations. Using the fontspec library seems a better way to go.

markbneal commented 5 years ago

Is there a short term back door/alternative workflow? Create the html table and send the image to the pdf. I think I saw some reference to a package that did that or the reverse (pdf/latex image to html), but can't find the reference now.

hughjonesd commented 5 years ago

A helper function would indeed be a workaround.

hughjonesd commented 5 years ago

Could you do me a favour and try out the latest change?

install_github("hughjonesd/huxtable")

If you set options(huxtable.latex_use_fontspec = TRUE) you will then be able to use portable font names in your tables. You will also need to compile PDFs using xelatex. You can do something like:

output:
   pdf_document:
     latex_engine: xelatex

in rmarkdown headers.

This is an experimental change, so I'd like to know how you get on.

markbneal commented 5 years ago

Thanks, you are a legend! It appears to be working sweetly now. I first got an error when I used the filename for Arial with a lower case a (as in arial.ttf, the filename). The key is to use the name as it appears in the description (e.g. as you see it when you open the c:\Windows\fonts\ folder), which usually appears to be capitalized. So, assume everything related to font names is case sensitive, and check the font name (not filename).

Font name, not filename huxtable font not found huxtable font working

markbneal commented 5 years ago

I've very recently learned more than I ever wanted to know about fonts.

Current table behaviour is that if you specify a font (e.g. for a row), and the font is available on your computer (e.g. c:\windows\fonts), then you will get what you want in the pdf, and the rstudio browser - Huzzah! However, if you open in your browser such as chrome (or someone else's), you will get some default. I'm not sure how this default is set - does it come from huxtable? As an aside, if I specify no font, I seem to get a default sans-serif font, all fonts and fallback fonts and families in my css file are sans serif.

For example, if I specify Agenda, which is sans serif, but my chrome browser doesn't have it (1). It isn't available there, so you get a default, which surprisingly ends up being a serif font.

So, if the default/fallback font does come from huxtable (or should), how would you specify it? If it doesn't, any ideas on where it should be set?

(1) If your specific font was freely available (e.g. check on "google fonts") you could force the browser to download it through code in the css style file (in style.css with a line like this: @import url('https://fonts.googleapis.com/css?family=Open+Sans');) which you would include by reference to the style.css file in the yaml.

markbneal commented 5 years ago

I checked the html in the browser where it tries to render the table, and it has: font-family: Agenda; Does huxtable need to pass something more complex like the fallbacks? Not sure how this would make sense coded in R, but something like this? font(ht)[1,] <- Agenda, "Source Sans Pro", sans-serif;

or alternatively, provide the fallback via the css style file? I'm not sure what the object is, but similar to how this link provides font family to .flat-table https://stackoverflow.com/a/49903625/4927395

.flat-table {
    display: block;
    font-family: sans-serif;
    -webkit-font-smoothing: antialiased;
    font-size: 115%;
    overflow: auto;
    width: auto;
  }
hughjonesd commented 5 years ago

Hi Mark, I don’t plan to support multiple fonts in huxtable for now. What you suggest might work. Meanwhile I will close this issue.

markbneal commented 5 years ago

Ok, solution for the fallback fonts. This makes the header row of your table Agenda, but if that font is not available, gives you control of the fallback fonts. font(ht)[1,] <- paste0("Agenda, \"Source Sans Pro\", sans-serif") Hat tip from https://stackoverflow.com/a/16761603/4927395

n.b. Changing defaults for the object didn't work (my other idea in the post above). Still no idea why it defaulted to a serif font.

markbneal commented 5 years ago

I've recently upgraded R, packages and related applications and now the fallback fonts no longer work with (latex?) output from rmarkdown to pdf. I thought it was a fontspec issue as per error message (see first pic), where it no longer accepts the string with fallbacks, though the .tex file looks ok (second pic) - maybe the problem is later with kpathsea which is a file in the latex distribution.

image

image

hughjonesd commented 5 years ago

Check if you’re still using xetex; and try with a single font instead of the comma-separated list. -- Sent from Gmail Mobile

markbneal commented 5 years ago

Single fonts are fine. e.g.: font(ht)[1,] <- "Agenda" The issue is the ability to use the same code with fallback fonts, which you do for html output that is robust to different font availability, that also knits to pdf without errors. Looking for feedback at rstudio community: rmarkdown-fallback-fonts-not-working-consistently-across-output-to-pdf-and-html

hughjonesd commented 5 years ago

xetex? Other system data? -- Sent from Gmail Mobile