1

A nice feature of make4ht is that it converts the latex document to HTML, but the awesome feature of make4ht is that it generates all the right images and inserts them in the right places for math. The pic-m option in particular is great, and I use all the pic-* options.

(see: How do I force `make4ht`/`tex4ht` to output all my mathematics as dvi/svg?)

What I am finding less nice is the CSS generated. Is there a way for the program to generate usefully class names, but then leave all the styling up to the user? I can look at each class, and then write my CSS to handle styling for each class, rather than have an automatic CSS generated?

(this question is a clone of: https://github.com/michal-h21/make4ht/issues/83)

3
  • using images for math makes me so sad, 20+years of fighting for math on the web, and still people find workflows where that is more convenient:( Commented Nov 2, 2022 at 19:57
  • @DavidCarlisle :( yeah...
    – bzm3r
    Commented Nov 2, 2022 at 21:15
  • There is no need to use images for math these days, thanks to software like mathjax which tex4ht/make4ht supports as an option. I have not used image for math for over 4 years now. Also using images makes the final output very large to upload to the server, and it takes longer to build/compile to html page also. I mentioned this before, but I think bzm3r has Latex they can't use mathjax for. But for me, mathjax works great.
    – Nasser
    Commented Nov 3, 2022 at 15:59

1 Answer 1

1

You can disable CSS generation using the -css option. But I don't recommend using it, as TeX4ht can use rules for particular elements, like table rules, colored text, or vertical alignment of pictures from the pic-m option. So you want to use at least these. See also this answer for more details.

I also investigated one more option - use make4ht post-processing filters to insert these specific rules as a style attribute to elements where they apply. The following build file does that, and also removes the link to the CSS file, so you need to add a link to your own CSS.

local domfilter = require "make4ht-domfilter"
local cssquery  = require "luaxml-cssquery"

local logging = require "make4ht-logging"

local log = logging.new("build file")

local cssrules = {}
local cssobj   = cssquery()

local function parse_rule(line)
  local selector, values = line:match("%s*(.-)%s*(%b{})")
  if values then
    values = values:sub(2,-2)
  end
  return selector, values
end

local function join_values(old, new)
  -- correctly joins two attribute lists, depending on the ending
  local separator = ";"
  if not old then return new end
  -- if old already ends with ;, then don't use semicolon as a separator
  if old:match(";%s*$") then separator = "" end
  return old .. separator .. new
end

local function parse_css(filename)
  local css_file = io.open(filename, "r")
  if not css_file then return nil, "cannot load css file: " .. (filename or "") end
  local newlines = {}
  for line in css_file:lines() do
    -- match lines that contain # or =, as these can be id or attribute selectors
    if line:match("[%#%=].-{") then
      -- update attributes for the current selector
      local selector, value = parse_rule(line)
      local oldvalue = cssrules[selector] 
      cssrules[selector] = join_values(oldvalue, value)
    else
      newlines[#newlines+1] = line
    end
  end
  -- we need to add css rules
  for selector, value in pairs(cssrules) do
    cssobj:add_selector(selector, function(dom) end, {value=value})
  end
  css_file:close()
  -- write new version of the CSS file, without rules for ids and attributes
  local css_file = io.open(filename, "w")
  css_file:write(table.concat(newlines, "\n"))
  css_file:close()
  return true
end

-- process the CSS file before everything else
local processed = false
Make:match(".*", function(filename, par)
  if processed then return true end
  processed = true
  local css_file = par.input .. ".css"
  local status, msg = parse_css(css_file)
  if not status then  log:warning(msg) end
end)

-- process the HTML file and insert inline CSS for id and attribute selectors
local process = domfilter {
  function(dom, par)
    -- loop over all elements in the current page
    dom:traverse_elements(function(curr)
      -- remove links to the CSS file generated by TeX4ht
      if curr:get_element_name() == "link" 
        and curr:get_attribute("href"):match("^" .. par.input .. "%.css")
      then
         curr:remove_node()
      end
      -- use CSS object to match if the current element
      -- is matched by id attribute selector
      local matched = cssobj:match_querylist(curr)
      if #matched > 0 then
        -- join possible already existing style attribute with values from the CSS file
        local values = curr:get_attribute("style")
        -- join values of all matched rules
        for _,rule in ipairs(matched) do
          values = join_values(values, rule.params.value)
        end
        curr:set_attribute("style", values)
      end

    end)
    return dom
  end
}

Make:match("html$", process)

Compile your file using:

 $ make4ht -e build.lua filename.tex

I've also added a variant of the above code to make4ht sources, as an inlinecss DOM filter and extension. So in the development version of make4ht, you can use the following command to get inline styles for colors and similar stuff:

 $ make4ht -f html5+inlinecss filename.tex

It doesn't remove link to the CSS file from HTML though, so you will need to remove it manually.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .