From c332fb0ced3affd7fa1d93fed75108915db3cb7f Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 7 Sep 2020 21:24:02 +0000 Subject: tex4ebook (7sep20) git-svn-id: svn://tug.org/texlive/trunk@56290 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/support/tex4ebook/README | 4 +- .../texmf-dist/doc/support/tex4ebook/changelog.tex | 54 ++++++++++ Master/texmf-dist/doc/support/tex4ebook/readme.tex | 9 +- .../doc/support/tex4ebook/tex4ebook-doc.pdf | Bin 78439 -> 79364 bytes Master/texmf-dist/scripts/tex4ebook/tex4ebook | 8 +- .../scripts/tex4ebook/tex4ebook-exec_azw.lua | 35 +++++++ .../scripts/tex4ebook/tex4ebook-exec_azw3.lua | 35 +++++++ .../scripts/tex4ebook/tex4ebook-exec_epub.lua | 113 +++++++++++++++++++++ .../texmf-dist/tex/latex/tex4ebook/tex4ebook.4ht | 10 +- .../texmf-dist/tex/latex/tex4ebook/tex4ebook.sty | 4 +- 10 files changed, 256 insertions(+), 16 deletions(-) create mode 100755 Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua create mode 100755 Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/support/tex4ebook/README b/Master/texmf-dist/doc/support/tex4ebook/README index 796445674a2..3634974ab82 100644 --- a/Master/texmf-dist/doc/support/tex4ebook/README +++ b/Master/texmf-dist/doc/support/tex4ebook/README @@ -81,7 +81,7 @@ But it is optional. You shouldn't need to modify your \TeX\ files `-f,--format (default epub)` -: Output format. Possible values are `epub`, `epub3` and `mobi`. +: Output format. Possible values are `epub`, `epub3`, `mobi`, `azw` and `azw3`. `-j,--jobname` @@ -304,7 +304,7 @@ Type - WARNING: filename.epub: item (OEBPS/foo.boo) exists in the zip file, but is not declared in the OPF file - Delete the `filename-(epub|epub3|mobi)` folder and `filename.epub`. Then + Delete the `filename-(epub|epub3|mobi|azw|azw3)` folder and `filename.epub`. Then run `tex4ebook` again. - WARNING(ACC-009): hsmmt10t.epub/OEBPS/hsmmt10tch17.xhtml(235,15): diff --git a/Master/texmf-dist/doc/support/tex4ebook/changelog.tex b/Master/texmf-dist/doc/support/tex4ebook/changelog.tex index 4cb5c8c7ca9..f77423e85b7 100644 --- a/Master/texmf-dist/doc/support/tex4ebook/changelog.tex +++ b/Master/texmf-dist/doc/support/tex4ebook/changelog.tex @@ -2,6 +2,60 @@ \section{Changes}\label{changes}} \begin{itemize} +\item + 2020/09/07 + + \begin{itemize} + \tightlist + \item + released version \texttt{0.3b} + \end{itemize} +\item + 2020/08/26 + + \begin{itemize} + \tightlist + \item + fixed hiearchical structure in NCX TOC for chapters in backmatter + and appendix + \item + load \texttt{common\_domfilters} extension by default. + \end{itemize} +\item + 2020/07/09 + + \begin{itemize} + \tightlist + \item + addded \texttt{AZW} and \texttt{AZW3} format support. + \end{itemize} +\item + 2020/06/21 + + \begin{itemize} + \tightlist + \item + save \texttt{\textbackslash{}title} element + \item + save contents of \texttt{\textbackslash{}author} in macro directly + \end{itemize} +\item + 2020/06/15 + + \begin{itemize} + \tightlist + \item + remove child elements from elements that don't allow them in the OPF + and NCX file. + \end{itemize} +\item + 2020/03/14 + + \begin{itemize} + \tightlist + \item + explicitly list supported section types in the NCX table + \end{itemize} \item 2019/11/01 diff --git a/Master/texmf-dist/doc/support/tex4ebook/readme.tex b/Master/texmf-dist/doc/support/tex4ebook/readme.tex index 13b064bf31d..0fdb16c1c91 100644 --- a/Master/texmf-dist/doc/support/tex4ebook/readme.tex +++ b/Master/texmf-dist/doc/support/tex4ebook/readme.tex @@ -92,8 +92,8 @@ Specify make4ht build file\footnote{\url{https://github.com/michal-h21/make4ht\# Defaulf build file filename is \texttt{filename.mk4}, use this option if you use different filename. \item[\texttt{-f,-\/-format\ (default\ epub)}] -Output format. Possible values are \texttt{epub}, \texttt{epub3} and -\texttt{mobi}. +Output format. Possible values are \texttt{epub}, \texttt{epub3}, +\texttt{mobi}, \texttt{azw} and \texttt{azw3}. \item[\texttt{-j,-\/-jobname}] Specify the output file name, without file extension. \item[\texttt{-l,-\/-lua}] @@ -371,8 +371,9 @@ issues:}\label{common-validation-issues}} but is not declared in the OPF file \end{itemize} -Delete the \texttt{filename-(epub\textbar{}epub3\textbar{}mobi)} folder -and \texttt{filename.epub}. Then run \texttt{tex4ebook} again. +Delete the +\texttt{filename-(epub\textbar{}epub3\textbar{}mobi\textbar{}azw\textbar{}azw3)} +folder and \texttt{filename.epub}. Then run \texttt{tex4ebook} again. \begin{itemize} \item diff --git a/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-doc.pdf b/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-doc.pdf index 1f956367135..942a92df29c 100644 Binary files a/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-doc.pdf and b/Master/texmf-dist/doc/support/tex4ebook/tex4ebook-doc.pdf differ diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook b/Master/texmf-dist/scripts/tex4ebook/tex4ebook index ebd7485c2d1..dc602c4e72b 100755 --- a/Master/texmf-dist/scripts/tex4ebook/tex4ebook +++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook @@ -23,7 +23,7 @@ local tex4ht_sty_par="" local tex4ht_par="" local t4ht_par="" local latex_par="" -local output_formats={epub=true,mobi=true,epub3=true} +local output_formats={epub=true,mobi=true,epub3=true,azw=true, azw3=true} local executor=nil local tidy = false local include_fonts = false @@ -67,7 +67,7 @@ else end if args.version then - print "tex4ebook v0.3a" + print "tex4ebook v0.3b" return end @@ -129,7 +129,9 @@ log:status("Input file: ".. params.tex_file) local output_format = params.output_format -- use epub as default output_format output_format = output_format or "epub" -local extensions = ebookutils.load_extensions(params.extensions, output_format) +-- load common_domfilters extension by default +local extensions = ebookutils.add_extensions("+common_domfilters", params.extensions) +extensions = ebookutils.load_extensions(extensions, output_format) -- but also support tex4ebook!s own parameters local oldparams = { -- htlatex=latex_cmd diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua new file mode 100755 index 00000000000..397292b648b --- /dev/null +++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw.lua @@ -0,0 +1,35 @@ +module(...,package.seeall) +local eb = require("tex4ebook-exec_epub") +local ebookutils = require("mkutils") +local log = logging.new "exec_azw" + +function prepare(params) + return eb.prepare(params) +end + +function run(out,params) + return eb.run(out, params) +end + +function writeContainer() + local ret = eb.writeContainer() + -- convert the epub file to azw + local epubpath = eb.basedir .. "/" .. eb.outputfile + + -- find the azw filename + local azwfile = eb.outputfile:gsub("epub$", "azw") + local azwdist = eb.destdir .. azwfile + local command = "kindlegen " .. epubpath .. " -o " .. azwfile + log:info("Pack azw ".. command) + local status, output = ebookutils.execute(command) + -- copy the azw file to the destination directory + -- the destination directory will be created by the epub writer, so it is possible to use + -- the cp function which doesn't try to create directory + ebookutils.cp(eb.basedir .. "/" .. azwfile, azwdist) + + return ret +end + +function clean() + return eb.clean() +end diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua new file mode 100755 index 00000000000..33e8a1182c5 --- /dev/null +++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_azw3.lua @@ -0,0 +1,35 @@ +module(...,package.seeall) +local eb = require("tex4ebook-exec_epub") +local ebookutils = require("mkutils") +local log = logging.new "exec_azw" + +function prepare(params) + return eb.prepare(params) +end + +function run(out,params) + return eb.run(out, params) +end + +function writeContainer() + local ret = eb.writeContainer() + -- convert the epub file to azw + local epubpath = eb.basedir .. "/" .. eb.outputfile + + -- find the azw filename + local azwfile = eb.outputfile:gsub("epub$", "azw3") + local azwdist = eb.destdir .. azwfile + local command = "kindlegen " .. epubpath .. " -o " .. azwfile + log:info("Pack azw ".. command) + local status, output = ebookutils.execute(command) + -- copy the azw file to the destination directory + -- the destination directory will be created by the epub writer, so it is possible to use + -- the cp function which doesn't try to create directory + ebookutils.cp(eb.basedir .. "/" .. azwfile, azwdist) + + return ret +end + +function clean() + return eb.clean() +end diff --git a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua index 52e2ab6134d..b0ccee62027 100755 --- a/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua +++ b/Master/texmf-dist/scripts/tex4ebook/tex4ebook-exec_epub.lua @@ -5,6 +5,7 @@ local io = require("io") local log = logging.new("exec_epub") --local ebookutils = require("ebookutils") local ebookutils = require "mkutils" +local dom = require("luaxml-domobject") local outputdir_name="OEBPS" local metadir_name = "META-INF" local mimetype_name="mimetype" @@ -319,11 +320,123 @@ function pack_container() ebookutils.cp(basedir .."/"..outputfile, destdir .. outputfile) end +local function update_file(filename, fn) + -- update contents of a filename using function + local f = io.open(filename, "r") + local content = f:read("*all") + f:close() + local newcontent = fn(content) + local f = io.open(filename, "w") + f:write(newcontent) + f:close() +end + +local function fix_ncx_toc_levels(dom) + -- OK, this is a weird hack. The problem is that when \backmatter + -- follows \part, the subsequent chapters are listed under part + -- in the NCX TOC + -- I've added special element to the ncx file to detect mark numbers. + -- chapters in backmatter should have empty mark number + + -- get current section type and mark number + local get_navpoint_info = function(navpoint) + local navmarks = navpoint:query_selector("navmark") + if navmarks and #navmarks > 0 then + -- we are interested only in the first navmark, because it contains the current navPoint info + local navmark = navmarks[1] + return navmark:get_attribute("type"), navmark:get_text() + end + return nil, "Cannot find navLabel" + end + + local fix_chapters = function(part) + -- move chapters from backmatter and appendix from the current part + -- find part position in the element list, it will be place where backmatter will be moved + local part_pos = part:find_element_pos() + 1 + local part_parent = part:get_parent() + -- child chapters + local children = part:get_children() + -- loop over children from back, where backmatter or appendix may be placed + for i = #children, 1, -1 do + local current = children[i] + local sect_type, mark = get_navpoint_info(current) + if sect_type then + -- remove spaces from mark + mark = mark:gsub("%s", "") + if sect_type == "appendix" or (sect_type == "chapter" and mark=="") then + -- move chapter at the same level as part, after part + -- the correct order will be kept, because we move from the back of the node list + -- and every new node is placed before previous added nodes + part_parent:add_child_node(current:copy_node(), part_pos) + current:remove_node() + else + -- break processing if we find normal chapter + break + end + end + end + end + + -- find the last part in the ncx table. it can contain incorrectly nested chapters + local parts = {} + for _, navpoint in ipairs(dom:query_selector("navMap navPoint")) do + -- we are not able to match just direct navPoint ancestors, so we will use this trick + if navpoint:get_parent():get_element_name() == "navMap" then + local sec_type, navmark = get_navpoint_info(navpoint) + if sec_type == "part" then table.insert(parts, navpoint) end + end + end + if #parts > 0 then + -- fix chapters in the last part + fix_chapters(parts[#parts]) + end + return dom +end + +local function clean_xml_files() + local opf_file = outputdir .. "/content.opf" + update_file(opf_file, function(content) + -- remove wrong elements from the OPF file + -- open opf file and create LuaXML DOM + local opf_dom = dom.parse(content) + -- remove child elements from elements that don't allow them + for _, el in ipairs(opf_dom:query_selector("dc|title, dc|creator")) do + -- get text content + local text = el:get_text() + -- replace element text with a new text node containing original text + el._children = {el:create_text_node(text)} + end + return opf_dom:serialize() + end) + local ncxfilename = outputdir .. "/" .. outputfilename .. ".ncx" + update_file(ncxfilename, function(content) + -- remove spurious spaces at the beginning + content = content:gsub("^%s*","") + local ncx_dom = dom.parse(content) + fix_ncx_toc_levels(ncx_dom) + -- remove child elements from element + for _, el in ipairs(ncx_dom:query_selector("text")) do + local text = el:get_text() + -- replace element text with a new text node containing original text + el._children = {el:create_text_node(text)} + end + for _, el in ipairs(ncx_dom:query_selector("navPoint")) do + -- fix attribute names. this issue is caused by a LuaXML behavior + -- that makes all attributes lowercase + el._attr["playOrder"] = el._attr["playorder"] + el._attr["playorder"] = nil + end + return ncx_dom:serialize() + end) + +end function writeContainer() make_opf() + clean_xml_files() pack_container() end + local function deldir(path) for entry in lfs.dir(path) do if entry~="." and entry~=".." then diff --git a/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.4ht b/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.4ht index e623ac8bc24..6ee87ed3aeb 100644 --- a/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.4ht +++ b/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.4ht @@ -157,7 +157,7 @@ href="#1" media-type="\a:CoverMimeType" />}} "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">\Hnewline}} %Get sanitized value of \title -%\def\Title{\Ref{TITLE+}} +\ifTag{TITLE+}{\def\Title{\LikeRef{TITLE+}}}{} % If title contains macros, SafeTitle should be configured % in the custom cfg file \NewConfigure{SafeTitle}[1]{\gdef\Title{#1}} @@ -255,7 +255,7 @@ href="#1" media-type="\a:CoverMimeType" />}} \def\navsection#1#2{ \ConfigureToc{#1}% {\expandafter\closelevels\expandafter{#2} - \a:NavSection\Ncx:Mark} + \def\curr:sect:type{#1}\a:NavSection\Ncx:Mark} {\c:NavSection} {} {\b:NavSection% @@ -361,16 +361,16 @@ href="#1" media-type="\a:CoverMimeType" />}} \Configure{toTocLink}{}{}% \Configure{NavSection}{\booltrue{tocnoempty}\HCode{\Hnewline\Hnewline\Hnewline}% + \the\navpoint\HCode{">\Hnewline\Hnewline}% }{\HCode{\Hnewline% \Hnewline}% \HCode{}% -}{ }{\HCode{\Hnewline}} +}{\HCode{}}{\HCode{\Hnewline}} % Meta inf \ncx:head % Book title \ncx:title -\tableofcontents%[part,chapter,likechapter,section,likesection,subsection,likesubsection]% +\tableofcontents[part,appendix,chapter,likechapter,appendixsec,section,likesection,appendixsubsec,subsection,likesubsection]% %Hack to get close tag working \HCode{} \EndNoFonts diff --git a/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.sty b/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.sty index 27a46b756ec..1b0114748c9 100644 --- a/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.sty +++ b/Master/texmf-dist/tex/latex/tex4ebook/tex4ebook.sty @@ -144,12 +144,12 @@ \let\tf@orig@author\author \newcommand\tf@author[1]{% \tf@orig@author{#1}% - \let\Author\@author% + \def\Author{#1}% } \newcommand\tf@optauthor[2][]{% \tf@orig@author[#1]{#2}% - \let\Author\@author% + \def\Author{#2}% } % support optiona argument for \author as well -- cgit v1.2.3