Closed bzm3r closed 9 months ago
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
This would be a nice Q&A for tex.stackexchange.com
I've also added an updated version of this code to make4ht sources as an extension.so it will be possible to use it as:
$ make4ht -f html5+inlinecss foo.tex
@michal-h21 You should post your answer here: https://tex.stackexchange.com/questions/663922/make4ht-generating-html-output-but-leaving-the-styling-to-the-user-i-e-don
(and thank you for all your work :)
A nice feature of
make4ht
is that it converts the latex document to HTML, but the awesome feature ofmake4ht
is that it generates all the right images and inserts them in the right places for math. Thepic-m
option in particular is great, and I use all thepic-*
options.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?