3

I'm using make4ht to convert a document to odt, and I'd like the underlying content.xml to be in utf-8 encoding. I'm using the u option of make4ht:

make4ht -uf odt filename.tex

Consider the following document:

\documentclass{article}

\usepackage[utf8]{inputenc}

\begin{document}

Hello World!!!

áéíóúâêîôûüãõç.

\end{document}

The resulting .odt is displayed correctly, but the underlying content.xml renders the accented characters as:

<text:p text:style-name="First-line-indent">   &#xE1;&#xE9;&#xED;&#xF3;&#xFA;&#xE2;&#xEA;&#xEE;&#xF4;&#xFB;&#xFC;&#xE3;&#xF5;&#xE7;.
   </text:p>

(even though the UTF-8 header is in place: <?xml version="1.0" encoding="UTF-8"?>).

With:

htlatex filename.tex "xhtml,ooffice,charset=utf-8" " -cmozhtf -utf8" " -coo"

I do get a proper utf-8 encoded content.xml. I also tried to pass these same arguments to make4ht, to no avail. What should I do to convince make4ht to deliver an utf-8 encoded .odt output?

1 Answer 1

4

Edit: The development version of make4ht now supports filters in the ODT output, so it is no longer necessary to update the ODT files using zip methods.

Simplified build file can look like this:

local filter = require "make4ht-filter"
local utfchar = unicode.utf8.char
local process =  filter {
  function(content)
    return content:gsub("%&%#x([A-Fa-f0-9]+);", function(entity)
      -- convert hexadecimal entity to Unicode
      print(entity,utfchar(tonumber(entity, 16)))
      return utfchar(tonumber(entity, 16))
    end)
  end
}

Make:match("4oo$", process)

It is just necessary to use temporary file names produced by tex4ht, so instead of content.xml it is necessary to process file with a .4oo extension, which contains the document text.


Original answer:

Unicode characters in content.xml are escapes as XML entities by xtpipes command, which post-process the file in order to fix some issues regarding to math and sections. xtpipes can be requested from t4ht command using -cooxtpipes option, make4ht uses this option by default for the ODT output.

If you use the same arguments as for htlatex and ommit xtpipes, make4ht will produce identical result, with Unicode characters:

make4ht sample.tex "xhtml,ooffice" " -cmozhtf -utf8" " -coo"

<text:p text:style-name="First-line-indent">   áéíóúâêîôûüãõç.

But I would advise against disabling xtpipes, because you can end with invalid ODT file.

Instead, it is possible to convert the entities to Unicode using make4ht build file:

local mkutils = require "mkutils"
local zip = require "zip"
local utfchar = unicode.utf8.char


-- use function to change contents of the ODT file
local function update_odt(odtfilename, file_path, fn)
  -- get name of the odt file
  local odtname = mkutils.remove_extension(odtfilename) .. ".odt"
  -- open and read contents of the requested file inside ODT file
  local odtfile = zip.open(odtname)
  local local_file = odtfile:open(file_path)
  local content = local_file:read("*all")
  local_file:close()
  odtfile:close()
  -- update the content using user function
  content = fn(content)
  -- write the updated file
  local local_file_file  = io.open(file_path,"w")
  local_file_file:write(content)
  local_file_file:close()
  os.execute("zip " .. odtname .. " " .. file_path)
  os.remove(file_path)
end

Make:match("tmp$", function(name, par)
  update_odt(name, "content.xml", function(content)
    return content:gsub("%&%#x([A-Fa-f0-9]+);", function(entity)
      -- convert hexadecimal entity to Unicode
      print(entity,utfchar(tonumber(entity, 16)))
      return utfchar(tonumber(entity, 16))
    end)
  end)
end)

Becase the ODT file is zipped in the same step as xtpipes are called, it is necessary to open the ODT file, read content.xml from it and then pack again.

The content seems to be correct then:

<text:p text:style-name="First-line-indent">   áéíóúâêîôûüãõç.
22
  • 1
    @gusbrs the -u option is not required, Unicode output is used implicitly in the ODT mode.
    – michal.h21
    Commented Jun 6, 2018 at 21:02
  • 1
    @gusbrs NoFonts will disable font formatting for font switches like \huge, \tiny or \bfseries. all font changing commands must be properly configured to produce some stylled element. It really depends on your document if it causes any issues, but if you use only standard commands, it should be OK.
    – michal.h21
    Commented Jun 6, 2018 at 21:05
  • 1
    @gusbrs yes, special configuration file must exist for each font, it is quite possible that some less commons fonts may contain bugs in these configuraton files
    – michal.h21
    Commented Jun 6, 2018 at 21:20
  • 1
    @gusbrs I think you got another error before this one, because it seems that content.xml is missing. it is necessary that config file exists for all fonts, so some is obviously missing even for T1 encoding.
    – michal.h21
    Commented Jun 7, 2018 at 19:13
  • 2
    @gusbrs the development version of make4ht now supports simplified method of filtering of the text.
    – michal.h21
    Commented Jun 13, 2018 at 9:03

You must log in to answer this question.

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