diff options
Diffstat (limited to 'macros/plain/contrib/pitex/sections.ptx')
-rw-r--r-- | macros/plain/contrib/pitex/sections.ptx | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/macros/plain/contrib/pitex/sections.ptx b/macros/plain/contrib/pitex/sections.ptx new file mode 100644 index 0000000000..a6d1f95431 --- /dev/null +++ b/macros/plain/contrib/pitex/sections.ptx @@ -0,0 +1,332 @@ +\newcount\ptx@penalty +\ptx@penalty=-10000 + +\def\newbreakpenalty#1{% + \advance\ptx@penalty-1 + \edef#1{\the\ptx@penalty\relax} + } + +\newbreakpenalty\clearpagepenalty +\def\clearpage{\vfil\penalty\clearpagepenalty} + +\newbreakpenalty\breakpagepenalty +\def\breakpage{\vfil\penalty\breakpagepenalty} + +\def\whitepage{\clearpage\shipout\hbox{}\advancepageno} + +% TODO: Rewrite in Lua. +\def\needspace#1{% + \par\penalty0 + \ifdim\dimexpr\pagegoal-\pagetotal<\dimexpr#1\relax + \breakpage + \fi + } + +\def\iflines#1{% + \par\penalty0 + \ifdim\dimexpr(\pagegoal-\pagetotal) < \numexpr(#1)\baselineskip + \expandafter\secondoftwo + \else + \expandafter\firstoftwo + \fi} + +\long\def\ignorepars#1{% + \ifxnextnospace\par + {\gobbleoneand{\ignorepars{#1}}} + {#1}% + } + +\def\sectioncommand#1#2#3{% + \ifnext[ + {\ptx@sectioncommand{#1}{#2}{#3}} + {\ptx@sectioncommand{#1}{#2}{#3}[]}% + } + +\def\ptx@sectioncommand#1#2#3[#4]{% + \Section execute {section}{#1}{#2}{#3}{#4}% + \ignorepars{}% + } +\def\makeroman#1{% + \uppercase\expandafter{\romannumeral#1\relax}% + } + +\newif\ifsectiontitle + +\luacode +pitex.sections = { sections = {} } +function pitex.sections.increment (type) + local n = type + type = pitex.sections.sections[type] or { num = 0 } + type.num = type.num + 1 + local level = type.level + if level then + for name, tb in pairs(pitex.sections.sections) do + tb.num = tb.level > level and 0 or tb.num + end + end +end +function pitex.sections.counter (type) + type = pitex.sections.sections[type] + return type and type.num or -1 +end +\luacode/ + +\def\declaresection#1#2{% + \ptx@lua{pitex.sections.sections.#1 = {num = 0, level = #2}}% + } + +\def\incrementsection#1{% + \ptx@lua{pitex.sections.increment("#1")}% + } + +\def\getsectioncounter#1{% + \ptx@lua{tex.print(pitex.sections.counter ("#1"))}% + } + +%%% Gates in section %%% + +\gates new \Section {Section} +\Section list {section} [4] + (section_break) [2] + . [section_vmode] [1] ?{conditional = \ifvalue #1 : vmode = true } {\par\removelastskip\penalty0 } + . [section_clearpage] [1] ?{conditional = \ifvalue #1 : clear = true } {\clearpage} + . [section_beforeskip] [2] ?{conditional = -\ifvalue #1 : clear = true } + {% Or skip some lines. The "beforeskip" attribute is + % the number of blank lines one wants before a section + % title, afterskip is the same thing after, + % and "minimum" is the minimum number of lines + % one wants after the section title. + \ifexpression{% + -\ifdim\dimexpr(\pagegoal-\pagetotal) < 0pt & + \ifdim\dimexpr(\pagegoal-\pagetotal) < \numexpr(\usevalueor #1 : beforeskip 0+\usevalueor #1 : afterskip 0+\usevalueor #1 : minimum 0) \baselineskip} + {\breakpage} % Not enough room. + {\passvaluenobracesand\vskip #1 : beforeskip \baselineskip{}}} +% + [section_advance] [1] {\incrementsection{#1}} +% + [section_bookmark] [4] ?{conditional = \ifvalue #1 : link = true } {% + \passvalueand{\outline[meta = #1bookmark]} #1 : bookmarklevel {[#4]{#3}}{}} +% + [section_toc] [3] ?{conditional = \ifvalue #1 : toc = true } {% + \edef\ptx@temp{{#1}{\ifvalue #1 : number = none {}{\getsectioncounter{#1}}}{\unexpanded{\unexpanded{#3}}}{\the\pageno}}% + \expandafter\writeout\expandafter*\expandafter{\expandafter\noexpand\expandafter\ptx@toc\ptx@temp}} +% + [section_pre] {% + \bgroup + \maintextfalse + \sectiontitletrue + \ptx@section_attribute=0\relax} +% + (section_typeset) [2] + . [section_number] [2] {% + \ifvalue #1 : number = none + {\Section return3 {#1}{}{#2}} + {\Section return3 + {#1} + {\usevalueor #1 : numbercommand \unbrace + {\usevalue #1 : beforenumber + \ifcasevalue #1 : number + \val roman \makeroman + \val arabic \unbrace + \endval{\getsectioncounter{#1}}% + \usevalue #1 : afternumber }} + {#2}}} +% + . [section_heading] [3] {% + \Section return2 {#1}{#2\usevalueor #1 : function \unbrace{#3}\usevalue #1 : aftertitle }} +% + . [section_addfont] [2] {\Section return {#1}{\usevalue #1 : font #2}} +% + . [section_addcolor] [2] ?{conditional = \ifattribute #1 : color } {% + \Section return {#1}{\passvalueand\color #1 : color {{#2}}{}}} +% + . [section_do] [2] {% + \noindent + \settovalue\hskip #1 : indent + #2% + \ifvalue #1 : inline = true {}{\settovalue\rightskip #1 :ragged \endgraf}} +% + [section_post] {\egroup} +% + [section_afterskip] [1] ?{conditional = -\ifvalue #1 : inline = true } {% + \vskip\usevalueor #1 : afterskip 0\baselineskip + \ifvalue #1 : removenextindent = true {\removenextindent}{}} + +\setparameter metasection : + clear = false + vmode = true + minimum = 3 + inline = false + number = arabic + afternumber = "\kern.3em" + link = true + ragged = 0pt + toc = true + removenextindent = true + +\declaresection {chapter} 1 +\declaresection {section} 2 +\declaresection {subsection} 3 +\declaresection {paragraph} 4 + +\setparameter chapter section subsection paragraph: + meta = metasection + +\setparameter chapter : + clear = true + number = arabic + afterskip = 3 + indent = "0pt plus 1fill" + beforenumber = "chapitre " + afternumber = {\par\hfill} + bookmarklevel = 1 + +\setparameter section : + beforeskip = 2 + bookmarklevel = 2 + +\setparameter subsection paragraph: + font = \it + beforeskip = 1 + +\setparameter subsection: + beforenumber = "\getsectioncounter{section}." + minimum = 3 + bookmarklevel = 3 + +\setparameter paragraph: + beforenumber = "\getsectioncounter{section}.\getsectioncounter{subsection}." + minimum = 2 + inline = true + aftertitle = ".\hskip.333em" + bookmarklevel = 4 + +\setparameter chapterbookmark sectionbookmark subsectionbookmark paragraphbookmark: + meta = navigator + +\def\chaptertitle{}% +\freedef\chapter{% + \sectioncommand{chapter}{#1}{#1}% + } +\freedef\section{\sectioncommand{section}{#1}{#1}} +\freedef\subsection{\sectioncommand{subsection}{#1}{#1}} +\freedef\paragraph{\sectioncommand{paragraph}{#1}{#1}} + +\newif\ifptx@sectioninfile +\def\sectioninfile{% + \ifnextnospace* + {\ptx@sectioninfilefalse + \gobbleoneand\ptx@sectioninfile} + {\ptx@sectioninfiletrue + \ptx@sectioninfile}% + } + +\freedef\ptx@sectioninfile{% + \ptx@sectioninfile_do{#1}% + } +\def\ptx@sectioninfile_do#1 #2 #3 {% + \sectioncommand{#2}{#1}{#1}% + \ptx@section_getlabel{#3}% + \ifptx@sectioninfile + \input #3\relax + \fi + } +\newstring/ +\newwhile\ptx@section_getlabel1{#1}{% + \ifcontains/{#1}% + {\splitstringat/{#1}{\gobbleoneand\changewhile}} + {\label{#1}\breakwhile}% + } +\freedef\ptx@sectioninfile_gobble{% + \ptx@sectioninfile_gobblerest + } +\def\ptx@sectioninfile_gobblerest#1 #2 #3 {} + +\newattribute\ptx@section_attribute +% +% Move pending titles if they happen. They shouldn't by themselves, +% but the next paragraph might want more room than available +% and clear the page. Hence this. +% It reads box 255 backwards and move everything with set +% section attribute to the next page. If the first such material +% is a line, a (totally arbitrary) one-line skip is added, unless +% there's already a skip on top of the next page that isn't +% TeX-inserted (e.g. \baselineskip). +% This is probably totally insufficient. +% +\luacode +onelineskip = node.new(11) +onelineskip.kern = tex.baselineskip.width +remove_pendingtitles = function (head) + local item, first = node.slide(head), true + while item do + if node.has_attribute(item,\attributenumber\ptx@section_attribute) then + local nextitem = item.prev + node.remove(head,item) + if not ((item.id == 10 or item.id == 11) and first) then + node.insert_before(tex.lists.contrib_head, tex.lists.contrib_head, item) + tex.lists.contrib_head = item + end + if item.id == 0 then + if first then + first = false + if not (tex.lists.contrib_head.next.id == 10 and tex.lists.contrib_head.next.subtype == 0) then + node.insert_after(tex.lists.contrib_head, item, node.copy(onelineskip)) + lualog("A title has been moved from page " .. tex.count[0] .. + " to page " .. tex.count[0]+1 .. ".") + end + end + else + end + item = nextitem + else + if item.id == 0 or item.id == 1 then + item = nil + else + item = item.prev + end + end + end +end +\luacode/ + +\def\removependingtitles{% + \ptx@lua{remove_pendingtitles(tex.box[255].list)}% + } + + +% ToC: this is an inefficient mess. + +\def\ptx@toc_tok{} +\def\ptx@toc#1#2#3#4{% + \addright\ptx@toc_tok{% + \usecs{ptx@toc_item:#1}{#2}{#3}{#4}}% + } + +\def\tableofcontents{% + \bgroup + \parindent=0pt + \ifemptycommand\ptx@toc_tok + {\ptx@warn{No table of contents.}} + {\ptx@toc_tok}% + \egroup + } + +\long\def\ptx@def_tocitem#1#2#3#4{% + \defcs{ptx@toc_item:#1}##1##2##3{% + \edefcs{ptx@toc_current#1}{##1}% + \bgroup\par\quitvmode + \leftskip#2\relax + \rightskip=0pt plus 1fil + #3\reverse\iffemptystring{##1}{\llap{#4##1\kern1em}}% + ##2\leaders\hbox{. }\hfill\hbox to .8cm{\hfil##3}\par + \egroup}% + } + +\ptx@def_tocitem{chapter}{0pt}{\big\bf\sc}{} +\ptx@def_tocitem{section}{1cm}{\sc}{} +\ptx@def_tocitem{subsection}{2cm}{\it} + {\reverse\iffemptycs{ptx@toc_currentsection}{\usecs{ptx@toc_currentsection}.}} +\ptx@def_tocitem{paragraph}{3cm}{} + {\reverse\iffemptycs{ptx@toc_currentsection}{\usecs{ptx@toc_currentsection}.}% + \reverse\iffemptycs{ptx@toc_currentsubsection}{\usecs{ptx@toc_currentsection}}.} |