\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}}.}