`make4ht`:生成 HTML 输出,但将样式留给用户(即不制作 CSS?)

`make4ht`:生成 HTML 输出,但将样式留给用户(即不制作 CSS?)

的一个不错的功能make4ht是它将乳胶文档转换为 HTML,但惊人的的功能make4ht是它可以生成所有正确的图像并将它们插入到正确的位置进行数学运算。这个pic-m选项特别棒,我使用了所有pic-*选项。

(看:我如何强制“make4ht”/“tex4ht”将所有数学运算输出为 dvi/svg?

我觉得不太好的是生成的 CSS。有没有办法让程序生成有用的类名,然后将所有样式留给用户?我可以查看每个类,然后编写 CSS 来处理每个类的样式,而不是自动生成 CSS?

(该问题是:https://github.com/michal-h21/make4ht/issues/83

答案1

您可以使用以下方式禁用 CSS 生成-css选项。但我不建议使用它,因为 TeX4ht 可以使用选项中特定元素的规则,如表格规则、彩色文本或图片的垂直对齐pic-m。所以你至少要使用这些。另请参阅这个答案更多细节。

我还研究了另一个选项 - 使用make4ht后处理过滤器将这些特定规则作为style属性插入到它们适用的元素中。以下构建文件执行此操作,同时删除指向 CSS 文件的链接,因此您需要添加您自己的 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)

使用以下方法编译您的文件:

 $ make4ht -e build.lua filename.tex

我还将上述代码的变体添加到make4ht源中,作为inlinecssDOM 过滤器和扩展。因此,在 的开发版本中make4ht,您可以使用以下命令获取颜色和类似内容的内联样式:

 $ make4ht -f html5+inlinecss filename.tex

但是它不会从 HTML 中删除 CSS 文件的链接,因此您需要手动将其删除。

相关内容