我有两列 html 输出,一列是文本,另一列是要导航的目录。但是,我的完整目录有 100 个条目,因此很混乱。我怎样才能只获取每个部分的 minitoc,或者更好地查看所有部分的列表,并且只查看当前查看部分的详细目录。以下是我的代码。
因此,在第 1 部分中,左侧目录应显示 P1、C1、C2、S1、S2、P2、P3。在第 2 部分中,它应显示 P1、P2、C12、C22、S12、S22、P3。
\documentclass[12pt,a4paper,notitlepage,twoside]{book}%
\usepackage{minitoc}
\begin{document}
\addcontentsline{toc}{part}{Start}
\dominitoc
\doparttoc
START
\part{P1}
\chapter{C1}
\chapter{C2}
\section{S1}
\section{S2}
\part{P2}
\chapter{C12}
\chapter{C22}
\section{S12}
\section{S22}
\part{P3}
\end{document}
和 cfg 文件:
\Preamble{xhtml,mathml}
\Configure{VERSION}{}
\Configure{DOCTYPE}{\HCode{<!DOCTYPE html>\Hnewline}}
\Configure{HTML}{\HCode{<html>\Hnewline}}{\HCode{\Hnewline</html>}}
\Configure{@HEAD}{\HCode{
<link type="text/css" rel="stylesheet" href="protex/style.css" />\Hnewline %Eigenes Stylesheet für notwendige Anpassungen.
}}
%Einfügen der Navigationssidebar/des Inhaltsverzeichnisses auf jeder Seite
\Configure{@BODY}{\HCode{<div class="mainnavigation"><a href="http://dynamische-vwl.de/"><img src="protex/images/logo.png" /></a>}\TableOfContents\HCode{</div>}}
% Der gesamte Text wird in das Blockelement "textkoerper" gepackt, um ihn sauber vom Inhaltsverzeichnis trennen zu können.
\Configure{@BODY}{\HCode{<div class="textkoerper">}}
\CutAt{part,likepart,appendix}
\CutAt{chapter,appendix,part,likepart}
% \Configure{endchapter}{chapter,section}
\CutAt{section,likesection}
\CutAt{subsection,likesubsection}
\Configure{paragraph}{}{}{\HCode{<div class="paragraphHead">}}{\HCode{</div>}}
\TocAt{chapter,section}
% \def\Tocchapter{\TableOfContents[chapter]}
\TocAt{section,subsection}
\begin{document}
\EndPreamble
and the css
body {
background: #f1f1f1 url("protex/images/bg.png") repeat;
font: normal 12px/21px Arial, Helvetica, sans-serif;
color: #404040;
}
/*div.partTOCS{
width: 25%;
float:left;
margin-left:-25%;
}
div.chapterTOCS{
width: 25%;
float:left;
margin-left:-25%;
}
div.sectionTOCS{
width: 25%;
float:left;
margin-left:-25%;
}*/
div.mainnavigation{
width: 20%;
float:left;
margin-left:5%;
background: #333;
color: #ececec;
padding-left:1%;
padding-right:1%;
padding-top:2%;
padding-bottom:2%;
margin-bottom:2%;
/* margin-right:5%; */
}
div.mainnavigation a{
color: #ececec;
}
div.textkoerper{
margin-left:27%;
width: 66%;
background: #f9f9f9;
padding-left:2%;
padding-top:2%;
padding-right:2%;
border-bottom: 1px solid #e7e5e5;
border-top-right-radius: 4px;
}
div#fusszeile{
/* float:left; */
}
答案1
这个任务可以通过以最简单的方式对 HTML 输出进行后处理来解决。make4ht
,构建系统以tex4ht
支持使用外部实用程序或使用函数修改输出 HTML 文件Lua
。
开发版本LuaXML,尚未在 CTAN 上发布,包含简单的 DOM 类库,可用于简单的 HTML 操作。我将首先发布完整的构建文件,稍后再发布一些评论。将构建文件命名为mybuild.mk4
:
local domobject = require "luaxml-domobject"
local filter = require "make4ht-filter"
-- return toc element type and it's id
local function get_id(el)
local name = el:get_attribute "class"
local a = el:query_selector "a" or {}
local first = a[1]
local href = first:get_attribute "href"
local id = href:match("#(.+)$")
return name, id
end
local function remove_sections(part_elements, currentpart)
-- we need to remove toc entries from the previous part if the
-- current document isn't part of it
if currentpart == false then
for _, part in ipairs(part_elements) do
part:remove_node()
end
end
end
local process = filter{ function(s)
local dom = domobject.parse(s)
-- search sectioning elements
local titles = dom:query_selector(".partHead a, .chapterHead a, .sectionHead a")
local section_ids = {}
for _, x in ipairs(titles) do
-- get their id attributes and save them in a table
section_ids[#section_ids+1] = x:get_attribute("id")
end
-- we need to retrieve the first table of contents
local toctables = dom:query_selector(".tableofcontents") or {}
-- process only when we got a TOC
if #toctables > 0 then
local tableofcontents = toctables[1]
-- all toc entries are in span elements
local toc = tableofcontents:query_selector("span")
local currentpart = false
local part_elements = {}
for _, el in ipairs(toc) do
-- get sectioning level and id of the current TOC entry
local name, id = get_id(el)
-- change span to div
el._name = "div"
if name == "partToc" then
remove_sections(part_elements,currentpart)
-- resert toc list
currentpart = false
part_elements = {}
else
-- add child elements of part to table
part_elements[#part_elements+1] = el
end
for _, sectid in ipairs(section_ids) do
-- detect if the current TOC entry match some sectioning element in the current document
if id == sectid then
currentpart = true
print("match", id)
end
end
end
-- remove sections from the last part
remove_sections(part_elements,currentpart)
-- remove unneeded br elements
local br = tableofcontents:query_selector("br")
for _, el in ipairs(br) do el:remove_node() end
-- remove unneded whitespace
for _, el in ipairs(tableofcontents:get_children()) do
if el:is_text() then el:remove_node() end
end
end
return dom:serialize()
end }
Make:match("html$", process)
使用以下方式编译文档
make4ht -c configname.cfg -e mybuild.mk4 filename.tex
其结果如下:
现在进行一些解释:
DOM 库在 中被命名"luaxml-domobject"
。最重要的功能是domobject:query_selector
它在 DOM 中搜索 CSS 查询并返回包含所有匹配元素的表。因此,如果您想搜索所有可能具有chapterHead
类的章节命令,那么您可以使用
domobject:query_selector(".chapterHead")
它将选择当前页面内的所有章节。我们使用更高级的选择器来获取页面中所有指向分段命令的链接,使用
local titles = dom:query_selector(".partHead a, .chapterHead a, .sectionHead a")
链接存储在元素id
的属性中a
,该元素是分段元素的子元素。我们使用这些 ID 来检查 TOC 元素是否链接到当前页面。
流程如下:
我们循环遍历所有 TOC 元素,检查它是否链接到当前页面或某个不同部分,如果链接到当前页面,则设置布尔变量。当当前元素是部分时,我们检查布尔变量是否为 false,因此前一部分中的章节和节链接到不同的部分。在这种情况下,我们删除所有指向节和章节的链接。然后我们进行更多清理,结果是 TOC 仅包含指向当前部分节和其他部分的链接。
最后一步,我们可以使用 将其保存回文本形式domobject:serialize
。我们使用make4ht-filter
库加载 HTML 文件,调用我们的处理函数并将结果保存回 HTML 文件。使用以下方法在所有生成的 HTML 文件上调用该过程:
Make:match("html$", process)